mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 21:05:21 +02:00
43b005b704f80aea3ce37cab8136920749c73ee6
1078
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
43b005b704 |
Add pipeline workflow primitives and operator UI (#7903)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The pipeline subsystem models repeatable work as items moving through stages, with agent automation, review gates, blockers, drift notices, and linked work. > - Operators need this to be usable as one coherent workflow surface, not just as backend primitives or disconnected route experiments. > - The branch now carries the pipeline data model, service/routes, CLI/tutorial path, aggregation feeds, operator UI, stage automation controls, liveness/retry handling, and follow-up polish that make the primitive reviewable end to end. > - This pull request is the single review target for that pipeline workflow primitive stack. > - The benefit is that reviewers can evaluate the full operator experience and server contract together against `master`. ## Linked Issues or Issue Description No public GitHub issue exists for this work. The underlying feature request is described inline. ### Problem or motivation Paperclip needs a first-class way to model multi-stage agent/company workflows where upstream items can spawn downstream work, request review, carry fields across pipelines, surface drift, retry automation, and show operators where work is blocked or active. Without a unified pipeline primitive, these workflows spread across ad hoc issues, routines, and comments, making the state hard to inspect or operate. ### Proposed solution Add the pipeline workflow primitive stack: database schema and migrations, shared validators/types, server services and REST routes, aggregation and liveness helpers, CLI/tutorial smoke support, and the React operator UI for pipeline lists, boards, item detail, review/learnings views, settings, stage automation, secrets, carry-over fields, and retry/recovery flows. ### Alternatives considered - Keep workflows as loosely linked issues and routines: rejected because operators need a single board/detail/settings surface for repeated workflow patterns. - Ship backend primitives first and defer UI: rejected for this branch because the operator experience is the main way to validate the primitive. - Add a narrower one-off content workflow: rejected because the same primitives are useful across future company processes. ## What Changed - Added and evolved pipeline schema, migrations, shared contracts, server services, REST routes, route tests, and CLI/tutorial smoke support. - Added pipeline aggregation, health/liveness, drift acknowledgment, blocker/carry-over, automation retry, stage automation environment, and permission recovery behavior. - Added the operator UI for pipeline index/board/item detail/settings/review/learnings flows, including stage secrets, automation controls, markdown/item descriptions, linked issue assets, liveness banners, and source automation metadata. - Refactored issue document frame rendering through the shared `DocumentFrameHeader` component to keep document controls consistent with the pipeline document surfaces. - Kept this PR as the single base-branch review target for the current pipeline branch. ## Verification Current branch refresh: - `pnpm vitest run server/src/__tests__/pipelines-service.test.ts` — 31 passed - `pnpm vitest run server/src/__tests__/pipelines-routes.test.ts` — 19 passed - `pnpm --filter ./server typecheck` — passed - `pnpm --filter ./ui typecheck` — passed - Verified Pipelines remains gated by `enablePipelines === true`: sidebar item is hidden unless the flag is enabled, direct pipeline routes redirect to `/dashboard` when disabled, and the Experimental settings UI still has no Pipelines toggle. - GitHub status checks on `df071c710646de625131064c3fb6588b5e97964a` — all complete with no failing conclusions, including Actions, Socket, Superagent/Security, and Greptile Review - Greptile summary on `df071c710646de625131064c3fb6588b5e97964a` — Confidence Score 5/5 - GitHub review-thread sweep — 0 unresolved Greptile threads Previously recorded during branch development: - Server pipeline service/route and aggregation tests - Shared validator tests - UI pipeline page/settings/item-detail/learnings/liveness tests - Pipeline tutorial smoke path ## Risks - High review surface: this is a large feature branch spanning database, shared contracts, server behavior, CLI/docs, and UI. - Migration ordering and schema compatibility need reviewer attention because this branch has been kept current across multiple `master` syncs. - GitHub still reports merge state `BLOCKED` because the PR is awaiting normal human review/branch-protection completion; all current status checks are green. - Branch-name checklist exception: this PR uses the pre-existing requested branch name, which predates the current public-branch naming rule. The PR title/body avoid internal issue references. > 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 based on GPT-5, with repository tool use, shell execution, git/GitHub CLI operations, and local verification commands. Earlier commits in this branch were assisted by Paperclip agents and other AI coding agents as recorded in commit authorship. ## 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> |
||
|
|
b3c0fadd63 |
feat(routines): add date variable controls (#8655)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Scheduled routines can prompt agents with variables that are filled in at dispatch time. > - Existing routine variable handling supported plain text-like values, but date inputs need a structured contract so routines can pass consistent date values. > - Operators also need date variables to be easy to configure and override from the routine UI. > - This pull request adds a date variable type across shared validation, server dispatch, and UI editing/run dialogs. > - The benefit is that routine authors can define date inputs once and agents receive validated ISO-style date values when routines run. ## Linked Issues or Issue Description Refs #219 Feature request: - Problem/motivation: Scheduled routines need first-class, typed date variables so operators can configure dates without relying on free-form text conventions. - Proposed solution: Add an `x-date` routine variable type with shared parsing/validation, server dispatch support, and UI date-picker controls in routine variable editors and run dialogs. - Alternatives considered: Continue treating dates as plain text, but that leaves validation and formatting to individual operators and agents. - Roadmap alignment: This is a focused improvement to the completed Scheduled Routines milestone and does not duplicate an active roadmap item. Related PR search: - Searched existing PRs/issues for `routine date picker`, `date variables`, and `scheduled routine date variable`; no direct duplicate PR was found. ## What Changed - Added the shared `x-date` routine variable contract, parsing, defaults, and validation coverage. - Extended routine dispatch to validate and pass date variable values. - Added date input controls to the routine variable editor and routine run variables dialog. - Added focused tests for shared validation, server dispatch, and the UI date controls. ## Verification - `git diff --check public/master...HEAD` - `pnpm run preflight:workspace-links && pnpm exec vitest run packages/shared/src/routine-variables.test.ts packages/shared/src/validators/routine.test.ts server/src/__tests__/routines-service.test.ts ui/src/components/RoutineRunVariablesDialog.test.tsx ui/src/components/RoutineVariablesEditor.test.tsx` - 5 test files passed - 68 tests passed ## Risks Low to medium risk. This adds a new routine variable type across shared/server/UI paths, so the main risk is compatibility with existing routine variable payloads. The change keeps existing variable types intact and adds targeted validation tests for the new date 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 coding agent based on GPT-5, with terminal, git, GitHub CLI, and local test execution capabilities. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8f7282066e |
Add workspace file downloads
Add first-class workspace file downloads, broader attachment content-type support, and the stream-lifetime limiter fix from PR review. |
||
|
|
569b7affc4 |
[codex] Add bounded workspace overview (#8627)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The execution workspace subsystem powers project and workspace views by listing runtime state, branch metadata, issue links, and status summaries. > - The existing workspace views relied on broad list data that can grow expensive as a company accumulates many workspaces and linked issues. > - That makes the Workspaces page and project workspace cards slower than necessary because the UI does not always need the full workspace detail payload up front. > - This pull request adds a bounded overview contract for workspace listings and moves the relevant UI surfaces to that cheaper path. > - The benefit is faster workspace loading while preserving detail fetches for pages that actually need full workspace data. ## Linked Issues or Issue Description No public GitHub issue exists for this change. Inline bug report follows the repository bug template. ### What happened? Workspace index-style screens can load too much execution workspace detail before the user asks for it. Several UI surfaces used fuller workspace data paths for summary displays, which can make workspace loading slower as workspace history grows. ### Expected behavior Overview screens should request a bounded summary payload, while detail screens should keep using the full workspace detail endpoint. ### Steps to reproduce 1. Run Paperclip from source with enough execution workspace history to make workspace lists non-trivial. 2. Open the Workspaces page or a project workspace summary card. 3. Observe that summary UI needs only bounded workspace metadata but can depend on broader workspace payloads. ### Paperclip version or commit `master` at the time this branch was prepared. ### Deployment mode Local dev (`pnpm dev`) ## What Changed - Added shared types, validators, and path constants for bounded execution workspace overviews. - Added server service and route support for overview queries with bounded linked issue/runtime metadata. - Updated workspace overview UI API calls, query keys, breadcrumbs, quicklooks, close dialogs, project summaries, and detail links to consume the cheaper overview shape where appropriate. - Added regression coverage for the new server route/service behavior and the UI overview consumers. - Registered the new workspace overview route in the generated OpenAPI spec. - Kept overview totals aligned with the project join and preserved project slug links in workspace headers. ## Verification - `pnpm exec vitest run server/src/__tests__/execution-workspaces-service.test.ts server/src/__tests__/execution-workspaces-routes.test.ts ui/src/api/execution-workspaces.test.ts ui/src/components/ProjectWorkspaceSummaryCard.test.tsx ui/src/pages/Workspaces.test.tsx` - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` - `pnpm exec vitest run server/src/__tests__/openapi-routes.test.ts server/src/__tests__/execution-workspaces-routes.test.ts server/src/__tests__/execution-workspaces-service.test.ts` - `pnpm test:run:serialized -- --shard-index 1 --shard-count 4` ## Risks Low to medium risk. The change introduces a new overview contract across shared/server/ui layers, so the main risk is a mismatch between summary and detail payload expectations. The added route/service/UI tests cover the intended split, and full detail pages continue using the detail path. > 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-based coding agent with repository tool use and local command execution. Exact served model identifier and context window were not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have 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> |
||
|
|
f90ea4dae4 |
Fix top-level secret ref binding sync (#8630)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Instance environments can store provider configuration fields as Paperclip secret references > - Environment save uses secret binding sync to keep persisted config refs aligned with `company_secret_bindings` > - Top-level secret-ref fields such as `apiKey` were not deleted during sync because the cleanup only matched child paths like `apiKey.*` > - Re-saving an environment with the same top-level secret ref could therefore hit the target/path unique constraint and return a 500 > - This pull request makes the sync cleanup include the exact top-level config path before reinserting current refs > - The benefit is that saved environment provider configs can be edited repeatedly without duplicate binding failures ## Linked Issues or Issue Description No public GitHub issue found in duplicate search for this exact environment secret-binding failure. ### Bug report #### Pre-submission checklist - I searched existing open and closed issues and this is not a duplicate. - I can reproduce this on the current `master` lineage. - I confirmed the error originates in Paperclip secret-binding sync, not the sandbox provider itself. #### What happened? Saving an instance environment whose provider config contains a top-level secret-ref field can fail with a duplicate key error on `company_secret_bindings_target_path_uq`. #### Expected behavior Saving the same environment config repeatedly should update/sync bindings idempotently. #### Steps to reproduce 1. Create or edit an instance environment with a provider config that has a top-level secret-ref field such as `apiKey`. 2. Save the environment. 3. Save the environment again without moving that field under a nested object. 4. The second save can attempt to insert a duplicate binding for the same target/path. #### Paperclip version or commit Observed on local dev from current `master` lineage before this fix. #### Deployment mode Local dev (pnpm dev), authenticated private mode. #### Installation method Built from source (pnpm dev / pnpm build). #### Agent adapter(s) involved Not adapter-specific (core bug). #### Database mode Embedded local Postgres. #### Access context Board (human operator) environment settings save. #### Relevant logs or output The server returned a 500 after Postgres rejected a duplicate `company_secret_bindings` row for the same environment target and `apiKey` config path. Secret values and local paths are intentionally omitted. #### Privacy checklist I reviewed the PR description for private instance links, local paths, API keys, tokens, and company-specific secrets. ## What Changed - Updated `syncSecretRefsForTarget()` so prefix cleanup removes both the exact top-level config path and nested child paths. - Added a regression test that syncs an environment top-level `apiKey` secret ref repeatedly, then replaces it and verifies only one binding remains. ## Verification - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/secrets-service.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `git diff --check` - Local diff scan for internal issue links, local paths, bearer/session tokens, and obvious secret literals returned no matches. - GitHub duplicate searches for related environment secret-binding issues/PRs returned no matches. ## Risks Low risk. The change only broadens the existing target/path cleanup used before reinserting secret refs. It preserves the existing child-path cleanup behavior and adds the missing exact-path case. ## Model Used OpenAI GPT-5 Codex via the `codex_local` Paperclip adapter. Tool-using coding-agent session with shell, git, and repository-edit capabilities. 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> |
||
|
|
b4a7efa8d2 |
Add skill category editing in settings (#8615)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Skills can be installed, inspected, filtered, and grouped inside company settings > - Skill category metadata already exists in the data model and list filters, but users could not edit categories after a skill was created or imported > - That made category filters and counts drift from the way operators actually want to organize their skills > - This pull request adds category editing to the existing skill settings dialog and sends those edits through the existing company-scoped skill update API > - The server mutation now includes category information in the activity log so settings changes are auditable > - The benefit is that operators can keep installed skills organized without reinstalling or recreating them ## Linked Issues or Issue Description No duplicate or closely related public GitHub issues or PRs were found for `skill categories settings`. Feature request fields: **Subsystem affected** Cross-cutting: `server/` REST API routes/services and `ui/` React board settings. **Problem or motivation** Company operators can create or import skills with categories, and Paperclip already exposes category filters and category counts. After installation, though, operators could not edit a skill's categories from the skill detail settings screen. That made it difficult to keep skills grouped correctly as workflows evolved. **Proposed solution** Add category editing to the existing skill settings dialog. The category field accepts comma-separated values, normalizes them into slugs, deduplicates repeated categories, allows clearing all categories, and saves categories together with the existing sharing setting through the company-scoped skill update API. **Alternatives considered** One alternative was to keep categories editable only during create/import flows, but that forces users to recreate or reinstall skills just to adjust grouping metadata. Another was a separate categories-only action, but batching settings into one explicit Save action keeps the dialog predictable. **Roadmap alignment** This supports the completed Skills Manager roadmap area by making installed skills easier to organize and maintain inside company settings. **Additional context** The server already persisted skill categories and supported category list filters/counts. This PR wires the existing metadata into the settings editing path and adds focused route, service, and UI tests. ## What Changed - Added category editing to the skill detail settings dialog, including comma-separated input, normalized deduplication, reset, dirty-state handling, and save feedback. - Updated the skill settings mutation path to save categories and sharing scope together, then refresh detail/list cache entries. - Included updated categories in `company.skill_updated` activity details. - Added server route/service coverage for category updates, normalization, filtering, counts, clearing, and activity logging. - Added UI coverage for saving category edits, clearing categories, reordered no-op category sets, saving sharing changes together, and preserving draft input after a failed save. - Updated the Storybook skill detail harness for the renamed settings callback props. ## Verification - `pnpm run preflight:workspace-links && pnpm exec vitest run server/src/__tests__/company-skills-routes.test.ts server/src/__tests__/company-skills-service.test.ts ui/src/pages/CompanySkills.test.tsx` - Latest-head GitHub checks are green for typecheck, build, e2e, general tests, serialized server suites, policy, commitperclip review, Socket Security, Snyk status, and Canary Dry Run. - Greptile Review succeeded on the latest head with zero unresolved review threads. ## Risks Low risk. The change uses the existing company skill update API and category normalization path. The main behavioral change is that the settings dialog now batches sharing and category edits behind an explicit Save button instead of saving sharing immediately on select change. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex coding agent based on GPT-5, with tool-enabled repository inspection, shell execution, git, 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 - [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> |
||
|
|
ed65d08d57 |
[codex] Gate skill mutations with skills:create permission (#8616)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents and board users operate inside a company-scoped control plane where permissions decide which mutating actions they can perform > - Company skills are part of the reusable agent-company setup surface, but skill mutation had been coupled to broader agent-creation authority > - That coupling meant importing or managing skills required a permission that also implies hiring power, which is broader than the operation needs > - Paperclip already has a grant-based permission vocabulary, so skill mutation should be authorized through a dedicated `skills:create` capability while preserving existing default behavior for trusted agents > - This pull request adds the skill creation permission contract, enforces it on company skill mutations, exposes it in agent permission management, and documents the changed CLI/API expectations > - The benefit is a narrower, auditable permission path for skill import/create/update/delete flows without forcing agents to receive broader agent-creation authority ## Linked Issues or Issue Description No public issue is linked. Problem: company skill mutation APIs were effectively tied to broader agent creation authority. This PR splits skill mutation authorization onto the public `skills:create` permission while keeping existing default skill creation behavior for agents unless explicitly disabled. Related public PR found during duplicate search: #5330. That PR uses an older `canManageSkills` shape; this PR implements the `skills:create` grant path instead. ## What Changed - Added `skills:create` to shared permission constants and agent permission types/validators as `canCreateSkills`. - Backfilled default human/member role grants for `skills:create`. - Updated company skill mutation routes to require board/user or agent access to `skills:create`, while preserving legacy/default agent behavior through `canCreateSkills` unless explicitly disabled. - Updated agent permission update handling, UI permission controls, duplicate-agent payloads, plugin SDK fixtures, and agent detail API surfaces for `canCreateSkills`. - Added regression coverage for skill route authorization, permission schema/default behavior, invite grants, omitted permission updates, and duplicate-agent payloads. - Updated CLI and Paperclip skill documentation for the new skill creation permission. ## Verification - `pnpm exec vitest run server/src/__tests__/agent-permissions-service.test.ts server/src/__tests__/agent-permissions-routes.test.ts server/src/__tests__/company-skills-routes.test.ts server/src/__tests__/invite-join-grants.test.ts ui/src/lib/duplicate-agent-payload.test.ts` — 5 files, 90 tests passed. - `pnpm --filter @paperclipai/shared typecheck && pnpm --filter @paperclipai/server typecheck && pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm test:run ...changed files...` was attempted first, but the stable wrapper rejects explicit file arguments; direct Vitest was used for the same targeted files. ## Risks - Moderate authorization risk: this changes the gate for company skill mutations, so the tests cover board grant checks, agent explicit grant checks, legacy default allowance, and explicit denial. - Migration/backfill risk is low: the migration only grants `skills:create` to existing human roles that already need broad management capability. - UI/API compatibility risk is low: `canCreateSkills` remains default-on for full agent permissions, and the update validator preserves omitted values so unrelated permission edits do not re-enable disabled skill creation. > 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 coding agent with terminal/tool use 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> |
||
|
|
a27e5ad002 |
Add ephemeral sandbox runtime status plumbing (#8593)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Sandboxed agent runs can spend meaningful time preparing a remote workspace before the agent transcript shows useful output. > - Operators need short, current progress text for those setup phases, but that text should not become durable run history. > - The existing live-run websocket path already carries run updates to the UI, so the backend can reuse that channel instead of adding polling. > - This pull request adds an ephemeral runtime-progress contract, a process-local status store, and heartbeat integration for sandbox-managed runs. > - The benefit is a clearer active-run experience without database migrations or persistent progress rows. ## Linked Issues or Issue Description Refs #248 No exact public GitHub issue was found for this status-message plumbing. The underlying problem is that active sandboxed runs currently have setup phases, such as workspace sync and restore, where the operator cannot see concise current progress through the live run state. This PR addresses that gap for the backend/runtime layer while keeping progress messages ephemeral. GitHub search performed for related or duplicate work: `sandbox runtime status`, `sandbox restore index`, and `runtime progress`. No direct duplicate PR was found. ## What Changed - Added shared runtime-progress types and the `heartbeat.run.progress` live event type. - Added a process-local heartbeat run runtime-status store with TTL, bounded/redacted messages, and terminal cleanup. - Threaded runtime progress callbacks through heartbeat execution and active/live run serialization. - Emitted sandbox-managed runtime phase updates for sync, adapter startup, restore/export, and finalization paths. - Added backend and adapter-utils tests for ephemeral status behavior, terminal cleanup, live serialization, and sandbox progress callbacks. ## Verification - `pnpm install --frozen-lockfile` - Local PII scan before push: high-confidence secret patterns, internal issue links, local user paths, and private URL patterns checked across all three split diffs; no real secrets or internal links found. The only secret-like text is an intentional fake test fixture (`sk-test-secret`). - `git diff --check origin/master..feat/sandbox-runtime-status` - `pnpm exec vitest run server/src/services/heartbeat-run-runtime-status.test.ts server/src/__tests__/heartbeat-runtime-state.test.ts server/src/__tests__/agent-live-run-routes.test.ts packages/adapter-utils/src/sandbox-managed-runtime.test.ts` — 4 files, 23 tests passed. - `pnpm run typecheck` passed on both top stacks that include this branch: `feat/sandbox-status-ui` and `fix/sandbox-restore-index-sync`. - `pnpm run build` passed on both top stacks that include this branch; Vite reported existing CSS `::highlight` and chunk-size warnings. - `pnpm run test:run` was attempted on `fix/sandbox-restore-index-sync`; it failed in two unrelated broad-suite tests. One depends on this host's Git default branch behavior, and one depends on local Claude model-discovery environment. The changed focused suites above pass. ## Risks - Runtime progress is process-local by design, so status disappears after TTL, terminal cleanup, or server restart. - Clients that do not consume `heartbeat.run.progress` simply keep existing behavior. - Message redaction is intentionally generic; overly specific phase details should stay out of runtime-progress payloads. > 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 via Codex coding agent, with shell/tool execution in a local worktree. Exact context-window metadata is not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [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 CTO <cto@paperclip.local> Co-authored-by: Paperclip CTO <noreply@paperclip.ing> |
||
|
|
f88ac9d078 |
[codex] Fix local skill, secrets, and file viewer regressions (#8586)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents rely on local skills, provider-backed secrets, and workspace file previews during normal execution. > - Local skill imports need bounded reference-file inventory so direct skill discovery stays accurate without accidentally walking too much of the filesystem. > - Secrets provider setup needs actionable AWS discovery errors so operators can recover from IAM/config problems without losing manual form input. > - The issue detail file viewer should reopen cleanly after the first close so users can keep inspecting files during task review. > - This pull request collects the small fixes and regression tests for those related operator workflows. > - The benefit is more predictable local skill imports, clearer secrets setup failure states, and a less brittle file preview interaction. ## Linked Issues or Issue Description - No public GitHub issue was found for this extracted local work. - Related prior sync context: #8536. - Problem: local skill reference discovery, AWS provider-vault discovery errors, and issue file preview reopening each had narrow workflow regressions that made operator recovery harder. - Expected behavior: skill imports inventory reference files within bounded local skill directories, AWS discovery failures present safe actionable guidance while preserving manual values, and closing the first file preview does not prevent opening another preview. - Reproduction scope: import a local skill with referenced files, attempt AWS Secrets Manager discovery with insufficient IAM/list permissions, and open/close/reopen file previews from an issue detail page. - Duplicate search: searched GitHub PRs/issues for `skill inventory secrets file viewer` and `skill inventory secrets AWS file viewer`; no matching public duplicate was found. ## What Changed - Bounded direct local skill file inventory discovery and added regression coverage for reference file imports. - Preserved and surfaced safe, actionable AWS Secrets Manager discovery/import errors in server responses and the secrets UI. - Kept AWS provider-vault manual form values intact when discovery fails or returns no candidates. - Fixed issue file viewer state so closing the first preview still allows later file previews to open. - Updated the secrets render test harness to avoid the missing `React.act` export in the current React package set. ## Verification - `pnpm run preflight:workspace-links && pnpm exec vitest run server/src/__tests__/company-skills-service.test.ts server/src/__tests__/secrets-routes.test.ts server/src/__tests__/secrets-service.test.ts ui/src/context/FileViewerContext.test.ts ui/src/pages/Secrets.render.test.tsx` - Result: 5 test files passed, 116 tests passed. - Install note: the isolated worktree needed `NODE_ENV=development pnpm install --frozen-lockfile --prod=false --force` before local verification because it initially had no dev dependencies installed. ## Risks - Low-to-medium risk: this touches skill import inventory, secrets-provider error handling, and file-viewer UI state, but each change is covered by focused regression tests. - No migrations. - No dependency or lockfile changes. - CI is rerunning on the latest head after review fixes; Greptile is 5/5 with no unresolved Greptile threads. > 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, GPT-5-family model as provided in the Paperclip run environment, with repository tool use and local command 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> |
||
|
|
4b1332b61c |
fix(openclaw-gateway): drop root paperclip params (#4416)
Fixes #5997, fixes #4081, fixes #4723, fixes #6625, fixes #3923 Refs #6606 — this PR removes the rejected root `paperclip` field, but #6606 also requires the protocol v3→v4 bump, which is out of scope here; referencing rather than closing it. ## Thinking Path > - Paperclip is the control plane that wakes and coordinates agent workers across company-scoped execution flows. > - The `openclaw_gateway` adapter is part of that wake path, so its outbound payload contract has to match the gateway's validated `agent` schema. > - `master` currently reintroduces a previously fixed regression by sending a top-level `paperclip` property in `agentParams` (see #3923, which reverts the original fix in #626). > - The gateway rejects unknown root params, which means OpenClaw wakes fail before the remote agent can start work. > - The actual wake context already rides in the generated `message`, so the extra root property is both redundant and harmful. > - This pull request removes that leaked root property, adds a focused regression test around param construction, and updates affected server expectations/docs to the supported contract. > - The benefit is that OpenClaw Gateway agents wake successfully again without losing inline wake context. ## What Changed - Removed the top-level `paperclip` field from OpenClaw Gateway `agentParams` and extracted `buildAgentParams()` so the contract is easy to test. - Added a package-level regression test that proves `payloadTemplate.paperclip` is stripped while explicit `agentId`/`timeout` behavior stays intact. - Updated server tests that inspect OpenClaw Gateway payloads to assert wake data is delivered in `message` instead of a rejected root field. - Updated the adapter configuration docs to state that wake context is embedded in the generated message text, not sent as a top-level param. ### Rebase onto current `master` (conflict resolution) This branch was opened against an older `master`; re-merging current `master` required: - Resolving conflicts in `execute.ts` — `master` hoisted `configuredAgentId` and moved the agentId/timeout precedence inline; this PR keeps the `buildAgentParams()` extraction that strips the gateway-rejected root `paperclip`. - Updating tests `master` added **after** this branch's base that assert the old root-`paperclip` contract. These suites use the OpenClaw gateway adapter purely as a delivery harness (`adapterType: "openclaw_gateway"` + a mock gateway) and observe wake content via the gateway payload, so dropping the root field requires them to read wake context from `message` instead: - `server/src/__tests__/heartbeat-comment-wake-batching.test.ts` - `server/src/__tests__/low-trust-red-team-routes.test.ts` (redaction guarantees preserved — sanitized body + `expectNoCanary` on the raw canary) - Replaced brittle JSON-substring assertions (flagged by Greptile) with a shared `parseWakePayloadFromMessage()` helper + `toMatchObject`, robust to serialization/key-order changes. The strict contract is confirmed upstream: OpenClaw's `AgentParamsSchema` is `Type.Object(..., { additionalProperties: false })` with no `paperclip` field, so a root `paperclip` is rejected (`invalid agent params: at root: unexpected property 'paperclip'`). ## Verification - `pnpm --filter @paperclipai/adapter-openclaw-gateway typecheck` — clean - `pnpm --filter @paperclipai/server typecheck` — clean - `pnpm exec vitest run --project @paperclipai/server server/src/__tests__/openclaw-gateway-adapter.test.ts server/src/__tests__/heartbeat-comment-wake-batching.test.ts server/src/__tests__/low-trust-red-team-routes.test.ts` — 26 passed (7 + 11 + 8) - `packages/adapters/openclaw-gateway/src/server/execute.test.ts` — 6 passed (run via a local temp vitest config because the root `vitest.config.ts` does not include this package) ## Risks - Low risk: this narrows the outbound payload to the gateway-supported contract and keeps wake context in the already-supported `message` channel. - Any downstream consumer that incorrectly depended on a top-level `paperclip` field from the gateway mock payloads would need to follow the supported `message` contract instead. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex CLI coding agent via API authored the original change; exact underlying model ID and context window were not exposed in that environment. - Rebase/conflict resolution and the test-assertion migration were done with Claude Code (Claude Opus 4.8, 1M context). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have 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 the related issues above - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: serenakeyitan via breeze-runner <serenakeyitan@users.noreply.github.com> Co-authored-by: Andrew Aymeloglu <aaymeloglu@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
72d4f2ad99 |
build(deps): bump better-auth from 1.4.18 to 1.6.20 (#8464)
Bumps [better-auth](https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth) from 1.4.18 to 1.6.20. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/better-auth/better-auth/releases">better-auth's releases</a>.</em></p> <blockquote> <h2>v1.6.20</h2> <h2><code>better-auth</code></h2> <h3>Bug Fixes</h3> <ul> <li>Fixed account-linking logs to route through the configured logger (<a href="https://redirect.github.com/better-auth/better-auth/pull/10121">#10121</a>)</li> <li>Fixed TypeScript inference errors by declaring inherited <code>APIError</code> properties (<a href="https://redirect.github.com/better-auth/better-auth/pull/8734">#8734</a>)</li> <li>Fixed refresh cookie <code>Max-Age</code> to be capped at <code>expiresIn</code> (<a href="https://redirect.github.com/better-auth/better-auth/pull/9621">#9621</a>)</li> </ul> <p>For detailed changes, see <a href="https://github.com/better-auth/better-auth/blob/c342f42fff46043b5e195f7f757b0f2c1043414c/packages/better-auth/CHANGELOG.md"><code>CHANGELOG</code></a></p> <h2><code>@better-auth/i18n</code></h2> <h3>Bug Fixes</h3> <ul> <li>Fixed English language fallback behavior and improved i18n documentation (<a href="https://redirect.github.com/better-auth/better-auth/pull/9872">#9872</a>)</li> </ul> <p>For detailed changes, see <a href="https://github.com/better-auth/better-auth/blob/c342f42fff46043b5e195f7f757b0f2c1043414c/packages/i18n/CHANGELOG.md"><code>CHANGELOG</code></a></p> <h2>Contributors</h2> <p>Thanks to everyone who contributed to this release:</p> <p><a href="https://github.com/adityachaudhary99"><code>@adityachaudhary99</code></a>, <a href="https://github.com/dipan-ck"><code>@dipan-ck</code></a>, <a href="https://github.com/sleepe229"><code>@sleepe229</code></a>, <a href="https://github.com/WilsonnnTan"><code>@WilsonnnTan</code></a></p> <p><strong>Full changelog:</strong> <a href="https://github.com/better-auth/better-auth/compare/v1.6.19...v1.6.20"><code>v1.6.19...v1.6.20</code></a></p> <h2>v1.6.19</h2> <h2><code>better-auth</code></h2> <h3>Features</h3> <ul> <li>Added support for pre-binding device codes to a specific user in the device authorization plugin (<a href="https://redirect.github.com/better-auth/better-auth/pull/9995">#9995</a>)</li> </ul> <h3>Bug Fixes</h3> <ul> <li>Fixed headerless session checks (<a href="https://redirect.github.com/better-auth/better-auth/pull/10053">#10053</a>)</li> <li>Fixed cookie cache fallback lookup (<a href="https://redirect.github.com/better-auth/better-auth/pull/9348">#9348</a>)</li> <li>Fixed <code>sendVerificationEmail</code> errors not being surfaced to the client (<a href="https://redirect.github.com/better-auth/better-auth/pull/8863">#8863</a>)</li> <li>Fixed auth client return types not being emitted correctly in TypeScript declaration builds (<a href="https://redirect.github.com/better-auth/better-auth/pull/10071">#10071</a>)</li> <li>Fixed session and account cache cookies being silently dropped when near the browser's per-cookie size limit by splitting them into chunks (<a href="https://redirect.github.com/better-auth/better-auth/pull/10088">#10088</a>)</li> <li>Fixed single-use verification flows (such as magic-link) hanging on connection-limited database adapters by reusing active transactions (<a href="https://redirect.github.com/better-auth/better-auth/pull/10070">#10070</a>)</li> <li>Fixed the domain not being included when clearing cross-subdomain cookies in the <code>last-login-method</code> plugin (<a href="https://redirect.github.com/better-auth/better-auth/pull/9319">#9319</a>)</li> <li>Fixed the <code>oauth-popup</code> plugin leaking internal OAuth state keys into <code>additionalData</code> (<a href="https://redirect.github.com/better-auth/better-auth/pull/10067">#10067</a>)</li> <li>Reverted the headerless session check fix (<a href="https://redirect.github.com/better-auth/better-auth/pull/10074">#10074</a>)</li> </ul> <p>For detailed changes, see <a href="https://github.com/better-auth/better-auth/blob/ac4d81df748b8c09e584fdd6c440f8f327490fd1/packages/better-auth/CHANGELOG.md"><code>CHANGELOG</code></a></p> <h2><code>auth</code></h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/better-auth/better-auth/blob/main/packages/better-auth/CHANGELOG.md">better-auth's changelog</a>.</em></p> <blockquote> <h2>1.6.20</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10121">#10121</a> <a href="https://github.com/better-auth/better-auth/commit/21448b1b77681e71e80ae0728d8658c936c18eb8"><code>21448b1</code></a> Thanks <a href="https://github.com/adityachaudhary99"><code>@adityachaudhary99</code></a>! - OAuth account-linking and create-user error logs now respect a custom <code>logger</code> configured in <code>betterAuth()</code>, instead of always being written to the default console logger.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/9621">#9621</a> <a href="https://github.com/better-auth/better-auth/commit/8ecf23817f5e501bdd8ab63ad5fdf2554ff1dff5"><code>8ecf238</code></a> Thanks <a href="https://github.com/dipan-ck"><code>@dipan-ck</code></a>! - Session refresh no longer emits a cookie Max-Age above the browser's 400-day ceiling when using a database without fractional-second precision.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/8734">#8734</a> <a href="https://github.com/better-auth/better-auth/commit/930f5341d956bf3075f43758392a5c7f50947104"><code>930f534</code></a> Thanks <a href="https://github.com/sleepe229"><code>@sleepe229</code></a>! - declare inherited APIError properties to fix TypeScript inference errors</p> </li> <li> <p>Updated dependencies []:</p> <ul> <li><code>@better-auth/core</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> <li><code>@better-auth/drizzle-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> <li><code>@better-auth/kysely-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> <li><code>@better-auth/memory-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> <li><code>@better-auth/mongo-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> <li><code>@better-auth/prisma-adapter</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> <li><code>@better-auth/telemetry</code><a href="https://github.com/1"><code>@1</code></a>.6.20</li> </ul> </li> </ul> <h2>1.6.19</h2> <h3>Patch Changes</h3> <ul> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10088">#10088</a> <a href="https://github.com/better-auth/better-auth/commit/de4aa52e991f0a56786300af3e0d9ac8331f1996"><code>de4aa52</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - Session and account cache cookies near the browser's per-cookie size limit (for example with a long <code>cookiePrefix</code> or many cached fields) are now split into chunks instead of being silently dropped by the browser. A cache too large to fit even when chunked is skipped with a warning rather than failing the request, so reads fall back to the database.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/9995">#9995</a> <a href="https://github.com/better-auth/better-auth/commit/b4b02660c760fe4c8889d1311a3dbf3165f88d0b"><code>b4b0266</code></a> Thanks <a href="https://github.com/ElGauchooooo"><code>@ElGauchooooo</code></a>! - The device authorization plugin now accepts an optional <code>user_id</code> when issuing a device code via <code>/device/code</code>, pre-binding the code to that user. Only the bound user can approve or deny the code, so a publicly visible user code can no longer be claimed by someone else.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10086">#10086</a> <a href="https://github.com/better-auth/better-auth/commit/5bd5e1cc73d2c9c38e69011f03038b61a4312a63"><code>5bd5e1c</code></a> Thanks <a href="https://github.com/gustavovalverde"><code>@gustavovalverde</code></a>! - Refresh-token rotation and token revocation, two-factor backup-code regeneration, device-code claiming, and organization invitation acceptance now work on Prisma. Concurrent or repeat requests in these flows could previously return an error on Prisma instead of the expected result.</p> <p>On MongoDB servers older than 5.0, these flows and other guarded value updates (rate-limit window resets, API-key refills) no longer fail with an empty-update error.</p> <p><code>@better-auth/core</code>: <code>incrementOne</code> now reports a clear error when called with no <code>increment</code> and no <code>set</code>.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/9319">#9319</a> <a href="https://github.com/better-auth/better-auth/commit/581f8271fb911cea2ce74810e086709909457cd3"><code>581f827</code></a> Thanks <a href="https://github.com/ping-maxwell"><code>@ping-maxwell</code></a>! - fix(last-login-method): include domain when clearing cross-subdomain cookies</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10067">#10067</a> <a href="https://github.com/better-auth/better-auth/commit/840788502a13d6fa4aa4540b930ddb4a99dc1ed6"><code>8407885</code></a> Thanks <a href="https://github.com/bytaesu"><code>@bytaesu</code></a>! - The <code>oauth-popup</code> plugin now ignores internal OAuth state fields passed through its <code>additionalData</code> parameter, so <code>additionalData</code> only ever carries your own custom values.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/9555">#9555</a> <a href="https://github.com/better-auth/better-auth/commit/c1a8a64c146fab20c7ad0076ffdf12eff9adc17a"><code>c1a8a64</code></a> Thanks <a href="https://github.com/ChrisMGeo"><code>@ChrisMGeo</code></a>! - Fix invalid OpenAPI output for Better Auth callback, session, and passkey routes so client generators can consume the schema.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10071">#10071</a> <a href="https://github.com/better-auth/better-auth/commit/635f1908702d0c63cf66b4e5f054e9d527a3c8f7"><code>635f190</code></a> Thanks <a href="https://github.com/gustavovalverde"><code>@gustavovalverde</code></a>! - Auth clients exported from wrapper packages can now be emitted in TypeScript declaration builds without extra type annotations.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/10070">#10070</a> <a href="https://github.com/better-auth/better-auth/commit/a787e0b66b368a1af0b4ba17c9750c2839668246"><code>a787e0b</code></a> Thanks <a href="https://github.com/gustavovalverde"><code>@gustavovalverde</code></a>! - Single-use verification flows no longer hang on database adapters that use a one-connection pool. This fixes magic-link verification and similar token checks in connection-limited serverless database setups.</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/9348">#9348</a> <a href="https://github.com/better-auth/better-auth/commit/c2f718fcdeec0c1767bb8acd5fefdd3810863b0a"><code>c2f718f</code></a> Thanks <a href="https://github.com/ping-maxwell"><code>@ping-maxwell</code></a>! - fix: cookie cache fallback lookup</p> </li> <li> <p><a href="https://redirect.github.com/better-auth/better-auth/pull/8863">#8863</a> <a href="https://github.com/better-auth/better-auth/commit/7d18175637a0b95a501fde0cf3db080879367a9d"><code>7d18175</code></a> Thanks <a href="https://github.com/ping-maxwell"><code>@ping-maxwell</code></a>! - <code>sendVerificationEmail</code> was invoked via <code>runInBackgroundOrAwait</code>, which could defer work when <code>advanced.backgroundTasks.handler</code> is configured (so the handler could return <strong>200</strong> before the email callback finished) and, in the default path, <strong>caught and logged errors without rethrowing</strong>. User callbacks that throw <code>APIError</code> (e.g. <strong>429</strong> from a rate limiter) were therefore not reliably reflected in the HTTP response (<a href="https://redirect.github.com/better-auth/better-auth/issues/8757">better-auth/better-auth#8757</a>).</p> <p>Now we await <code>sendVerificationEmailFn</code> so failures surface to the client with the correct status. The unauthenticated <code>/send-verification-email</code> path enforces a constant-time floor (500 ms) so that the response duration does not reveal whether the email belongs to a real unverified user.</p> </li> <li> <p>Updated dependencies [<a href="https://github.com/better-auth/better-auth/commit/08959936d29de8a37d469e42d9077859b643d6b3"><code>0895993</code></a>, <a href="https://github.com/better-auth/better-auth/commit/5bd5e1cc73d2c9c38e69011f03038b61a4312a63"><code>5bd5e1c</code></a>, <a href="https://github.com/better-auth/better-auth/commit/a787e0b66b368a1af0b4ba17c9750c2839668246"><code>a787e0b</code></a>]:</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/better-auth/better-auth/commit/c342f42fff46043b5e195f7f757b0f2c1043414c"><code>c342f42</code></a> chore: release v1.6.20 (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10108">#10108</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/21448b1b77681e71e80ae0728d8658c936c18eb8"><code>21448b1</code></a> fix: route account-linking logs through the configured logger (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10121">#10121</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/8ecf23817f5e501bdd8ab63ad5fdf2554ff1dff5"><code>8ecf238</code></a> fix(session): cap refresh cookie Max-Age at expiresIn (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/9621">#9621</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/ac4d81df748b8c09e584fdd6c440f8f327490fd1"><code>ac4d81d</code></a> chore: release v1.6.19 (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10034">#10034</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/1e697250273aff1e80e8103d296d74eafff61874"><code>1e69725</code></a> docs: clarify stateless Cognito token refresh (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10092">#10092</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/de4aa52e991f0a56786300af3e0d9ac8331f1996"><code>de4aa52</code></a> fix(cookies): chunk session and account cookies near the browser size limit (...</li> <li><a href="https://github.com/better-auth/better-auth/commit/5bd5e1cc73d2c9c38e69011f03038b61a4312a63"><code>5bd5e1c</code></a> fix: make guarded state transitions portable on Prisma (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10086">#10086</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/36f345b1bcd5c83eb16d4d967719d101394a99b0"><code>36f345b</code></a> revert: fix: allow headerless get session checks (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10053">#10053</a>) (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10074">#10074</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/635f1908702d0c63cf66b4e5f054e9d527a3c8f7"><code>635f190</code></a> fix(client): name auth client return types (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10071">#10071</a>)</li> <li><a href="https://github.com/better-auth/better-auth/commit/d009daedc75d0e61eb69e545a6ab40dd75cf541e"><code>d009dae</code></a> fix: allow headerless get session checks (<a href="https://github.com/better-auth/better-auth/tree/HEAD/packages/better-auth/issues/10053">#10053</a>)</li> <li>Additional commits viewable in <a href="https://github.com/better-auth/better-auth/commits/v1.6.20/packages/better-auth">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for better-auth since your current version.</p> </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> Co-authored-by: Nicky Leach <nicky@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
8a59cafbd5 |
build(deps): bump hermes-paperclip-adapter from 0.2.0 to 0.3.0 (#8463)
Bumps [hermes-paperclip-adapter](https://github.com/NousResearch/hermes-paperclip-adapter) from 0.2.0 to 0.3.0. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/NousResearch/hermes-paperclip-adapter/commits">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> |
||
|
|
746e287e33 |
feat(control-plane): add annotation and workspace controls (#8229)
## Thinking Path > - Paperclip is the open source app people use to manage AI-agent companies. > - The control plane coordinates issues, workspaces, documents, routines, and board review flows across company-scoped data. > - The local source branch contained related schema, service, and UI changes for workspace issue scoping and document/routine annotations. > - These changes need to move together because db schema, shared types, server services, and UI consumers form one contract. > - This pull request extracts the migration-bearing control-plane work from the source branch onto `origin/master`. > - The benefit is a standalone branch with deterministic migration order and focused review for the highest-risk part of the split. ## Linked Issues or Issue Description No GitHub issue exists for this branch split. Internal source task: [PAP-11234](/PAP/issues/PAP-11234). Problem/motivation: - Workspace operations need explicit issue scoping so readiness and blocker handling can be derived correctly. - Document annotations need reliable live updates, save failure surfacing, normalized activity keys, and better comment panel behavior. - Routine descriptions need the same annotation contract as issue documents so operators can discuss and edit routine text without special-case infrastructure. Proposed solution: - Add the workspace-operation `issueId` migration and readiness scoping. - Add routine document/annotation schema, shared types, services, routes, and UI editing support. - Keep the related migrations in one PR so the renumbered `0106` and `0107` migrations land in a deterministic order after current `master`. Alternatives considered: - Split migrations into separate PRs, rejected because that would create migration-numbering conflicts and make each branch less standalone. - Merge this with UI polish, rejected because this branch needs deeper server/db review. Roadmap alignment: - Checked `ROADMAP.md`; the roadmap mentions future recurring routine capabilities generally, but no duplicate implementation PR for these annotation/workspace changes was found. ## What Changed - Added `0106_workspace_operations_issue_id.sql` and `0107_routine_description_annotations.sql`, plus schema exports. - Scoped workspace readiness to blocker issues and attached workspace operation issue ids. - Scoped issue-thread interaction accept finalization to the source run. - Added routine document annotation contracts across db/shared/server/UI. - Improved document annotation live updates, activity-key normalization, save failure surfacing, and comment panel behavior. - Added issue workspace property controls and compact blocked-by/quick-control UI updates. - Added focused server and UI regression tests for the new contracts. ## Verification - `CI=true NODE_ENV=development pnpm install --frozen-lockfile --prefer-offline` - `NODE_ENV=test pnpm exec vitest server/src/__tests__/document-annotation-routes.test.ts server/src/__tests__/issue-thread-interactions-service.test.ts server/src/__tests__/issues-service.test.ts server/src/__tests__/routine-document-annotation-routes.test.ts server/src/__tests__/routines-routes.test.ts server/src/__tests__/workspace-runtime.test.ts ui/src/components/IssueDocumentAnnotations.test.tsx ui/src/components/IssueProperties.test.tsx ui/src/components/WorkspaceRuntimeControls.test.tsx ui/src/context/LiveUpdatesProvider.test.ts --run` — 10 files, 273 tests passed. - `NODE_ENV=test pnpm -r --filter @paperclipai/db --filter @paperclipai/shared --filter @paperclipai/server --filter @paperclipai/ui typecheck` — passed, including db migration numbering check. ## Risks - Migration-bearing PR; merge this branch before any later PR that adds migrations with higher numbers. - Cross-layer contract risk across db/shared/server/ui, mitigated with targeted tests and affected-package typecheck. - Review should pay special attention to company scoping in new routine/document annotation paths. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI GPT-5 Codex via Paperclip `codex_local` / CodexCoder, GPT-5-class coding model with tool use and shell execution. Exact runtime snapshot and context-window setting were not exposed by the Paperclip run context. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details available from the run context) - [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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (N/A per source task: do not add screenshots/images unless specifically part of the work) - [x] I have updated relevant documentation to reflect my changes (N/A; no public docs changed) - [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> |
||
|
|
e68188c438 |
fix: upstream deployed document-comment, routine-annotation, workspace & board-polling fixes (#8536)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - This change touches several already-shipped subsystems — document-comment annotations, the selected-agent Conference Room chat surface, routine description annotations, workspace-operation tracking, and the board polling/inbox UI > - A batch of incremental fixes and two small backend additions had accumulated on a local mainline and were deployed to a live instance, but never landed upstream — so each `origin/master` sync kept re-diverging > - Leaving them un-upstreamed means the same delta has to be re-merged on every sync and risks being lost or silently reverted > - This pull request rebases that delta cleanly on top of current `origin/master` (preserving recent upstream work such as reusable sandbox leases and the relation-list collapse controls) and brings it up for review > - The benefit is that mainline and the deployed instance converge, and these fixes/additions get normal review + CI + Greptile coverage ## Linked Issues or Issue Description No single GitHub issue tracks this; it is a bundle of bug fixes and two small feature additions. Following the issue-template fields: **Bug fixes (what was wrong → what this does):** - Document comments rendered out of document order, didn't live-update across clients, swallowed save failures, and lost the markdown text selection on re-render. Now: doc-order sort, live updates, surfaced save-failure state, stable selection across re-renders. - The board polling hot path returned oversized payloads on every poll. Now: an opt-in `summary` projection trims the heartbeat-run list payload. - Assorted UI fixes: sidebar nav peek/streamlining edge cases, markdown file-viewer re-mount/line-height issues on iOS Safari, inbox badge/skill deep-link tab selection, and `⌘.` work-mode cycling on iOS. **Feature additions:** - `workspace_operations.issue_id` — associate a workspace operation with the issue that triggered it (new migration `0106`, schema, service, shared type). - Routine **description annotations** — comment threads on a routine's description document, mirroring issue document annotations (new migration `0107`, `routine_documents` schema, routes/service, editable-sections UI). - Selected-agent **Conference Room chat** surface wiring and live issue-thread updates. **Related PR:** #8229 (`feat(control-plane): add annotation and workspace controls`, draft) covers overlapping annotation/workspace-control territory — flagging it so a reviewer can reconcile the two rather than double-merging. ## What Changed - `feat(workspace)`: `workspace_operations.issue_id` migration + schema/service/type; issue workspace property controls reconciled with upstream's evolved "Service" row. - `feat(routines)`: routine description annotations — `routine_documents` schema, migration `0107`, routes/service, `editable-sections` UI. - `fix(document-comments)`: doc-order sort, live updates, save-failure surfacing, stable markdown selection (+ storybook story, rerender test). - `feat(chat)`: selected-agent Conference Room chat surface and live issue-thread updates (`LiveUpdatesProvider`, `issue-chat-messages`, interactions service). - `perf(board)`: opt-in `summary` projection for the board polling/heartbeat-run list payload, plus assorted sidebar / file-viewer / inbox / IssueProperties UI fixes. Organized into 5 logical commits. Migrations are numbered incrementally after upstream's latest (`0105`) — `0106` then `0107`, no journal collision. ## Verification - Built by 3-way merging the deployed delta onto current `origin/master`; the only merge conflict (`IssueProperties.test.tsx`, two adjacent test blocks) was resolved in favor of upstream's evolved "green service link above the workspace row" layout, which matches the merged component's rendered output. - Confirmed recent upstream work is preserved post-merge: reusable sandbox lease teardown (`#8513`), the IssueProperties relation-list collapse controls, and the sidebar streamlined-nav default. - Confirmed the net diff vs `origin/master` is exactly the intended feature delta (65 files) and that overlapping server files (`issues.ts`, `agents.ts`, `heartbeat.ts`) only add feature code without disturbing upstream logic. - This delta is already running on a live deployed instance. - Full typecheck/test suite + Greptile to run in CI (see checklist). ## Risks - Two new migrations (`0106`, `0107`). Both are additive (new table / new nullable column) and ordered after upstream's `0105`; no data backfill, low risk. If another migration-bearing PR merges first, renumber before merge. - Largest blast radius is in the merged overlapping UI/service files; covered by the existing test suites for those files plus CI. - Overlaps thematically with draft PR #8229 — reviewers should reconcile rather than merge both blindly. ## Model Used Claude Opus 4.8 (`claude-opus-4-8`), extended thinking, with tool use (git, shell). Agentic coding workflow. ## 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) - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2dbaf4a7fa |
External object references across issue surfaces (#8512)
## Thinking Path > - Paperclip is the open source control plane people use to coordinate AI agents, issues, approvals, comments, and work products. > - The involved subsystem is issue context: markdown links, issue properties, related work, lists, filters, inbox/sidebar status, and plugin-provided external context. > - The gap is that URLs to external systems currently remain mostly plain links, so humans and agents must manually open them to understand status, identity, and liveness. > - This matters because external work objects such as GitHub issues and pull requests are part of the operational state of a Paperclip company. > - The implementation keeps core provider-neutral: shared contracts, storage, sync, routes, and UI surfaces live in core while providers can contribute detection and status resolution. > - This pull request adds the external object reference foundation, GitHub provider support, issue-surface rendering, filters, sidebar/list/inbox signals, and test/story coverage. > - The benefit is that linked external work becomes inspectable Paperclip context without hardcoding every provider directly into the UI. ## Linked Issues or Issue Description No public GitHub issue exists for this work. Feature request: - Problem: URLs in Paperclip issues, comments, documents, and related surfaces do not expose provider status or object identity inline. - Proposed behavior: detect supported external object URLs, persist normalized references, refresh provider status, and render concise status-aware links across issue surfaces. - Users affected: board users, agents, and maintainers who triage issues containing external work links. - Acceptance: external object references are company-scoped, provider-extensible, visible in key issue surfaces, filterable where relevant, and covered by focused shared/server/UI tests. Related PR search: - No open duplicate PRs found for `external object references`. - Closed related prior attempt: #4556. ## What Changed - Added shared external-object contracts, validators, status/liveness helpers, and plugin protocol declarations. - Added database schema and additive migrations for external objects, source mentions, and display metadata. - Added server services/routes for detecting, syncing, summarizing, refreshing, and resolving external objects across issues, documents, comments, projects, and plugins. - Added a GitHub external-object provider plus plugin SDK authoring docs. - Wired UI presentation across markdown links, comments, issue chat, documents, properties, related work, issue rows, filters, inbox/sidebar badges, and Storybook stories. - Rebasing cleanup: moved the branch onto current `master`, repaired stale worktree provision config, hardened environment-sensitive tests/mocks, and removed committed screenshot artifacts from the PR branch to keep the reviewable file set below tool limits. ## Verification - `pnpm exec vitest run packages/shared/src/external-objects.test.ts server/src/__tests__/external-object-routes.test.ts server/src/__tests__/external-objects-service.test.ts ui/src/components/ExternalObjectPill.test.tsx ui/src/lib/external-objects.test.ts` passed after rebasing: 5 files, 56 tests. - Historical branch verification before this PR creation included `pnpm test:run`, `pnpm -r typecheck`, and `pnpm build`; this PR body does not claim those were rerun after the final rebase. ## Risks - Medium: this adds a new cross-surface sync path on issue/document/comment writes. The implementation uses safe sync wrappers so external-object failures warn instead of blocking core mutations. - Medium: the migrations introduce new tables and indexes. They are additive and company-scoped. - Medium: provider-specific URL parsing can miss or misclassify edge cases. Shared canonicalization tests and provider tests cover current GitHub shapes. - Low: UI badge/filter behavior could add visual noise for object-heavy issues; component tests and Storybook stories cover the intended surfaces. > Roadmap checked: `ROADMAP.md` references the plugin system as the current extension path and does not list a duplicate core feature. Related long-range docs discuss external references, work products, preview URLs, and plugin extension points; this PR implements the scoped external-object reference foundation. ## Model Used OpenAI Codex, GPT-5 coding-agent runtime, with shell and GitHub CLI tool use. Reasoning mode: medium. Exact deployed runtime model ID and context window were not exposed in the environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [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> |
||
|
|
cd38c150b0 |
feat: reuse Daytona sandbox leases (#8513)
Add opt-in reusable Daytona sandbox lease support, including retryable pending cleanup handling.\n\nPR: https://github.com/paperclipai/paperclip/pull/8513 |
||
|
|
2e2da3bc2f |
fix: isolate remote Claude config from local credentials (#7676)
Fix remote Claude sandbox config isolation and permissions handling.\n\nPR: https://github.com/paperclipai/paperclip/pull/7676 |
||
|
|
0b945f449b |
Make streamlined sidebar default to on (#8496)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board UI has an experimental streamlined left navigation mode that changes how projects and agents appear in the sidebar. > - Today that mode is opt-in, so users keep seeing the classic navigation unless they find and enable the experiment. > - The requested product behavior is to make streamlined navigation the default experience while keeping an explicit experiments opt-out. > - This pull request flips the shared/server default, updates UI consumers to treat only explicit `false` as classic mode, and covers both the default-on path and opt-out behavior in tests. > - The benefit is that new and legacy settings get the streamlined sidebar by default without removing the classic-sidebar escape hatch. ## Linked Issues or Issue Description Refs #7645 Related: #8430 takes the broader route of removing the classic sidebar. This PR intentionally keeps the opt-out path. ## What Changed - Default `enableStreamlinedLeftNavigation` to `true` in shared validation and server-side normalization. - Preserve explicit stored `false` as the experiments opt-out for the classic sidebar. - Render the sidebar and experimental settings toggle as streamlined-on unless the setting is explicitly `false`. - Add regression coverage for loading/default streamlined sidebar behavior and the opt-out patch from the experiments page. - Remove internal issue identifiers from newly touched source comments before publishing. ## Verification - `git diff --check origin/master...HEAD` — passed. - `pnpm -r typecheck` — passed. - `pnpm exec vitest run server/src/__tests__/instance-settings-service.test.ts ui/src/components/Sidebar.test.tsx ui/src/pages/InstanceExperimentalSettings.test.tsx` — passed, 3 files / 27 tests. - `pnpm build` — passed, with existing Vite/CSS/chunk-size warnings. - `pnpm test:run` — failed in unrelated `server/src/__tests__/workspace-runtime.test.ts`: the test `auto-detects the default branch via symbolic-ref when origin/HEAD is set` creates a temp repo on `main` then runs `git push -u origin main master`; `master` does not exist in that temp repo. Summary: 1 failed, 214 passed, 1780 tests passed, 1 skipped. ## Risks Low-to-medium behavioral risk: the default sidebar changes for users who never explicitly set the experiment. Explicit `false` remains respected, so users can still opt out via experimental settings. > 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 via Codex local adapter, with tool use and code execution. Exact context window was not surfaced in 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> |
||
|
|
93fdb9c218 |
[codex] Harden same-company CEO authorization (#8276)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Companies are the primary tenant boundary for agents, board users, settings, and portability operations. > - CEO agents need limited same-company management powers, but those powers must not cross into another company. > - The affected company routes mixed route-level access checks with validation middleware and repeated CEO checks, which left adjacent mutation and portability surfaces easy to drift. > - This pull request centralizes same-company CEO-or-board authorization for those company-scoped surfaces. > - It also adds regression coverage proving a CEO agent from one company cannot read, mutate, archive, delete, export, or import against another company. > - The benefit is tighter company isolation without removing legitimate same-company CEO operations. ## Linked Issues or Issue Description Internal task: PAP-11205 / PAP-11347. Bug report: - What happened: same-company CEO authorization for company settings, branding, and portability routes was implemented per-route, making it possible for adjacent surfaces to drift and risking company-boundary mistakes. - Expected behavior: an agent API key must only manage the company that owns the authenticated agent, and only CEO agents should get the limited same-company management permissions. - Steps to reproduce: authenticate as a CEO agent from Company A and call Company B company routes such as `PATCH /api/companies/:companyId`, `PATCH /api/companies/:companyId/branding`, export/preview export, safe import preview/apply, archive, delete, or read. - Version/commit: fixed on this branch at `45edaccb8` on top of `public/master` `ddc193c2b`. - Deployment mode: server API behavior; no UI change. Related search results reviewed, not duplicates of this exact route hardening: - Refs #2212 - Refs #1083 - Refs #8053 ## What Changed - Added a shared `assertSameCompanyCeoAgentOrBoard` company route guard and reused it for company settings, branding, export, and safe import endpoints. - Moved request parsing after authorization on sensitive company mutation/export/import routes so unauthorized cross-company callers are rejected before route body validation side effects or service calls. - Tightened archive and delete ordering to assert route company access before board-only mutation authorization. - Added a cross-company company-route authorization regression suite covering read, settings, branding, archive, delete, export, export preview, import preview, and import apply paths. - Extended adjacent route/service tests to prove non-CEO and cross-company agent keys are rejected on the relevant company-scoped surfaces. - Addressed Greptile follow-ups by removing a redundant board assertion and inlining the portability authorization wrapper. ## Verification Local focused verification on rebased head `45edaccb8`: - `pnpm exec vitest run server/src/__tests__/companies-route-cross-company-authz.test.ts server/src/__tests__/company-branding-route.test.ts server/src/__tests__/company-portability-routes.test.ts server/src/__tests__/agent-permissions-routes.test.ts server/src/__tests__/authorization-service.test.ts server/src/__tests__/openclaw-invite-prompt-route.test.ts` - 6 test files passed - 127 tests passed Remote PR checks on rebased head `45edaccb8`: - Paperclip PR workflow: green, including policy, typecheck, build, e2e, canary dry run, workspace tests, server general tests, and all serialized server shards. - Greptile Review: success with 5/5 confidence on `45edaccb8`. - Greptile review threads: all resolved. ## Risks Low to moderate risk. This intentionally tightens company route authorization and changes whether some unauthorized requests fail at the authz layer before schema validation. Legitimate board users and same-company CEO agents remain covered by tests, but callers that depended on validation errors from unauthorized company routes will now receive authorization errors first. No migrations. No `pnpm-lock.yaml` changes. No `.github/workflows` changes. No screenshots or design images added. > 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.5-based coding agent with tool use, terminal execution, repository inspection, and GitHub connector 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (N/A: no UI change) - [x] I have updated relevant documentation to reflect my changes (N/A: no docs needed beyond this PR description) - [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> |
||
|
|
9ac24317e6 |
fix(issues): ignore cancelled child blockers in attention (#7577)
Fixes #7578 ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - Blocked issue health is surfaced through blockerAttention so operators can see whether blocked work has a live path. > - The blockerAttention graph uses both explicit blockedBy edges and direct child issue edges. > - Done children were already ignored, but cancelled direct children still appeared as unresolved blockers. > - Explicit cancelled dependencies should remain visible as dependency problems, but terminal direct children should not inflate a parent blocker count. > - This pull request narrows child-edge traversal to non-terminal children and adds a regression test for the observed case. > - The benefit is that cancelled child issues no longer make blocked parents look like they have extra unresolved blocker attention. ## What Changed - Added terminal child status filtering for blockerAttention parent-child traversal so cancelled direct children are ignored with done children. - Added a server regression test where a blocked parent has active explicit blockers plus a cancelled direct child; the cancelled child no longer increases unresolved counts or becomes the sample blocker. ## Verification - `perl -e 'alarm shift; exec @ARGV' 300 pnpm exec vitest run server/src/__tests__/issue-blocker-attention.test.ts` -> 19 tests passed. ## Risks - Low risk: the change only affects implicit direct-child blockerAttention edges. - Explicit blockedBy edges to cancelled issues are intentionally unchanged and remain represented as attention-required dependency problems. ## Model Used - OpenAI GPT-5, Codex coding agent in tool-enabled CLI environment; reasoning and code execution used for repository inspection, patching, git operations, and targeted 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (not applicable; no UI change) - [x] I have updated relevant documentation to reflect my changes (not applicable; bugfix covered by regression test) - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
d1e6662ed8 |
fix(server): let codex_local agents inherit host Codex login by default (#8425)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The `codex_local` adapter spawns the Codex CLI for an agent, and `server/src/routes/agents.ts` normalizes each agent's `adapterConfig.env` on create/hire/update > - PR #8272 added an isolation guard that, on every codex_local agent, force-set a per-agent `CODEX_HOME` and injected `OPENAI_API_KEY = ""`, and rejected any "shared" home > - This broke the common case: operators who deleted `CODEX_HOME` / `OPENAI_API_KEY` in the UI saw them silently re-appear on save, and every agent was forced into an isolated home instead of sharing the device's existing Codex login (`~/.codex` / `$CODEX_HOME`) > - This pull request replaces the always-on isolation guard with key-scoped isolation: a keyless agent gets no env overrides and inherits the host Codex login at runtime; we only carve out an isolated per-agent `CODEX_HOME` when the agent sets its own `OPENAI_API_KEY` > - The benefit is that env-var deletion now persists, agents on one device share the host login by default, and per-account isolation is still available by setting a per-agent key ## Linked Issues or Issue Description No public GitHub issue exists. Bug report (following `bug_report.yml`): **What happened?** In a `codex_local` agent's configuration, removing the `CODEX_HOME` and `OPENAI_API_KEY` env vars via the UI (clicking the X) appears to work, but on save they instantly re-appear. The persisted config never loses the slots. **Root cause.** `applyCodexLocalIsolationGuard` in `server/src/routes/agents.ts` (added in #8272) re-injected `CODEX_HOME` (defaulting to a per-agent home) and `OPENAI_API_KEY = ""` on every create/hire/update, and rejected shared homes outright. So a PATCH that omitted those keys had them written back server-side. **Expected behavior.** Deleting these env vars should persist. A codex_local agent with no key should inherit whatever Codex login already exists on the device. **Steps to reproduce.** 1. Open a `codex_local` agent's configuration with `CODEX_HOME` and `OPENAI_API_KEY` set. 2. Remove both env vars and save. 3. Re-open the config — both slots are back. Related (different approach): Refs #8399 (keeps per-agent isolation, fixes only the empty `OPENAI_API_KEY` slot), Refs #8272 (introduced the guard), Refs #8403 (managed-auth seeding into isolated homes). ## What Changed - `server/src/routes/agents.ts` — replaced `applyCodexLocalIsolationGuard` (+ `assertCodexLocalHomeIsNotShared` / `normalizeCodexLocalHomePath`) with `applyCodexLocalKeyIsolation`. A codex_local agent now receives **no** env overrides unless it explicitly sets `OPENAI_API_KEY`; only then is an isolated per-agent `CODEX_HOME` injected (and only if the agent has not set its own `CODEX_HOME`). Keyless agents fall back to the host Codex login at runtime. Dropped the now-unused `node:os` import and the shared-home rejection. - `server/src/__tests__/agent-adapter-validation-routes.test.ts` — updated the validation-route tests to assert env-var deletion persists, keyless agents get no overrides, and key-bearing agents still get an isolated `CODEX_HOME`. ## Verification ```bash cd server && npx vitest run src/__tests__/agent-adapter-validation-routes.test.ts ``` All 6 tests pass locally. Manually verified in the live UI: removing `CODEX_HOME` and `OPENAI_API_KEY` from a codex_local agent and saving now persists the deletion (slots no longer re-appear on reload). ## Risks - **Host-key leak for keyless agents on a host with `OPENAI_API_KEY` set.** Low/intended: the product direction here is that codex_local agents inherit the host's Codex login by default; per-account isolation is opt-in via a per-agent `OPENAI_API_KEY`, which then gets its own `CODEX_HOME`. - **Divergence from #8399.** That PR retains the per-agent isolation default and only stops injecting the empty key, so it does not address the `CODEX_HOME` re-injection half of this bug. This PR intentionally changes the default to host-login inheritance. Reviewers should pick one direction. - **No migration.** Existing agents that already store these slots are not auto-cleaned, but operators can now delete them and the deletion sticks. ## Model Used - Provider: Anthropic (Claude) - Model ID: `claude-opus-4-8` - Capabilities: tool use, code execution, extended reasoning, agentic workflow ## 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 - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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 |
||
|
|
2c98c8e1e5 |
Fix sandbox git publishing and large workspace uploads (#8422)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Sandbox and SSH runtimes need to preserve agent work across isolated execution environments > - Git-backed workspaces were being copied mostly as filesystem archives, which breaks when `.git` points outside the mounted workspace and makes sandbox agents unable to publish their own branches > - Large ignored dependency trees could also be swept into the sandbox overlay, causing multi-GB transfers and max-string failures in some sandbox clients > - This pull request makes sandbox runtime setup use a git-backed HEAD sync plus a small dirty/untracked overlay, and bounds sandbox file transfers so large archives do not need one huge string > - The benefit is that sandbox agents can commit and push from a usable git checkout without uploading dependency trees such as `node_modules` ## Linked Issues or Issue Description Refs #8395 No public duplicate issue or PR was found after searches for `sandbox git workspace`, `git push sandbox`, and `node_modules sandbox upload`. Bug report: - What happened: sandbox-backed agent workspaces could receive a `.git` file that pointed at host-only git state, leaving the sandbox unable to run normal git workflows. The sandbox overlay upload could also include ignored dependency directories, creating very large transfers. - Expected behavior: sandbox and remote runtimes should prepare a usable git-backed workspace, copy only the necessary workspace overlay, and restore git history plus file changes without depending on a host-only `.git` path. - Steps to reproduce: 1. Run an agent in a sandbox-backed workspace whose local git checkout is a worktree. 2. Ask the agent to complete a GitHub workflow that requires commit/push access. 3. Observe that git operations can fail inside the sandbox, and ignored dependency trees can be uploaded as part of the workspace overlay. - Paperclip version or commit: reproduced against `master` before this PR, base `7aa212296eb1`. - Deployment mode: local dev / sandbox-backed runtime. - Installation method: built from source. - Agent adapters involved: local adapters using shared adapter-utils runtime preparation. - Database mode: not database-related. - Access context: agent runtime. - Local verification environment: Node.js v25.6.1, pnpm 9.15.4, macOS arm64. - Privacy checklist: all pasted output was reviewed for secrets, private hostnames, local usernames, and internal instance links. ## What Changed - Added a GitHub workflow push preflight so agent runs can detect missing push credentials when a workflow explicitly needs GitHub publishing. - Added shared git workspace sync helpers for shallow HEAD import/export and dirty/untracked overlay tracking. - Updated sandbox managed runtime setup to use git history plus a selected overlay instead of uploading the full local workspace for git-backed workspaces. - Bounded sandbox archive upload/download paths so large payloads stream or chunk instead of materializing one oversized string. - Excluded `.git` and ignored dependency trees from sandbox upload, download, and restore baselines while preserving local ignored directories during sync-back. - Added focused tests for git workspace sync, sandbox overlay selection, transfer chunking, and heartbeat push-preflight behavior. ## Verification - `pnpm exec vitest run packages/adapter-utils/src/git-workspace-sync.test.ts packages/adapter-utils/src/sandbox-managed-runtime.test.ts packages/adapter-utils/src/command-managed-runtime.test.ts server/src/__tests__/heartbeat-project-env.test.ts server/src/__tests__/heartbeat-workspace-session.test.ts` - `pnpm --filter @paperclipai/adapter-utils typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm build` - Public-hygiene scan of the PR diff and commit messages for internal issue ids, local paths, private hostnames, and obvious token patterns. ## Risks - Medium risk: this changes sandbox runtime synchronization semantics for git-backed workspaces, especially around dirty tracked files, untracked files, deleted paths, and ignored files. - The main mitigation is focused test coverage for upload contents, restore exclusions, and git round-trip behavior. - The SSH runtime keeps the current bundle-based implementation from `master`; this PR only aligns shared excludes and sandbox behavior with that model. ## Model Used OpenAI Codex, GPT-5-based coding agent, tool-enabled shell/git/GitHub workflow, with code execution and repository 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 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] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
33353ce62b |
feat(skills): remove bundled paperclip-dev skill and retire required skill attribute (#7029)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Local adapters (Claude, Codex, Cursor, Gemini, Grok, OpenCode, Pi, ACPX) ship bundled "skills" — opinionated Markdown prompt bundles materialized into the agent's runtime > - One of those bundled skills, `paperclip-dev`, existed to let agents develop Paperclip itself; it has now moved to its own external repo and no longer belongs in the core tree > - The adapter skill model also carried a `required` / `requiredReason` attribute plus a `paperclip_required` `AdapterSkillOrigin` variant, all of which only existed to mark bundled skills as non-optional in the UI and adapter sync logic > - With `paperclip-dev` gone, no bundled skill is "required" anymore, and the type / runtime surface for `required` is dead weight — but it is computed at request time and never persisted, so a clean removal is safe (no compatibility shim needed) > - This pull request deletes `skills/paperclip-dev/` and removes every trace of the `required` / `requiredReason` field and the `paperclip_required` origin across shared types, validators, adapter-utils, all eight local adapters, server routes, the company-skills service, the UI, the storybook fixtures, and the test suite > - The benefit is a smaller, simpler adapter-skill surface: one origin (`company_managed`) for managed bundled skills, `resolvePaperclipDesiredSkillNames` collapses to "just the configured desired set", and the AgentDetail skills tab no longer renders a "Required by Paperclip" section that no longer applies ## Linked Issues or Issue Description <!-- No existing public GitHub issue; describing the underlying work inline (feature_request template fields). --> **Summary** Remove the bundled `paperclip-dev` skill (now maintained in its own external repo) and retire the `required` / `requiredReason` skill attribute and the `paperclip_required` skill origin, which only existed to support it. **Problem or motivation** `paperclip-dev` is the only bundled skill that was ever marked "required". Now that it lives in a separate repository, shipping it inside the core tree is wrong, and the entire `required` surface (a type field, a validator field, a synthesized `paperclip_required` origin, UI "Required by Paperclip" section, and required-skill merging in the desired-skills calculation) becomes dead weight. The `required` value is computed at request time and never persisted, so it can be removed cleanly without a migration or compatibility shim. **Proposed solution** Delete `skills/paperclip-dev/`, drop the `required` / `requiredReason` fields and `paperclip_required` origin everywhere they are produced or consumed, collapse managed-skill origin to a single `company_managed` value, and simplify `resolvePaperclipDesiredSkillNames` to return only the configured desired set. **Alternatives considered** Keeping the `required` attribute as a no-op for forward compatibility — rejected because it is request-time only (nothing persists it), so leaving it in place is pure dead surface area with no callers. **Roadmap alignment** Internal cleanup / dead-code removal that simplifies the adapter-skill surface; it does not introduce or duplicate any planned core feature in ROADMAP.md. ## What Changed - Deleted bundled `skills/paperclip-dev/` (moved to a separate repo). - Dropped `required`, `requiredReason`, and the `paperclip_required` origin from `packages/shared/src/types/adapter-skills.ts`, `packages/shared/src/validators/adapter-skills.ts`, and `packages/adapter-utils/src/types.ts`. - In `packages/adapter-utils/src/server-utils.ts`: removed `readSkillRequired()`; dropped `required`/`requiredReason` from `listPaperclipSkillEntries()`, `normalizeConfiguredPaperclipRuntimeSkills()`, `buildPersistentSkillSnapshot()`, and `PaperclipSkillEntry`; collapsed `buildManagedSkillOrigin()` to always return `company_managed`; simplified `resolvePaperclipDesiredSkillNames()` to return only the configured desired set (signature preserved so adapter call sites are untouched). - Walked all eight local adapters (`acpx-local`, `claude-local`, `codex-local`, `cursor-local`, `gemini-local`, `grok-local`, `opencode-local`, `pi-local`) and removed every remaining `requiredReason` / `paperclip_required` reference. - `server/src/services/company-skills.ts`: dropped the `required = sourceKind === "paperclip_bundled"` synthesis when listing runtime skill entries. - `server/src/routes/agents.ts`: removed required-skill merging from the desired-skills calculation in the persist-config path and the unsupported-snapshot path (keeping the current version-aware `desiredSkillEntries` structure). - `ui/src/pages/AgentDetail.tsx`: dropped required-based filters, the required tooltip, and the entire "Required by Paperclip" section from the agent skills tab; storybook fixtures in `ui/storybook/stories/acpx-local.stories.tsx` cleaned up to match. - Tests: deleted the `required: false` case in `paperclip-skill-utils.test.ts` and the "keeps required bundled skills installed" case in every `*-local-skill-sync.test.ts`; `acpx-local-execute.test.ts`, `cursor-local-execute.test.ts`, `cursor-local-skill-sync.test.ts`, `agent-skills-routes.test.ts`, and `packages/adapter-utils/src/server-utils.test.ts` were updated to drop removed fields and map `origin: "paperclip_required"` → `"company_managed"`. - `server/src/adapters/registry.ts`: two `as unknown as ServerAdapterModule["..."]` casts on `hermesListSkills` / `hermesSyncSkills` (matching the existing `executeHermesLocal` pattern). `hermes-paperclip-adapter@0.2.0` still depends on the published `@paperclipai/adapter-utils` which keeps the retired `paperclip_required` variant; the cast bridges the workspace-vs-published type mismatch at the registry seam and can drop once hermes upgrades. ## Verification Run from the workspace root: ```sh grep -rn "skills/paperclip-dev" . grep -rn "paperclip_required" --include="*.ts" --include="*.tsx" . grep -rn "requiredReason" --include="*.ts" --include="*.tsx" . pnpm -w typecheck pnpm --filter @paperclipai/server exec vitest run paperclip-skill-utils pnpm --filter @paperclipai/server exec vitest run skill-sync ``` The first three greps return only the explanatory comment in `server/src/adapters/registry.ts` (no live `paperclip_required` / `requiredReason` usage) and zero `skills/paperclip-dev` source hits. Locally: - `pnpm -w typecheck` → all packages this PR touches pass (adapter-utils, shared, server, ui, cli, and the cursor/gemini/opencode/pi adapters). - Affected vitest suites pass: `paperclip-skill-utils`, `server-utils`, all eight `*-local-skill-sync`, `agent-skills-routes`, and the `acpx`/`cursor`/`pi` execute suites. ## Risks - Behavioral shift in the agent skills UI: the "Required by Paperclip" section disappears. No bundled skill is required anymore, so this only affects environments that previously surfaced `paperclip-dev` as a forced-on row; those installs will see the skill move into the regular "company-managed" list (and be uninstalled on next sync unless explicitly listed as desired). - Existing agents may still have the string `"paperclip-dev"` in their persisted `desiredSkills`. That entry is inert (no source for it to install from); a one-time DB cleanup is out of scope. Low risk. - Hermes adapter type bridge: two casts in `registry.ts` paper over a type-only divergence between the workspace `@paperclipai/adapter-utils` and the published version still pinned by `hermes-paperclip-adapter@0.2.0`. Runtime behavior is unaffected because the retired `paperclip_required` value is no longer produced by anything in this tree. The casts can be removed once hermes upgrades its dependency. ## Model Used - Provider: Anthropic - Model: Claude Opus 4.7 (`claude-opus-4-7`) - Capability: agent tool use via Paperclip's `claude_local` adapter ## 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 - [ ] 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> |
||
|
|
5ebbe67ebd |
fix(workspace-runtime): base fresh worktrees on origin/master and refresh unstarted reuses (#8412)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agent work runs inside git worktrees created by the workspace runtime, each branched from a configured base ref (typically the repo's default branch) > - When the local `master` is stale or ahead of `origin/master` (committed but unpushed work, or local-only commits), a freshly created worktree inherits that divergence — so an unrelated task branch silently carries commits it never intended to touch > - This surfaced as a docs-only task whose PR accidentally pulled in unrelated changes from a diverged local master > - The base for a fresh worktree should be resolved authoritatively to the remote-tracking ref (`origin/<branch>`), and an idle/unstarted reused worktree should be safely fast-forwarded — without ever destroying in-progress work > - This pull request makes both behaviors explicit in the workspace runtime > - The benefit is that task branches start from a clean, authoritative base, eliminating accidental inclusion of unrelated local changes ## Linked Issues or Issue Description This is a bug fix. No public GitHub issue exists, so describing it inline following the Bug Report template: **What happened** A task intended to change only docs produced a PR that also contained unrelated changes pulled in from `master`. The root cause: when a new worktree is created from a configured local branch (e.g. `master`), the worktree inherits whatever that local branch points at. If the local `master` has committed divergence from `origin/master` (unpushed or local-only commits), that divergence leaks into the new task branch. The leak comes from committed local-vs-`origin/master` ref drift, not uncommitted working-tree changes (each worktree has its own working tree). **Expected behavior** A fresh worktree should be based on the authoritative `origin/master` head so unrelated local commits never seed a task branch. **Steps to reproduce** 1. Have a local `master` that is ahead of `origin/master` (committed but unpushed work). 2. Create a new worktree/task branched from `master` via the workspace runtime. 3. Open a PR from that branch — it carries the unrelated local commits. **Deployment mode** Self-hosted / local workspace runtime. ## What Changed - Fresh worktrees now resolve their base ref authoritatively: a configured local branch (e.g. `"master"`) is mapped to its `origin/<branch>` remote-tracking counterpart so unpushed/ahead local commits can never seed a task branch. Remote-tracking refs, SHAs, and tags are used verbatim; an unset/`HEAD` base falls back to the detected default branch. The resolved ref is recorded (`repoRef`) so downstream drift checks stay accurate. - If a configured local branch has no matching `origin/<branch>`, the runtime warns and falls back to the local ref rather than failing. - On reuse, a *provably unstarted* worktree (no commits past base + clean tree including untracked files) is fast-forwarded to the latest `origin/master`. Started or dirty worktrees keep the prior warn-only behavior, so in-progress work is never reset. Only remote-tracking bases are eligible for the refresh. ## Verification - `cd server && npx vitest run src/__tests__/workspace-runtime.test.ts` - 5 new tests cover: local-branch→`origin/<branch>` mapping, no-remote fallback warning, unstarted-reuse fast-forward, and that started/dirty worktrees are left untouched. - Result: 65 passed. 1 pre-existing failure (`auto-detects the default branch via symbolic-ref when origin/HEAD is set`) is unrelated to this change and fails only due to the test host's git default-branch config (test setup runs `git push -u origin main master` but the local default branch is `main`); it also fails on `master`. ## Risks - Low risk. The refresh path is intentionally conservative: it only fast-forwards worktrees that are provably unstarted (zero commits past base and a fully clean tree, including untracked files) and only when the base is a remote-tracking ref. Started or dirty worktrees fall through to the existing warn-only drift behavior, so no in-progress work can be destroyed. - Behavioral shift: fresh worktrees configured against a local branch will now base on `origin/<branch>` instead of the local ref. This is the intended fix; the only case it changes is when local and remote have diverged. ## Model Used Claude — `claude-opus-4-8` (extended thinking, tool use / code execution via Claude Code). ## 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 - [ ] If this change affects the UI, I have included before/after screenshots (N/A — no UI changes) - [x] I have updated relevant documentation to reflect my changes (N/A — no doc changes needed) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (pending CI run) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (pending review) - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
67ca8287e8 |
fix(codex-local): seed managed auth into isolated homes (#8403)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The `codex_local` adapter isolates local Codex runs by assigning managed `CODEX_HOME` state per company and per agent > - PR #8272 tightened that isolation, but it left a gap: once `CODEX_HOME` became explicit, the adapter treated it like a user-managed override and skipped auth seeding > - That meant newly isolated agents could launch with no usable `auth.json`, hit OpenAI unauthenticated, and fail with `401 Missing bearer` > - Users who had already persisted one of those broken managed homes could remain stranded even after config changes unless Paperclip repaired the home itself > - This pull request teaches Paperclip to seed managed homes correctly, backfill already-stranded managed homes on startup, and reject credential-less managed homes before they reach the provider > - The benefit is that affected managed `codex_local` agents recover automatically after upgrade and restart, without manual `CODEX_HOME` surgery ## Linked Issues or Issue Description - Fixes #497 - Refs #5028 - Related PR: #8272 - Related PR: #8399 ## What Changed - Distinguished Paperclip-managed `CODEX_HOME` paths from genuine external overrides and always seeded auth into managed homes, even when `CODEX_HOME` is explicit in config. - Wrote API-key-backed `auth.json` files for managed homes when `OPENAI_API_KEY` is configured, otherwise symlinked the shared Codex auth for subscription/OAuth flows. - Added a startup reconciliation pass that backfills already-isolated managed homes created by the broken release so upgrade plus restart repairs stranded agents automatically. - Preserved previously resolved API-key auth when the stored `OPENAI_API_KEY` binding is secret-backed and startup cannot resolve the secret value directly. - Hardened the managed-home preflight to require a credential-bearing `auth.json`, not just file presence, and documented the recovery behavior. - Added regression tests covering managed-home seeding, fail-fast behavior, and server-side startup reconciliation. ## Verification ```bash pnpm exec vitest run packages/adapters/codex-local/src/server/codex-home.test.ts packages/adapters/codex-local/src/server/execute.auth.test.ts server/src/__tests__/codex-auth-reconciliation.test.ts server/src/__tests__/codex-local-execute.test.ts server/src/__tests__/server-startup-feedback-export.test.ts pnpm --filter @paperclipai/adapter-codex-local typecheck pnpm --filter @paperclipai/server typecheck pnpm check:tokens pnpm exec vitest run server/src/__tests__/server-startup-feedback-export.test.ts ``` GitHub Actions `PR` workflow is green on latest head `e5b1e08d4`, including policy, typecheck, test shards, build, e2e, serialized server suites, and canary dry run. Greptile Review is green on latest head with 0 comments added. No UI changes. ## Risks - Startup reconciliation now mutates persisted managed Codex homes at boot. Risk is low because it only touches Paperclip-managed company/agent home paths and no-ops when a home already has usable auth. - Genuine external `CODEX_HOME` overrides remain intentionally self-managed, so those users still own repair steps inside their custom home. - Hosts with neither shared Codex auth nor an explicit per-agent API key now fail earlier with a clearer adapter error instead of surfacing a downstream `401`, which changes timing but not capability. ## Model Used - OpenAI Codex, GPT-5-based coding agent in a local Codex session; exact served model ID/context window were not exposed to the session. Tool use and code 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 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] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
d5ceb82571 |
Prefer loopback runtime API URL for local agents (#5102)
## Thinking Path > - Paperclip is the open-source app that manages AI agents and their work coordination > - The server subsystem exposes a control-plane HTTP API that agents read and write task state against at runtime > - On local development machines, Paperclip binds to loopback (`127.0.0.1:3100`) but also advertises LAN hostnames via `allowedHostnames` for multi-device setups > - Agents inherit their API URL from `PAPERCLIP_API_URL` / `PAPERCLIP_RUNTIME_API_URL` env vars exported during server startup > - `choosePrimaryRuntimeApiUrl` was selecting the first entry in `allowedHostnames` (the LAN IP) before the loopback bind host, so agents on the same machine tried to connect to an unreachable LAN address (NEE-327) > - This PR fixes the chooser to return the normalized loopback bind host first, before considering LAN `allowedHostnames` > - The benefit is that local agents reliably reach the control plane regardless of `allowedHostnames` configuration ## What's going on Local Paperclip agents were sometimes inheriting `PAPERCLIP_API_URL=http://192.168.1.50:3100` even when the server was bound to loopback, which made the control plane unreachable from this workspace. This keeps the runtime API on the loopback bind host for local startup while still preserving LAN candidates for other callers. ## Problem `choosePrimaryRuntimeApiUrl` preferred the first allowed hostname over the actual loopback bind host. In the failing setup from NEE-327, that exported `http://192.168.1.50:3100` into agent env even though `http://127.0.0.1:3100` was the reachable control-plane URL. ## Solution The primary runtime URL chooser now returns the normalized loopback bind host before considering `allowedHostnames`. I added a focused unit test for the chooser and a startup regression that verifies `PAPERCLIP_RUNTIME_API_URL` / `PAPERCLIP_API_URL` stay on `127.0.0.1` while the candidate list still includes the LAN hostname. ## Testing - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/runtime-api.test.ts src/__tests__/server-startup-feedback-export.test.ts` - Result: `2` files passed, `13` tests passed - Runtime check: `curl -sS http://127.0.0.1:3100/api/health` returned `{"status":"ok",...}` during this heartbeat ## Notes Already-running local Paperclip servers need a restart to export the corrected `PAPERCLIP_API_URL` into new agent runs. Rollback is revert `df8d7fcf`. ## Model Used Claude Sonnet 4.6 (`claude-sonnet-4-6`), 1M context window, via the Paperclip Founding Engineer agent harness. Capabilities used: extended tool use, code editing, test execution, shell commands. ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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: Neeraj Kumar Singh <b.nirajkumarsingh@hotmail.com> |
||
|
|
c0743482bc |
fix(claude-local): tolerate sandboxes whose Claude CLI lacks --effort (#8393)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The claude-local adapter launches the Claude CLI inside execution environments (local, SSH, and ephemeral sandboxes such as Daytona) > - Newer adapter code passes `--effort` to the CLI, but the Claude binary baked into some sandbox images is older and rejects it with `error: unknown option '--effort'`, so every run in those environments fails > - This needs addressing because the failure is environment-dependent and silent from the operator's perspective — the run just dies with a CLI usage error > - This pull request probes the in-sandbox CLI for `--effort` support once, caches the result per environment, and strips the flag (with a warning) when the CLI does not support it > - The benefit is that sandboxes with older Claude CLIs keep working instead of failing, with negligible probe overhead because the capability check is cached and reused across ephemeral leases ## Linked Issues or Issue Description No public GitHub issue exists. Describing the bug inline following the bug report template: ### What happened? Runs using the `claude-local` adapter inside certain sandbox/execution environments fail with `error: unknown option '--effort'`. The adapter unconditionally appends `--effort` to the Claude CLI invocation, but the Claude CLI version present in some sandbox base images predates that flag, so the process exits with a usage error and the run dies. ### Expected behavior The adapter should detect that the target environment's Claude CLI does not support `--effort` and degrade gracefully — drop the flag and emit a warning — rather than failing the run. ### Steps to reproduce 1. Configure an execution environment (e.g. a sandbox image) whose bundled Claude CLI is old enough to predate the `--effort` option. 2. Run any claude-local task that resolves to an effort level (so `--effort` is appended). 3. Observe the run fail immediately with `error: unknown option '--effort'`. ### Paperclip version or commit `master` at the time of this PR (branch forked from current `master`). ### Deployment mode Self-hosted / local instance using execution environments (reproducible with ephemeral sandbox providers such as Daytona where `reuseLease: false`). ### Agent adapter(s) involved Claude Code (`claude-local`). ## What Changed - Add a CLI capability probe (`cli-capabilities.ts`) that runs the target Claude binary's `--help` inside the execution environment to detect `--effort` support. - Strip `--effort` from the CLI args (emitting a warning) when the probe reports the flag is unsupported; keep it otherwise. - Cache probe results keyed by `sandbox:providerKey:environmentId:command` (no lease id) so the probe is reused across ephemeral leases — important for `reuseLease: false` sandbox configs like Daytona, which would otherwise re-probe on every run. - Conservative fallback: if the probe itself can't run/parse, assume the flag is supported (preserves prior behavior). ## Verification - `node_modules/.bin/vitest run src/__tests__/claude-local-execute.test.ts src/__tests__/claude-local-adapter-environment.test.ts` → **2 files, 30 tests passed**. - Regression test issues two `execute()` calls with distinct lease ids and asserts the in-sandbox `--help` probe runs exactly once (cache reuse across leases). - Added tests covering: flag stripped when unsupported, flag retained when supported, warning emitted, and conservative fallback when the probe fails. ## Risks Low risk. The change is additive and gated behind a probe with a conservative default (assume supported on probe failure), so existing environments that support `--effort` are unaffected. Worst case for an environment where the probe is unreliable is the prior behavior (flag passed through). ## Model Used Claude Opus 4.8 (claude-opus-4-8), extended thinking, with tool use / code execution via Claude Code. ## 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 - [ ] If this change affects the UI, I have included before/after screenshots (N/A — no UI change) - [ ] I have updated relevant documentation to reflect my changes (N/A — no doc-facing behavior change) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (pending CI) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (pending review) - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
07e98d2b2c |
feat(adapter-utils): add observable sandbox sync progress (#8395)
## Thinking Path > - Paperclip is the control plane for running AI-agent companies, so long-running remote work needs to stay observable to human operators. > - Cloud / sandbox agents are an active roadmap area, and their workspace sync path is part of the runtime substrate every remote coding run depends on. > - In the sandbox and SSH execution-target flows, Paperclip logged that sync had started, then often went silent for the full transfer window. > - That made large remote syncs feel stalled and also hid a real performance problem in the command-managed sandbox upload path. > - The first part of this pull request threads a throttled progress-reporting surface through the adapter execution-target stack so sync and restore work can emit meaningful updates. > - The second part fixes the command-managed sandbox transport itself: it removes the old serial 32KB append bottleneck, but also falls back away from the single-stream path when a provider-backed sandbox runner cannot surface mid-flight stdin progress. > - The result is that sandbox and SSH transfers are both faster and more observable, including the live Daytona-style sandbox case that previously only emitted `0%` and `100%`. ## Linked Issues or Issue Description No public GitHub issue exists for this bug, so it is described inline below following the bug report template. ### What happened - Remote sandbox and SSH workspace syncs could spend a long time transferring data while only logging a start line (`Syncing workspace and runtime assets to sandbox environment`) and, at best, a terminal line. - In the command-managed sandbox path, the original upload implementation also paid a large performance cost by appending base64 data in many small sequential remote writes (thousands of serial 32KB round-trips on a large workspace). - After the initial transport rewrite, live provider-backed sandbox runs still only emitted `0%` and `100%` because the single-stream stdin RPC buffered progress until completion. ### Expected behavior - Long-running sandbox and SSH syncs should periodically report how much of the transfer is complete (a percentage and/or MB transferred) so an operator can tell the run is healthy and making progress rather than stuck. - The main sandbox upload path should not be artificially slow. - A transfer that fails partway should leave an explicit failure marker in the log rather than a dangling intermediate percentage. ### Steps to reproduce 1. Run an agent against a sandbox (command-managed) or SSH (remote-managed) execution target with a non-trivial workspace. 2. Watch the run log during the workspace/runtime asset sync phase. 3. Observe that the log shows the sync start line and then stays silent for the full transfer (live provider-backed sandbox runs only show `0%` then `100%`). ### Paperclip version or commit - Branch `PAPA-825-provide-status-updates-when-syncing-sandboxes` off `master`. ### Deployment mode - Self-hosted / local instance using sandbox (command-managed) and SSH (remote-managed) execution targets, including provider-backed sandbox runners. ## What Changed - Added shared throttled runtime progress reporting and threaded `onProgress` through the adapter execution-target surface and adapter `execute.ts` entrypoints. - Added sync and restore progress reporting for the command-managed sandbox path and the SSH/remote-managed path, including git import/export progress where totals are known. - Reworked command-managed sandbox transfer behavior so uploads use the faster single-stream path when appropriate, but fall back to chunked progress-emitting writes when the runner cannot expose mid-stream stdin progress. - Marked provider-backed environment sandbox runners as not supporting single-stream stdin progress so live sandbox runs emit meaningful intermediate updates instead of only `0%` and `100%`. - Emit an explicit terminal failure marker (`failed at NN% (x/y MB)`) when an SSH/tar transfer rejects, so a failed sync no longer leaves a dangling intermediate percentage in the log. - Run the SSH sync/restore size estimate (local directory walk / remote `du` probe) concurrently with the transfer instead of awaiting it before opening the pipe, so progress instrumentation no longer adds startup latency proportional to workspace file count. - Added and extended focused regression coverage for runtime progress throttling and the new failure marker, command-managed sandbox transfers, sandbox orchestration, SSH transfer progress, and environment execution-target wiring. ## Verification - `pnpm exec vitest run packages/adapter-utils/src/runtime-progress.test.ts packages/adapter-utils/src/ssh-fixture.test.ts packages/adapter-utils/src/command-managed-runtime.test.ts packages/adapter-utils/src/sandbox-managed-runtime.test.ts` - `pnpm exec vitest run packages/adapter-utils/src/command-managed-runtime.test.ts server/src/__tests__/environment-execution-target.test.ts` - `npx tsc --noEmit` for `packages/adapter-utils` ## Risks - The provider-backed sandbox fallback now prefers chunked command-managed writes when progress hooks are active, so small-to-medium uploads may trade some raw throughput for observable intermediate progress on runtimes that cannot surface true mid-stream stdin progress. - Progress percentages on tar-based transfers still depend on estimates in some cases, so operators may briefly see MB-only lines before the estimate resolves, then near-final clamping before the terminal `100%` line. - This PR changes shared execution-target behavior used by multiple adapters, so regressions would most likely appear in remote runtime setup/teardown flows rather than in a single adapter. ## Model Used - Initial implementation: OpenAI GPT-5.4 via Codex local agent (`codex_local`), high reasoning mode. - Observability follow-ups (failure marker, concurrent size estimate, added tests): Claude Opus 4.8 via Claude Code (`claude_local`). ## 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] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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: Paperclip <noreply@paperclip.ing> |
||
|
|
e93d78b46c |
fix(server): harden live events upgrade sockets (#8383)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The server exposes live event updates to board and agent clients over WebSocket upgrade requests > - WebSocket upgrade authorization can be asynchronous, leaving the raw HTTP upgrade socket in server-owned code before `ws` takes over > - If the client disconnects during that authorization window, the server can still try to reject or upgrade a closed socket > - A raw socket write after peer disconnect can emit `EPIPE` / `ECONNRESET`, and without a listener that can become process-fatal > - This pull request hardens the pre-`ws` upgrade socket path and adds regression coverage for disconnect/error races > - The benefit is that live event reconnect churn degrades gracefully instead of risking a server crash ## Linked Issues or Issue Description External public context: Refs https://github.com/aronprins/paperclip-desktop/issues/14 No matching open upstream issue or PR was found when searching `paperclipai/paperclip` for `EPIPE`, `rejectUpgrade`, `live-events-ws`, `websocket upgrade`, and related socket-write terms. ### Bug report **What happened?** The live events WebSocket upgrade handler could write a rejection response to the raw upgrade socket after the peer had already disconnected during async authorization. A transport-level `EPIPE` or similar socket error on that raw socket can terminate the server process if it is emitted without an error listener. **Expected behavior** The server should not write to destroyed/non-writable upgrade sockets, should tolerate raw socket errors while authorization is pending, and should not call `handleUpgrade()` after the socket is no longer writable. **Steps to reproduce** 1. Start a Paperclip server with live events enabled. 2. Open a raw WebSocket upgrade request to `/api/companies/:companyId/events/ws`. 3. Disconnect the client before async authorization resolves. 4. Let the server take the reject or upgrade path. 5. Observe that the pre-fix path can still write to or upgrade a closed socket. **Paperclip version or commit** Reproduced by static inspection on `master` before this PR at `950484d20`. **Deployment mode** Any mode using live event WebSocket upgrades. The report was originally observed from local Desktop embedding, but the vulnerable code is in the server package. ## What Changed - Added a writable-state guard for raw upgrade sockets before rejecting or completing an upgrade. - Changed rejection responses from raw `write()` + `destroy()` to guarded `end()` with warning logging if rejection fails synchronously. - Attached a temporary raw socket error listener during the async upgrade authorization window and cleaned it up on socket close or successful `ws.handleUpgrade()`. - Added regression tests for rejecting after an early socket close and for handling raw socket `error` events while authorization is pending. ## Verification - `pnpm exec vitest run server/src/__tests__/live-events-ws.test.ts` - `pnpm --filter @paperclipai/server typecheck` - `git diff --check` ## Risks - Low risk: the change is scoped to the live-events WebSocket upgrade path before `ws` takes ownership of the socket. - Rejected upgrade responses now use graceful `socket.end(...)`; clients should still receive the same HTTP status text when the socket is writable. - The temporary error listener is removed before successful `handleUpgrade()` so normal WebSocket client error handling remains owned by the existing `connection` path. > 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 coding agent with repository-aware tool use, shell command execution, GitHub connector access, and local code editing. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
547463d3a2 |
refactor(environments): make execution environments instance-scoped (#8375)
## Thinking Path > - Paperclip is the control plane for AI-agent companies, so execution environment selection has to stay inspectable and predictable across companies, agents, and runs. > - The environment subsystem decides where an agent heartbeat actually runs and how remote sandbox state is realized and restored. > - That subsystem previously mixed company-scoped environment catalogs with issue-level environment stamping, so a reassigned issue could keep executing in the previous assignee's sandbox. > - That behavior breaks the control-plane contract: changing the assignee should change the executing agent/environment path unless there is an explicit current override. > - Fixing it cleanly required more than a narrow patch; the environment model had to move to instance scope with a single inherited default and per-agent override semantics. > - This pull request rewires the schema, server/API surface, runtime resolution, and UI around that model, then adds regression coverage for cross-company inheritance and per-agent isolation. > - The benefit is that environment choice now follows the approved instance/agent configuration path instead of stale issue state, while shared environments only need to be configured once per instance. ## Linked Issues or Issue Description - No directly matching public GitHub issue or PR was found while searching for this refactor. ### What happened? Reassigning work between agents with different execution environments could keep running in the previous sandbox because environment choice was stamped onto the issue and outranked the current assignee. The same subsystem also forced environment catalogs to be duplicated per company even though the underlying execution environments were instance-wide resources. ### Expected behavior Execution should resolve through the current instance and agent configuration path, with one instance-scoped environment catalog, one instance default, optional per-agent override, and no stale issue-level environment authority surviving reassignment. ### Steps to reproduce 1. Configure two agents to use different execution environments. 2. Assign an issue to the first agent so the issue records execution state in that environment. 3. Reassign the same issue to the second agent and run another heartbeat. 4. Observe that the pre-fix runtime can still sync or execute in the original sandbox instead of the second agent's environment. ### Paperclip version or commit Current `master` before this PR. ### Deployment mode Self-hosted server. ### Installation method Built from source (`pnpm dev` / `pnpm build`). ### Agent adapter(s) involved - Claude Code - Not adapter-specific (core bug in environment authority / resolution) ### Database mode External Postgres. ### Access context Both board reassignment and agent heartbeats were involved. ## What Changed - Moved environments and their default selection contract to instance scope in DB/shared types, including the migration that dedupes legacy per-company environments and seeds the instance local default. - Reworked environment CRUD/auth flows to use instance-scoped APIs and added route/service coverage for instance-level environment management. - Changed runtime resolution to prefer `agent default -> instance default -> built-in local`, removed issue-level environment stamping from the active execution path, and isolated sandbox/plugin leases by `(executionWorkspaceId, agentId)`. - Added environment env-var runtime precedence so environment-provided values act as the baseline for agent execution. - Moved the environment UI into instance settings and updated agent configuration surfaces to reflect inherit/override behavior. - Added regression coverage for instance-default inheritance across companies and for the new runtime resolution behavior. - Fixed a rebase-only duplicate `enableTaskWatchdogs` flag regression in instance settings types/validators/services so the branch typechecks cleanly on current `master`. - Updated stale server tests so CI matches the shipped instance-scoped environment contract. ## Verification - `git diff --check` - `pnpm --filter @paperclipai/shared typecheck` - `pnpm --filter @paperclipai/db typecheck` - `pnpm exec vitest run server/src/__tests__/environment-runtime-driver-contract.test.ts server/src/__tests__/agent-permissions-routes.test.ts server/src/__tests__/environment-routes.test.ts server/src/__tests__/environment-instance-routes.test.ts server/src/__tests__/execution-workspace-policy.test.ts server/src/__tests__/heartbeat-plugin-environment.test.ts server/src/__tests__/instance-settings-routes.test.ts` ## Risks - The migration changes environment scope and dedupes existing rows, so installs with unusual legacy environment combinations should be reviewed carefully during upgrade. - Remote execution behavior now depends on instance-default inheritance semantics instead of issue-level stamping, so any remaining code paths that still assume issue-scoped environment authority would surface as follow-up bugs. - This PR includes both server/runtime behavior and UI relocation, so reviewers should watch for authorization edge cases around instance settings and environment management. > I checked [`ROADMAP.md`](ROADMAP.md). This work fits the existing Cloud / Sandbox agents direction as a bug-fix/refactor to current behavior, not a new parallel product surface. ## Model Used - OpenAI Codex coding agent in this Paperclip/Codex session; GPT-5-class tool-using model with code execution and shell access. The exact backend model ID is not exposed to the session 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 - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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 |
||
|
|
631b7806ed |
Add heartbeat preflight budget caps (#8347)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Heartbeats are the control-plane path that turns scheduled,
comment-driven, or on-demand wakeups into adapter executions.
> - Budgeting and recurring work need enforcement before an adapter
starts, not only after model usage is recorded.
> - Empty timer wakes also need an opt-in fast-exit path so operators
can keep routine schedules without paying for no-op model turns.
> - This pull request adds heartbeat preflight gates for daily run and
daily cost caps, plus an explicit timer no-work skip policy.
> - The benefit is safer autonomous operation: capped agents stop before
new execution, queued work is cancelled cleanly at claim time, and
proactive agents still run by default unless the operator opts into
no-work skipping.
## Linked Issues or Issue Description
No public issue exists for this change. Inline bug report:
### What happened?
Heartbeat execution can start without enforcing per-agent daily
invocation and spend limits at the heartbeat boundary. A run that was
queued before a cap was reached can also be claimed later and invoke the
adapter unless the cap is checked again immediately before execution.
Operators also do not have an explicit opt-in fast-exit policy for
generic timer wakes with no actionable assigned work.
### Expected behavior
Configured daily run and daily cost caps should stop new heartbeat runs
before adapter execution. Already queued runs should be rechecked at
claim time and cancelled cleanly when a cap is now reached. Queued issue
runs cancelled by daily caps should release their issue execution locks
and promote deferred wakeups without entering immediate recovery loops.
Generic timer no-work skipping should be opt-in so proactive agents
continue to run by default.
### Steps to reproduce
1. Configure an agent heartbeat policy with a one-run daily cap or a
daily cost cap.
2. Create or queue heartbeat wakeups for that agent after the cap has
already been consumed.
3. Observe that without preflight and claim-time checks, the heartbeat
path can still enqueue or claim work that should be blocked before
adapter execution.
### Paperclip version or commit
Reproduced against `master` before this branch.
### Deployment mode
Local dev (`pnpm dev`) / built from source.
### Installation method
Built from source (`pnpm dev` / `pnpm build`).
### Agent adapter(s) involved
Not adapter-specific (core heartbeat scheduling and claim logic).
### Database mode
External Postgres in tests via embedded test harness.
### Access context
Not applicable.
### Node.js version
Node 20 in CI-compatible local development.
### Operating system
macOS local development, Linux CI-compatible tests.
### Relevant logs or output
The regression suite added in this PR covers the failing paths:
```shell
pnpm exec vitest run server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts
```
### Relevant config (if applicable)
```json
{
"heartbeat": {
"maxDailyRuns": 1,
"maxDailyCostCents": 1,
"skipTimerWhenNoActionableWork": true
}
}
```
### Additional context
This affects recurring/autonomous operation because the safest place to
stop excess work is before adapter execution starts.
### Privacy checklist
Reviewed for sensitive data; no private logs, credentials, or local
instance URLs are included.
## What Changed
- Added heartbeat policy parsing for per-agent daily run caps, daily
cost caps, and opt-in no-actionable-work timer skipping.
- Added pre-queue daily cap checks while preserving same-issue wake
coalescing.
- Added claim-time cap checks so already queued runs are cancelled
before adapter execution when a cap is reached.
- Added skipped wakeup metadata for cap and timer fast-exit decisions.
- Released issue execution locks for queued issue runs cancelled by
daily caps, with deferred wake promotion and without immediate recovery
loops while caps are active.
- Added regression coverage for timer skipping, proactive default
behavior, run caps, cost caps, queued-run cancellation, started
cancelled runs, and deferred issue wake promotion.
## Verification
- `git diff --check`
- `node -c server/src/services/heartbeat.ts`
- `pnpm exec vitest run
server/src/__tests__/heartbeat-stale-queue-invalidation.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- Local autoreview: `skills/autoreview/scripts/autoreview --mode branch
--base origin/master --engine codex --model gpt-5.5 --thinking high`
- Result: clean, no accepted/actionable findings
## Risks
- Medium operational risk because this changes heartbeat scheduling and
claim-time behavior.
- The no-actionable-work timer fast-exit is explicitly opt-in to avoid
suppressing proactive agents unexpectedly.
- Daily run caps count runs by `startedAt` so old queued rows do not
consume today’s cap, while started runs still count even if they later
end as cancelled.
- Queued issue-run cap cancellation uses the existing release/promotion
path with immediate recovery suppressed to avoid retry loops while caps
are active.
## Model Used
Codex with GPT-5.5 high reasoning assisted with implementation, local
testing, and autoreview. The final review gate used local autoreview
with `gpt-5.5` high reasoning.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [ ] 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] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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
|
||
|
|
277a9a43d6 |
fix(recovery): convert review-parked continuations into dependency waits (#8371)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The productivity-recovery subsystem watches for "stranded" assigned issues — claims whose live run disappeared — and repairs, resumes, or visibly blocks them > - When an executor decomposes an umbrella issue into sub-tasks, it parks its own continuation as "waiting on review/approval" (error code `issue_continuation_waiting_on_review`) — a deliberate pause, not a lost run > - Recovery's staleness gate mistook that deliberate park for a disappeared run: it retried once, then escalated the issue to `blocked` with a recovery action and an operator-facing failure notice — even though nothing had failed and there was nothing for a human to do > - The user is left staring at an inscrutable, over-technical "stranded" error on a task they did nothing wrong with, with no idea what action to take > - This pull request teaches recovery to recognize a review-parked continuation and, when the issue has a real waiting target (open sub-tasks or unresolved blockers), convert it into a first-class dependency wait: `blocked`-by-children, original assignee kept, plus a plain-language comment saying it will resume automatically > - The benefit is that post-decomposition umbrellas sit on a real waiting path and self-resume through the normal blockers-resolved flow, while genuine strands (no waiting target) still escalate exactly as before ## Linked Issues or Issue Description Refs #6503 ## What Changed - `server/src/services/recovery/service.ts`: add `resolveContinuationWaitingOnReview`. When a continuation was cancelled with `issue_continuation_waiting_on_review` and the issue has a real waiting target — open (non-terminal) sub-tasks or existing unresolved blockers — recovery sets the issue `blocked` by those issues, keeps the original assignee, posts a plain-language `system` comment, and logs the activity. Wired into `reconcileStrandedAssignedIssues` ahead of the escalation path, with a new `waitingOnReviewResolved` counter on the result. - With no waiting target, the code falls through to the existing escalation, preserving genuine stranded-run detection. - `server/src/__tests__/heartbeat-process-recovery.test.ts`: two new tests — (1) a review-parked continuation converts into a dependency wait on its open sub-tasks (done children excluded, no recovery issue opened, plain-language comment, raw error code never leaks), and (2) it still escalates when no open dependency remains. - `doc/execution-semantics.md`: document the "Deliberate wait is not a lost run" recovery rule and the requirement that a post-decomposition umbrella hold a first-class waiting path rather than relying on `parentId` rollup. ## Verification - `cd server && npx tsc --noEmit` — passes against current `master`. - New tests in `server/src/__tests__/heartbeat-process-recovery.test.ts` (describe: "heartbeat orphaned process recovery"): - "converts a continuation parked for review into a dependency wait on its open sub-tasks" - "still escalates a continuation parked for review when no open dependency remains" - Run with the repo's vitest setup, e.g. `pnpm vitest run server/src/__tests__/heartbeat-process-recovery.test.ts` (requires the embedded-postgres test harness). ## Risks Low. The change adds a single guarded pre-check ahead of the existing escalation path; behavior is unchanged when the cancellation error code is not `issue_continuation_waiting_on_review` or when the issue has no open sub-task / unresolved blocker to wait on. No schema or migration changes. ## Model Used Claude (Anthropic), Opus-class model, via the Claude Code agent harness — extended thinking and tool use 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 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 - [ ] If this change affects the UI, I have included before/after screenshots (N/A — server-only) - [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 (pending CI) - [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 |
||
|
|
fb0e3fb02a |
Fix mention-granted closed issue comments with resume intent (#8350)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Issue comments are part of the control plane boundary between agent collaboration and task mutation. > - Mention grants intentionally let a mentioned peer agent answer on an issue thread without taking ownership of the task. > - Closed issue comments have a second mutation guard because comments can also request resume or reopen behavior. > - A mention-granted comment should stay append-only unless the actor also has mutation authority. > - This pull request preserves the narrow comment path while keeping explicit `resume` and `reopen` intent behind mutation authorization. > - The benefit is a smaller authorization exception with regression coverage for both allowed and denied paths. ## Linked Issues or Issue Description Refs #2884 Related prior authorization work: #8024, #7863, #6113, #7998. Bug fix description: - What happened: a mention-granted non-assignee agent could be treated as authorized for the closed issue comment route without preserving a clean distinction between append-only comments and explicit reopen/resume mutation intent. - Expected behavior: a mention grant allows a plain comment on a closed issue, but `resume: true` or `reopen: true` still requires mutation authorization. - Steps to reproduce: create a closed issue assigned to one agent, give a different agent a valid mention-scoped comment grant, then POST a comment as that agent with and without `resume`/`reopen` intent. - Deployment mode: server route behavior; covered by focused Vitest regression tests. ## What Changed - Preserve the `issue:comment` authorization decision in `POST /api/issues/:id/comments` so the route can identify legitimate mention-grant decisions. - Skip the closed-issue non-assignee mutation fallback only for inert mention-granted comments. - Continue requiring mutation authorization when a mention-granted closed issue comment includes explicit `resume` or `reopen` intent. - Add regression coverage for the allowed inert comment and denied resume/reopen cases. ## Verification - `pnpm vitest run server/src/__tests__/issue-comment-reopen-routes.test.ts` passed locally: 72 tests. ## Risks - Low risk: scoped to the issue comment route and tests for a specific authorization decision reason. - Residual risk: CI should run the full PR suite. ## Model Used OpenAI GPT-5 Codex via Paperclip Git Expert agent, with tool use for code inspection, test execution, Git, and GitHub operations. ## 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] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
67f97e8fb0 |
fix(server): enforce read auth for single issue comments (#8346)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Issue comments are part of the control-plane audit trail and must respect the same company and issue authorization boundaries as issue reads. > - Mention-scoped commenting gives low-trust agents a narrow way to reply when an authorized assignee mentions them. > - The comment list route already enforces issue-read authorization, but the single-comment read route only checked same-company access before returning a known comment id. > - That created a broken object-level authorization gap for same-company low-trust agents outside the issue boundary. > - This pull request applies the existing issue-read guard to the single-comment route before loading the comment. > - The benefit is consistent comment-read authorization across list and single-comment endpoints, with regression coverage for the low-trust boundary. ## Linked Issues or Issue Description Refs #7389 Bug fix context: - What happened: `GET /api/issues/:id/comments/:commentId` checked company access but did not enforce the issue-read authorization boundary before returning a single comment by known id. - Expected behavior: single-comment reads should use the same issue-read boundary as issue thread list reads. - Steps to reproduce: authenticate as a same-company low-trust agent outside an issue's readable boundary, then request a known comment id via the single-comment endpoint. - Deployment mode: applies to server authorization behavior in authenticated agent API usage. ## What Changed - Added `assertIssueReadAllowed` to the single issue-comment read route before `getComment` is called. - Added mocked route coverage proving peer agents outside the issue-read boundary get `403` and the comment is not loaded. - Added authorization and embedded route coverage for mention-scoped low-trust comment grants so the intended narrow reply path remains allowed. ## Verification - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts` — passed, 60 tests. - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/authorization-service.test.ts` — passed, 26 tests. - `NODE_ENV=test pnpm exec vitest run server/src/__tests__/low-trust-red-team-routes.test.ts` — passed, 8 tests. - `git diff --check` — passed. ## Risks Low risk. This reuses the existing issue-read guard for a read endpoint. The main behavioral shift is that same-company actors who cannot read an issue can no longer fetch a known comment id from that issue, which is the intended authorization boundary. > 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 via Codex, with repository tool use and command execution. Runtime context-window details were not exposed by the environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [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] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
364f0f5a8d |
fix(server): enforce issue read for issue thread lists (#8331)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agents coordinate through issue threads, so issue comments and interactions are part of the task authorization surface. > - Low-trust and boundary-limited agents can receive narrow mention-scoped access, but that must not turn into broad same-company issue-thread reads. > - The comment creation path was narrowed to allow explicit mention replies without granting mutation access. > - The surrounding list/read routes still needed to enforce the same `issue:read` boundary before returning thread data. > - This pull request applies the issue read check to issue comment and interaction listing routes, and locks that behavior with server regressions. > - The benefit is that narrow cross-agent collaboration remains possible without exposing unrelated issue-thread history. ## Linked Issues or Issue Description Bug fix: - What happened: same-company agents outside an issue read boundary could still hit issue-thread listing routes and receive thread data. - Expected behavior: issue comments and issue-thread interactions should only be listed after the actor is allowed to read the issue. - Steps to reproduce: configure a peer agent denied by the issue read boundary, then request `GET /api/issues/:id/comments` or the issue interaction listing route. - Paperclip version/commit: current `master` before this branch. - Deployment mode: applies to server authorization in all modes. Related public context: #7389, #7863, #8024. ## What Changed - Added issue read enforcement before listing issue comments. - Added issue read enforcement before listing issue-thread interactions. - Added server regressions for denied peer-agent issue-thread access while preserving mention-scoped collaboration behavior. - Removed an avoidable per-mentioned-comment issue reload in mention-grant authorization by passing the already-loaded issue assignee through the helper. - Documented cross-agent issue read/comment authorization behavior in the Paperclip API reference. - Added a resilient fallback for pinned external skills when GitHub tree fetches are temporarily unavailable during catalog builds. ## Verification - `pnpm vitest run server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts server/src/__tests__/authorization-service.test.ts` - 2 test files passed - 84 tests passed - Existing mocked recovery revalidation warnings were emitted by the route suite and the command exited 0 - Greptile: 5/5 on commit `b73fc323f192dc44f88374c16865008d4348923b`; no unresolved review threads. - `pnpm vitest run packages/skills-catalog/src/catalog-builder.test.ts` - 1 test file passed - 6 tests passed - CI: all visible PR checks are terminal green on commit `b73fc323f192dc44f88374c16865008d4348923b`. ## Risks Low risk. This tightens read authorization on issue-thread listing routes; any caller that depended on same-company access without `issue:read` will now receive 403 and must use an explicit grant or valid issue read path. ## Model Used OpenAI GPT-5 Codex, Codex coding agent environment, tool use and local command execution enabled, reasoning mode active. Context window not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
a71c4b6782 |
[codex] feat(watchdog): add task watchdog control plane (#8339)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The task lifecycle and recovery subsystems decide when agent work is still productive, stalled, or ready for review. > - Existing recovery paths can observe stopped or incomplete work, but there was no first-class per-task watchdog model with scoped review permissions. > - Watchdog follow-ups also need strict boundaries so recovery/status-only runs cannot mutate approvals or perform deliverable work. > - This pull request adds the task watchdog data model, API/service layer, scheduler/review flow, adapter wake context, UI configuration surfaces, and docs. > - The branch has been rebased onto current `paperclipai/paperclip` `master`; the watchdog migration is now ordered after master's latest migrations as `0104_issue_watchdogs`. > - The benefit is a more explicit task-review loop that preserves Paperclip's single-assignee and governance invariants while making stalled work easier to route. ## Linked Issues or Issue Description No linked GitHub issue. Paperclip task: [PAP-11275](/PAP/issues/PAP-11275). ## Problem or motivation Task recovery needs a first-class watchdog path that can inspect stopped work and create scoped follow-ups without bypassing normal task ownership. Board/UI users need a way to configure watchdogs on tasks and see watchdog-related live work. Recovery/status-only runs must remain limited to status reporting and must not create approvals, link approvals, or submit approval comments. ## Proposed solution Add a task-watchdog data model, scheduler/classifier, scoped mutation guard, adapter wake context, API/UI configuration surfaces, and documentation so watchdog agents can review stopped task subtrees under explicit boundaries. ## Alternatives considered Reuse the existing recovery-action flow only. That would keep stopped-work detection implicit, make per-task watchdog assignment harder to expose in the UI, and would not provide a durable scoped-review issue for stalled task trees. ## Roadmap alignment This is Paperclip control-plane lifecycle infrastructure for task execution and recovery. I checked `ROADMAP.md`; this PR does not duplicate an existing planned core item. ## What Changed - Added issue watchdog schema, migration, shared contracts, validators, CRUD API, and service support. - Added task watchdog scheduler/classifier behavior, scoped mutation enforcement, adapter wake context, and default watchdog mandate guidance. - Added UI surfaces for configuring watchdogs on new/existing tasks, viewing watchdog activity, and exposing the experimental setting. - Added docs for the user-facing task watchdog workflow and implementation semantics. - Gated new-task watchdog setup behind `enableTaskWatchdogs` and blocked cheap status-only recovery runs from approval mutations. - Rebased onto current `master` and renumbered the idempotent watchdog migration from the branch-local `0102_issue_watchdogs` slot to `0104_issue_watchdogs`. - Addressed Greptile feedback by loading watchdog classifier input with a recursive subtree query and centralizing the watchdog origin-kind constant. - Added and updated focused server/UI tests for watchdog routes, scheduler/classifier behavior, scope boundaries, live task visibility, settings, and new issue dialog behavior. ## Verification - `pnpm vitest run server/src/__tests__/task-watchdogs-scheduler.test.ts server/src/__tests__/task-watchdogs-classifier.test.ts` - `pnpm vitest run server/src/__tests__/approval-routes-idempotency.test.ts server/src/__tests__/issue-agent-mutation-ownership-routes.test.ts` - `pnpm vitest run ui/src/components/NewIssueDialog.test.tsx` - `pnpm --filter @paperclipai/server typecheck` - `git diff --check` - Verified the PR diff does not include `pnpm-lock.yaml` or `.github/workflows`. ## Risks - Medium risk: this introduces a new task lifecycle surface touching DB schema, server routes/services, adapter wake context, and UI task configuration. - Watchdog scheduling behavior depends on the new experimental setting and runtime context checks behaving consistently across local and production agents. - The watchdog migration is idempotent (`IF NOT EXISTS` / duplicate-object guards) so users who tried the previous branch-local migration number should not get duplicate-object failures. - CI and the second Greptile pass are pending after the latest review-fix push. > 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-class coding agent in the Paperclip workspace. Exact runtime model id and context window were not exposed to the agent; tool use and local command 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots — N/A per Paperclip task instruction: do not add screenshots/images to this PR unless they are specifically part of the work. - [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> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6a3f5b685d |
fix(agents): clear inbox hire approval when approving/terminating from detail page (#8340)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Hiring a new agent creates a `hire_agent` approval record; until it is resolved, the agent sits in `pending_approval` and the open approval surfaces an "Approve/Reject" card in the inbox > - There are two places to act on that hire: the inbox approval card and the agent detail page's Approve/Terminate buttons > - The agent detail page only flipped the agent to `idle` via `activatePendingApproval`, never resolving the linked approval record > - So after approving (or terminating) from the detail page, the approval stayed `pending` and the inbox kept showing a stale "Approve/Reject" card for an agent that was already decided > - This pull request routes the detail-page approve through the shared `approvalsSvc.approve()` (which resolves the approval and runs activation, budget policy, and the hire-approved notification), and rejects the linked approval when a still-pending agent is terminated > - The benefit is a single source of truth: deciding a hire in one place clears it everywhere, so the inbox no longer asks you to approve an agent you already approved ## Linked Issues or Issue Description No public GitHub issue exists for this; describing in-PR (bug report). **What happened:** Create a new agent, then approve it from the agent detail page. The agent activates, but the inbox still shows a "Hire Agent" item with Approve/Reject buttons for it. **Expected:** Once a hire is approved or rejected anywhere in the UI, it should be resolved everywhere — the inbox should not re-ask you to approve an agent that is already decided. **Root cause:** `POST /agents/:id/approve` called `activatePendingApproval`, which only changes the agent's status. The linked `hire_agent` approval row stayed `pending`. The inbox lists approvals filtered to unresolved statuses, so the card persisted. Terminating a pending agent from the detail page had the mirror problem for the "reject" half. Related (not duplicates): #215 (join-request inbox badge), #1815 (approval detail button loading text). ## What Changed - Added `approvalService.findOpenHireApprovalForAgent(companyId, agentId)` to locate the open `hire_agent` approval for an agent. The company/type/open-status **and** `payload->>'agentId'` predicates all run in SQL (jsonb operator), so the DB returns only the relevant row instead of filtering in JS (`server/src/services/approvals.ts`). - `POST /agents/:id/approve` resolves the linked approval through the shared `approvalsSvc.approve()` — running activation, budget-policy upsert, and the hire-approved notification as one path — and falls back to direct `activatePendingApproval` only when no open approval exists (legacy agents created before approvals were tracked) (`server/src/routes/agents.ts`). - `POST /agents/:id/terminate` now branches the same way: when a still-`pending_approval` agent has an open hire approval, it delegates to `approvalsSvc.reject()` (which resolves the approval **and** terminates the agent internally) and re-reads the agent, otherwise it terminates directly. This avoids terminating the agent twice (`reject()` already calls `agentsSvc.terminate()`) (`server/src/routes/agents.ts`). - The `agent.approved` activity log records the resolved `approvalId` (or `null` on the fallback path) for traceability. ## Verification - `pnpm --filter @paperclipai/server typecheck` — clean. - Targeted server tests pass (57 tests): `npx vitest run src/__tests__/approvals-service.test.ts src/__tests__/agent-permissions-routes.test.ts` - `findOpenHireApprovalForAgent` returns the row the SQL filter yields / returns null when none matches. - Approving from the detail page resolves the linked approval via `approvalsSvc.approve()` and does not double-activate; legacy fallback still calls `activatePendingApproval`. - Terminating a still-pending agent with an open approval calls `approvalsSvc.reject()` and does **not** call `agentsSvc.terminate()` a second time; terminating with no open approval terminates directly. - Manual: create an agent → inbox shows the hire card → approve from the agent detail page → inbox card is gone and the agent is active. Same for terminate-while-pending clearing the card. ## Risks Low risk, server-only, no schema or migration changes. The fallback to `activatePendingApproval` preserves existing behavior for agents with no tracked approval record, so legacy agents still activate. The shared approval path is the same one the inbox card already uses, so approve/terminate-from-detail-page now match approve/reject-from-inbox exactly. ## Model Used Claude Opus 4.8 (claude-opus-4-8), extended thinking with tool use, via Claude Code. ## 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] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots (server-only change, no UI diff) - [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 (in progress) - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
7069053a1f |
[codex] Add ask issue work mode (#8334)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Issue work mode controls how a task starts and how the conversation composer frames the operator's intent. > - Paperclip already supports standard agent execution and planning mode, but there is no lightweight mode for asking a question without immediately implying execution or plan drafting. > - That gap makes low-commitment clarification workflows look like normal task execution. > - This pull request adds an explicit Ask mode and threads it through shared contracts, server heartbeat context, and the issue composer UI. > - The benefit is that operators can create or switch a task into a question-oriented mode while preserving existing agent and planning flows. ## Linked Issues or Issue Description No public GitHub issue exists for this change. Inline feature request follows the repository feature request template. ### Subsystem affected Cross-cutting: `packages/shared`, `server/`, and `ui/`. ### Problem or motivation Issue conversations currently distinguish standard agent work from planning work, but question-first conversations do not have a clear public mode in the shared contract or UI. Operators who want to ask an agent a focused question have to use standard mode, which can imply normal task execution, or planning mode, which asks for a plan rather than an answer. ### Proposed solution Add Ask as a first-class issue work mode. It should be selectable from issue creation and issue chat, cycle alongside Standard and Planning from the keyboard shortcut/menu, appear distinctly in composer styling, and be included in heartbeat context so agents know to answer directly instead of executing or drafting a plan. ### Alternatives considered - Keep using standard mode for questions: rejected because it does not communicate answer-only intent to the agent or the UI. - Reuse planning mode for questions: rejected because planning mode asks for a plan and is semantically different from asking a question. - Add only local UI copy: rejected because the mode needs to be represented in the shared contract and server heartbeat context to be reliable. ### Roadmap alignment This is a focused issue-workflow improvement. `ROADMAP.md` was checked and no duplicate planned core work was found. ### Additional context Related public searches performed before opening this PR: - GitHub PR search for `"ask mode" repo:paperclipai/paperclip` - GitHub issue search for `"ask mode" repo:paperclipai/paperclip` - GitHub PR search for `"work mode" "ask" repo:paperclipai/paperclip` No duplicate PR was found. ## What Changed - Added `ask` to the shared issue work-mode contract and validation coverage. - Included issue work mode in heartbeat context summaries so agents can see standard, planning, and ask state. - Added Ask mode metadata, styling, composer tone handling, and selection/cycling behavior in the issue chat/new issue UI. - Updated focused tests for shared validators, heartbeat context, and affected UI work-mode flows. ## Verification - `NODE_ENV=test pnpm exec vitest run ui/src/components/ChatComposer.test.tsx ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/lib/work-mode-meta.test.ts` - `NODE_ENV=test pnpm exec vitest run packages/shared/src/validators/issue.test.ts server/src/__tests__/heartbeat-context-summary.test.ts server/src/__tests__/issues-service.test.ts ui/src/components/ChatComposer.test.tsx ui/src/components/IssueChatThread.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/lib/work-mode-meta.test.ts ui/src/pages/IssueDetail.test.tsx` The broader targeted command passed 8 test files / 245 tests. Visual reference for Standard/Planning/Ask composer states: https://gist.github.com/cryppadotta/714d8590bac55500a65e7e16de5bb4b8 It emitted an expected warning from an existing server test fixture about a missing run-log fixture while verifying derived issue comment metadata. ## Risks Low to moderate risk. This adds a new enum value that crosses shared, server, and UI contracts. Existing standard and planning modes are preserved, but any downstream code assuming only two non-terminal work modes may need to handle `ask`. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI GPT-5 Codex coding agent in Paperclip CodexCoder mode, with shell, git, GitHub connector, and local test execution tools. Context window and exact hosted model snapshot are 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) - [ ] My branch name describes the change (e.g. `docs/...`, `fix/...`, `feat/...`) 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] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
aeea5f9195 |
fix(ui): stabilize routine schedule editor and interrupted run labels (#8333)
## Thinking Path > - Paperclip is the open source control plane people use to manage AI agents for work. > - This change touches the board UI surfaces for issue run timelines and routine schedule editing. > - Operators need cancelled runs to distinguish ordinary cancellation from human interruption, otherwise the run history reads as more severe than it is. > - Routine schedule editing also needs to preserve user-entered cron values while rendering common schedules in a stable, understandable editor. > - This pull request keeps the editor state tied to explicit schedule values, adds coverage for routine editable sections, and makes interrupted run copy more precise. > - The benefit is less surprising routine editing and clearer issue run history for operators. ## Linked Issues or Issue Description No public GitHub issue is filed for this exact branch. Related public PRs: - Refs #3581, which addresses a narrower schedule reset case. - Refs #1803, which is another open schedule editor UI improvement. Problem description: Routine trigger schedules can be edited through the board UI, but the previous schedule editor path could normalize or reset cron state in ways that made unsaved edits fragile. Issue run history also labeled operator-interrupted cancelled runs like ordinary cancellations. Reviewers should treat this PR as a combined UI stabilization pass for those two visible operator workflows. ## What Changed - Added a more stable routine schedule editor flow that preserves explicit cron values and handles custom/common schedule transitions. - Wired routine editable-section state so schedule drafts do not get overwritten by unrelated section refreshes. - Added tests for schedule editor behavior, routine editable sections, and routine service schedule preservation. - Updated issue run timeline copy so operator-interrupted cancelled runs display as interrupted, while ordinary cancelled runs remain cancelled. - Kept the classic issue thread run label behavior aligned with the current issue thread surface. ## Verification - `NODE_ENV=development pnpm run preflight:workspace-links && NODE_ENV=development pnpm exec vitest run server/src/__tests__/routines-service.test.ts ui/src/components/IssueChatThread.test.tsx ui/src/components/ScheduleEditor.test.tsx ui/src/components/routine-sections/editable-sections.test.tsx` — 103 tests passed. Note: direct `pnpm exec vitest ...` without `NODE_ENV=development` loaded a React build where `React.act` is undefined in this workspace. The same targeted tests pass under the development React build. ## Risks Low to medium risk. The changes are UI-focused but touch routine schedule editing, which is a high-frequency operator workflow. The main risk is that an uncommon cron expression could render as custom when a user expected a preset; the added tests cover preservation and explicit custom handling. > 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-class coding agent. Exact hosted runtime model ID and context window were not exposed in this session. Tool use and local command execution were used for inspection, verification, GitHub PR creation, and Paperclip issue updates. ## 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] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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> |
||
|
|
f13fd1157b |
feat(adapters): stamp agent id via X-Anthropic-Agent-Id for claude_local (#8322)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Local agents run through the `claude_local` adapter, which spawns Claude Code and routes its Anthropic API traffic through a shared proxy (e.g. better-ccflare). > - That proxy's request log feeds observability dashboards that break down cost and token usage. > - But requests from local agents arrive without an agent identifier, so all traffic collapses into a single unattributed bucket and per-agent telemetry is impossible. > - Anthropic's CLI forwards `ANTHROPIC_CUSTOM_HEADERS` onto each API request, and better-ccflare now reads an `X-Anthropic-Agent-Id` header to attribute requests per agent. > - This pull request stamps the agent's id into `ANTHROPIC_CUSTOM_HEADERS` as `X-Anthropic-Agent-Id`, injected into the env the adapter actually forwards to the spawned process. > - The benefit is per-agent cost/token attribution in proxy-backed dashboards, with zero impact on agents that don't run behind such a proxy. ## Linked Issues or Issue Description No public GitHub issue exists; describing inline per CONTRIBUTING.md (feature template). **Problem or motivation** When several `claude_local` agents share a proxy (better-ccflare) in front of the Anthropic API, the proxy cannot tell which agent issued a given request. Per-agent cost and token dashboards therefore can't be built — every request is attributed to one undifferentiated bucket. **Proposed solution** Have the `claude_local` adapter stamp each spawned Claude Code process with `ANTHROPIC_CUSTOM_HEADERS: X-Anthropic-Agent-Id: <agentId>`. The Anthropic CLI forwards that header on every API call, so the proxy can attribute requests to the specific agent. **Alternatives considered** Parsing per-agent identity from workspace paths or session ids in the proxy — brittle and proxy-specific. A first-class request header is the stable contract; it pairs with better-ccflare's `X-Anthropic-Agent-Id` support ([tombii/better-ccflare#260](https://github.com/tombii/better-ccflare/pull/260)) and dashboards like [danieltamas/axon](https://github.com/danieltamas/axon). **Roadmap alignment** Additive observability glue for an existing adapter; no overlap with planned core work. ## What Changed - Added `server/src/adapters/claude-agent-id-header.ts` exporting `stampClaudeAgentIdHeader`, which wraps the `claude_local` execute and merges `X-Anthropic-Agent-Id: <agentId>` into the run's `config.env.ANTHROPIC_CUSTOM_HEADERS`. - `server/src/adapters/registry.ts`: the `claude_local` adapter now uses the wrapped execute (`stampClaudeAgentIdHeader(claudeExecute)`). - The header is merged into **`config.env`** — the env the Claude adapter actually forwards into the spawned process — rather than `agent.adapterConfig.env`, which is resolved upstream before `execute` runs and is never read by the Claude adapter. - `agentId` is sanitized (CR/LF stripped, capped at 256 chars) before interpolation to prevent HTTP header injection. - Passthrough when no agent id is available; a pre-existing `X-Anthropic-Agent-Id` (manual override) is respected and not duplicated. - Added `server/src/adapters/claude-agent-id-header.test.ts` covering injection into `config.env`, append-to-existing `ANTHROPIC_CUSTOM_HEADERS`, CR/LF sanitization, length bounding, no-agent-id passthrough, and the duplicate-header guard. ## Verification - Unit tests: `cd server && npx vitest run src/adapters/claude-agent-id-header.test.ts` → 6 passing. - CI: typecheck, build, server suites, and Greptile gates run on this PR. - Manual: configure a `claude_local` agent behind better-ccflare, run a heartbeat, and confirm the proxy log shows `X-Anthropic-Agent-Id: <agentId>` on that agent's requests. An agent that already sets `X-Anthropic-Agent-Id` in its adapter config keeps its override (no duplicate line). ## Risks Low risk. The change is additive and non-breaking: - When no agent id is present, or when an `X-Anthropic-Agent-Id` is already configured, execution is byte-for-byte unchanged (the original `ctx` is passed straight through). - The header only has an effect for deployments whose proxy reads it; agents without such a proxy are unaffected. - The agent id is sanitized (CR/LF removed, length-bounded) before it is interpolated into a header value, preventing header injection. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. This is additive observability glue for an existing adapter and does not overlap planned core work. ## Model Used Claude (Anthropic) — Claude Opus 4.8 (`claude-opus-4-8`), via the Claude Code CLI with extended reasoning and tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots (N/A — no UI 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: zenprocess <zenprocess@users.noreply.github.com> Co-authored-by: Devin Foley <devin@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
5e086cb828 |
fix(server): resolve published skills catalog package root and fallback (#8327)
## Thinking Path > - Paperclip is the open source control plane people use to run and supervise AI-agent companies. > - The skills system is part of that core operator experience because agents and humans both depend on the catalog-backed Skills Manager surfaces. > - In source checkouts, the server can find the catalog manifest and bundled skill files through monorepo-relative paths, but published installs do not preserve that layout. > - That mismatch makes `GET /api/skills/catalog` fail in npm/pnpm installs even though the catalog package itself is present. > - The server therefore needs to resolve the catalog from the published `@paperclipai/skills-catalog` package first, while still keeping a monorepo fallback for local development. > - This pull request makes the published package the primary resolution path, uses the same resolved package root for bundled skill file reads, and degrades the list route safely when the manifest is unavailable. > - The benefit is that Skills Manager catalog reads behave correctly in packaged installs instead of only in repo-local development layouts. ## Linked Issues or Issue Description Fixes #8316 Refs #7281 Refs #7313 Refs #7350 Refs #7860 Refs #8223 Refs #8227 ## What Changed - Added `@paperclipai/skills-catalog` as a runtime dependency of `@paperclipai/server`. - Exported `./package.json` from `@paperclipai/skills-catalog` so the server can resolve the published package root directly. - Updated `server/src/services/skills-catalog.ts` to resolve the manifest and package root from the published package first, with the monorepo path retained only as a development fallback. - Applied that resolved package root to bundled catalog file reads so manifest lookup and skill-file reads use the same published layout. - Added `listCatalogSkillsOrEmpty()` so `GET /api/skills/catalog` returns `[]` and logs a warning when the manifest is unavailable instead of surfacing a 500. - Added targeted server tests for published-package resolution and missing-manifest fallback handling. ## Verification - `pnpm --filter @paperclipai/server exec vitest run src/__tests__/skills-catalog-service.test.ts src/__tests__/company-skills-routes.test.ts` - `pnpm --filter @paperclipai/server build` - Packaging smoke: - pack `@paperclipai/shared` and `@paperclipai/skills-catalog` from this checkout - mount those packed artifacts under `server/dist/node_modules` - import `server/dist/services/skills-catalog.js` - verify a bundled catalog `SKILL.md` resolves and reads successfully from the packed package layout ## Risks - Low risk: the change is narrowly scoped to catalog package resolution and fallback behavior. - The new `./package.json` export slightly broadens the catalog package's public surface, so reviewers should confirm that is an acceptable runtime contract. - The empty-array fallback intentionally changes failure mode for a missing manifest from `500` to a warning + empty payload, which is safer for packaged installs but could hide packaging regressions if logs are not monitored. ## Model Used - OpenAI Codex via Paperclip `codex_local` (GPT-5-based coding agent; exact backend model ID/context window not exposed in this harness), with tool use, shell execution, git, and local test/build 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] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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 |
||
|
|
0186e66c7c |
test(SAG-4328): de-flake checkout-lock race in orphan-recovery test (#8315)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The server heartbeat subsystem tracks agent runs and recovers orphaned processes via `reapOrphanedRuns` > - When a local process dies mid-run, the recovery path queues a retry run and releases the checkout lock asynchronously > - The test `queues exactly one retry when the recorded local pid is dead` verifies both the retry state and that the checkout lock is released > - The `checkoutRunId` null-check was a bare synchronous assertion, but the checkout-lock release is async — so the test could read `checkoutRunId` before the write committed > - This PR wraps the predicate already gating on `executionRunId` to also wait for `checkoutRunId === null`, so both writes are committed before the assertions fire > - The benefit is a deterministic test that does not race the async checkout-lock release ## Linked Issues or Issue Description - ## What Changed - `server/src/__tests__/heartbeat-process-recovery.test.ts`: Extended the `waitForValue` predicate (line ~1024) from `executionRunId === retryRun?.id` to also require `checkoutRunId === null` before returning the row. This eliminates the race between the assertion and the async terminal-run checkout-lock release. ## Verification - No production code changed — test file only. - Ran the test file 10× locally with `pnpm exec vitest run server/src/__tests__/heartbeat-process-recovery.test.ts --no-file-parallelism --maxWorkers=1`: ``` Run 1: Test Files 1 passed (1) | Tests 57 passed (57) Run 2: Test Files 1 passed (1) | Tests 57 passed (57) Run 3: Test Files 1 passed (1) | Tests 57 passed (57) Run 4: Test Files 1 passed (1) | Tests 57 passed (57) Run 5: Test Files 1 passed (1) | Tests 57 passed (57) Run 6: Test Files 1 passed (1) | Tests 57 passed (57) Run 7: Test Files 1 passed (1) | Tests 57 passed (57) Run 8: Test Files 1 passed (1) | Tests 57 passed (57) Run 9: Test Files 1 passed (1) | Tests 57 passed (57) Run 10: Test Files 1 passed (1) | Tests 57 passed (57) ``` 10/10 green streak — race eliminated. ## Risks Low risk — test-only change. No production code modified. The predicate change only narrows the waitForValue poll to require both writes committed before asserting, matching the intent already documented in the comment on line 1031. > 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 Claude Sonnet 4.6 (claude-sonnet-4-6) — Anthropic, 200K context, tool use 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] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] 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: Director of Engineering <cto@paperclip.ing> Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Devin Foley <devin@paperclip.ing> |
||
|
|
f672a9e2e5 |
fix(runtime): keep agent pause durable at execution-start (#8317)
**Issue (described inline; no existing tracking issue):** Pausing an
agent is not durable. Pausing cancels the in-flight run, but a queued or
recovery-dispatched run can clobber the agent back to `running` because
the execution-start status update is unconditional — so a "paused" agent
silently resumes work while `paused_at` is still set.
## Thinking Path
> - Paperclip orchestrates AI agents for zero-human companies; agent
work executes as "runs" tracked in `heartbeat_runs`, with a
recovery/automation layer that re-dispatches work when a run disappears.
> - The agent lifecycle has a pause control (status `paused`,
`paused_at` set) meant to stop an agent from taking or continuing work.
> - The problem: pause is not durable. Pausing cancels the in-flight
run, but the execution-start path then sets `agents.status = 'running'`
with an unconditional `UPDATE ... WHERE id = ?`, so any queued or
recovery-dispatched run can clobber the paused agent back to `running`
and execute.
> - Why it matters: a "paused" agent silently resuming undermines the
core operational control operators rely on to halt runaway,
cost-sensitive, or unsafe work.
> - This pull request guards the execution-start status flip with an
atomic conditional UPDATE, and tags pause-cancellations for
observability without changing resume behaviour.
> - The benefit is that a paused agent can no longer transition back to
`running`; queued/recovery-dispatched runs are cancelled cleanly instead
of clobbering status, while un-pausing still resumes in-flight work.
## What Changed
- Execution-start guard: replaced the unconditional `UPDATE agents SET
status='running' WHERE id = ?` with an atomic conditional `UPDATE ...
WHERE id = ? AND status NOT IN
('paused','terminated','pending_approval')`. On a zero-row match the run
is cancelled (`errorCode: "agent_not_invokable"`), the issue execution
lock is released, and the path returns — instead of clobbering status.
- Exported `DIRECT_NON_INVOKABLE_STATUSES` from `agent-invokability.ts`
and reused it in `heartbeat.ts` as the single source of truth for the
guard.
- Pause observability: `cancelActiveForAgentInternal` now accepts an
`errorCode` (default `"cancelled"`); the pause-route wrapper
`cancelActiveForAgent` passes `"agent_paused"`. This is
classification-neutral — `agent_paused` is NOT added to
`NON_RETRYABLE_CONTINUATION_ERROR_CODES`, so on un-pause the issue's
continuation re-enqueues and work resumes.
- Exported `classifyContinuationFailure` from `recovery/service.ts` for
unit testing (no logic change).
- Added `server/src/services/recovery/service.pause-durability.test.ts`
covering continuation classification.
## Verification
- `pnpm --filter @paperclipai/server typecheck` — clean.
- `pnpm exec vitest run
server/src/services/recovery/service.pause-durability.test.ts` — 5
passed.
- `pnpm exec vitest run server` — full server suite passes locally. The
only failures are pre-existing and environment-specific, unrelated to
this change (a git default-branch test fixture, and a known
checkout-lock race) — both reproduce identically on clean `master` with
this change stashed out.
- Behavioural: a paused agent's execution-start now aborts cleanly with
no status clobber; non-pause cancellations keep `errorCode "cancelled"`
and existing behaviour; un-pausing resumes the in-flight issue.
## Risks
- Low risk. No schema change, no migration, no new dependency; four
files. The change narrows a single UPDATE to be conditional and adds a
rarely-taken abort branch on the run-start path; behaviour for invokable
agents is unchanged. The abort's `agent_not_invokable` code is already
in `NON_RETRYABLE_CONTINUATION_ERROR_CODES`. The only caller of
`cancelActiveForAgent` is the pause route.
## Related upstream work — not duplicates
This area has prior and in-flight PRs; #8317 was checked against them
and is intentionally distinct:
- **#4503** (`fix(heartbeat): make agent pause status guard atomic with
status update`) targets a different TOCTOU race on the **post-run /
finalize** path (`finalizeAgentStatus`). #8317 targets the
**execution-start** race, where a recovery-dispatched run flips a paused
agent back to `running` *before the run begins*. #4503 does not cover
the proven failure path here: `pause → active run cancelled → recovery
dispatches a new run → execution-start overwrites the paused state`.
#4503 also does not add the resume semantics below.
- **#4356** (`honor system/manual/auto pause at all heartbeat-run
enqueue sites`) and **#1067** (`pause guard on queue drain`) protect the
**enqueue / queue-drain** layer. They are complementary to — not
substitutes for — the execution-start guard, which is the last gate
before a run actually starts.
- **#6944** (`guard executeRun against paused agent`), **#7140**, and
**#7141** attempted similar execution-start ideas but were closed for
implementation hygiene / build issues, not because the guard concept was
wrong. #8317 implements that concept cleanly: a single atomic
conditional UPDATE, a clean abort with `errorCode:
"agent_not_invokable"`, a shared `DIRECT_NON_INVOKABLE_STATUSES` source
of truth, and passing tests + typecheck.
Intentional, minor difference (not a criticism of #4503): #8317's
execution-start deny-list is `paused`, `terminated`, and
`pending_approval` — the full non-invokable set for run-start
invokability — whereas #4503 appears focused on `paused`/`terminated`.
The broader set is deliberate for the execution-start guard.
Resume semantics: #8317 keeps `agent_paused` as observability-only and
classification-neutral (retryable), so a paused agent's in-flight work
resumes on un-pause rather than escalating to blocked.
## Model Used
- Provider: Anthropic. Model: Claude Opus 4 (`claude-opus-4-8`), via the
Claude desktop "Cowork" agent. Mode: agentic/extended reasoning with
tool use (shell, file editing, running `tsc`/`vitest`, git). Used to
investigate the root cause in source, design the fix, implement it, and
validate locally.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots (N/A — no UI change)
- [ ] I have updated relevant documentation to reflect my changes (N/A —
no doc-facing change)
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
- [x] I have searched the open and closed PR list for similar/duplicate
PRs and found none
|
||
|
|
fc95699fde |
fix(server): enforce agent secret binding sync across lifecycle flows (#8307)
## Thinking Path > - Paperclip is the control plane people use to create, configure, and run AI agents for work. > - This change sits in the server-side agent lifecycle and secret-binding subsystem, where adapter config `env` entries can reference company secrets. > - An incident (while trying to configure a Novita sandbox) showed that an agent can reach a broken runtime state if `adapterConfig.env` contains `secret_ref` entries but the matching `company_secret_bindings` rows are missing. > - The immediate run-path guard and error-surfacing work made the failure diagnosable, but they did not fully prevent new broken agents from being created. > - The risk came from create and approval flows being responsible for remembering to sync bindings at each call site, which is easy to miss as new flows are added. > - This pull request moves the invariant into `agentService` create/update/activate paths, keeps the existing hire-flow fix, and adds regression coverage for create, update, and legacy pending-approval recovery. > - The benefit is that agent secret binding integrity is enforced closer to the data mutation point, so future callers inherit the protection automatically. ## Linked Issues or Issue Description Refs #8309 ### What happened? A Paperclip agent could persist `adapterConfig.env` `secret_ref` entries without matching agent-scoped `company_secret_bindings` rows. When that happened, the config UI could still look configured, but the real run path failed pre-dispatch because the secret was not actually bound to that agent. ### Expected behavior Every normal agent create, config-update, and pending-approval activation flow should leave the agent with secret bindings that match its persisted secret-ref env config. ### Steps to reproduce 1. Create or activate an agent through a flow that persists `adapterConfig.env` secret refs without synchronizing `company_secret_bindings`. 2. Observe that the config state can still appear populated. 3. Start a run for that agent. 4. Observe that pre-dispatch binding validation fails because the secret reference exists but the agent binding does not. ### Deployment mode Local dev (`pnpm dev`) ### Installation method Built from source (`pnpm dev` / `pnpm build`) ### Agent adapter(s) involved - Claude Code - Not adapter-specific (core bug) ### Database mode Embedded PGlite / embedded local dev database flow ### Access context Board (human operator) created or approved the agent; agent runtime later consumed the config. ### Additional context This PR focuses on preventing new broken states from normal service flows and on backfilling the covered legacy pending-approval activation path. ## What Changed - Kept the existing branch-local hire-flow fix that synchronized bindings for route and approval paths. - Moved the binding integrity invariant into `agentService.create()`, `agentService.update()` when `adapterConfig` changes, and `agentService.activatePendingApproval()`. - Added `server/src/__tests__/agents-service-secret-bindings.test.ts` covering create-time sync, update-time resync, and backfill for legacy pending-approval agents. - Removed now-redundant route-layer and approval-layer binding sync calls once the service layer became authoritative. - Simplified the affected unit tests so route/approval tests no longer assert service-owned binding writes directly. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm exec vitest run server/src/__tests__/agents-service-secret-bindings.test.ts server/src/__tests__/approvals-service.test.ts server/src/__tests__/agent-skills-routes.test.ts` ## Risks - Low to medium risk. - This changes where secret-binding synchronization is enforced, so any unexpected caller that relied on upper-layer manual sync behavior could behave differently. - Agent create/update/activation flows now perform binding synchronization consistently, which adds binding-table writes at those mutation points. - This PR does not retroactively scan and heal every already-broken historical agent row; it prevents and backfills through the covered service flows. > 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 Codex class model via `codex_local` - Session model family: GPT-5 Codex - Tool-assisted coding with shell, git, HTTP, and local test execution - Reasoning mode: medium interactive tool-use workflow ## 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 run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] 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> |
||
|
|
67c98323b0 |
fix(recovery): exempt routine-parent issues from missing-disposition handoff (#8157)
Recognize active routine-parent issues as having a valid continuation path during successful-run handoff recovery. This prevents unnecessary missing-disposition corrective wakes when an active routine owns the next scheduled action. Also keeps the routine-continuation guard before the productivity check so logs surface the decisive skip reason for both productive and non-productive routine-parent runs. Verification: - CI status checks passed on PR #8157 - Greptile Review passed at 5/5 - Focused recovery unit test passed locally Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
5c11725784 |
build(deps-dev): bump tsx from 4.21.0 to 4.22.4 (#7754)
Bumps [tsx](https://github.com/privatenumber/tsx) from 4.21.0 to 4.22.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/privatenumber/tsx/releases">tsx's releases</a>.</em></p> <blockquote> <h2>v4.22.4</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.22.3...v4.22.4">4.22.4</a> (2026-05-31)</h2> <h3>Bug Fixes</h3> <ul> <li>resolve CommonJS directory requires inside dependencies (<a href="https://redirect.github.com/privatenumber/tsx/issues/803">#803</a>) (<a href="https://github.com/privatenumber/tsx/commit/1ce846335b7c445a3328c7d27f06424949356d97">1ce8463</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.22.4"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.22.3</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.22.2...v4.22.3">4.22.3</a> (2026-05-19)</h2> <h3>Bug Fixes</h3> <ul> <li>decode typed loader source (<a href="https://github.com/privatenumber/tsx/commit/dce02fc3b8b64a58d24560714902b16f89332f1f">dce02fc</a>)</li> <li>preserve entrypoint with TypeScript preload hooks (<a href="https://github.com/privatenumber/tsx/commit/68f72f3304d8c3ff7048bde8571af9c163fcefa2">68f72f3</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.22.3"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.22.2</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.22.1...v4.22.2">4.22.2</a> (2026-05-18)</h2> <h3>Bug Fixes</h3> <ul> <li>preserve CJS JSON require in ESM hooks (<a href="https://github.com/privatenumber/tsx/commit/35b700bd8620696df03827068af29dcd0d091a60">35b700b</a>)</li> <li>preserve named exports from CommonJS TypeScript (<a href="https://github.com/privatenumber/tsx/commit/11de737dae1fb9dae28db3716df5b1a7e1a6a089">11de737</a>)</li> <li>support module.exports require(esm) interop (<a href="https://github.com/privatenumber/tsx/commit/cf8f19918e4e0a0dc5ee5c52d8cc15e5e22d7c49">cf8f199</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.22.2"><code>npm package (@latest dist-tag)</code></a></li> </ul> <h2>v4.22.1</h2> <h2><a href="https://github.com/privatenumber/tsx/compare/v4.22.0...v4.22.1">4.22.1</a> (2026-05-17)</h2> <h3>Bug Fixes</h3> <ul> <li>resolve tsconfig path aliases containing a colon (<a href="https://redirect.github.com/privatenumber/tsx/issues/780">#780</a>) (<a href="https://github.com/privatenumber/tsx/commit/6979f28810829dc79ec9baf406e162a18b65ab4b">6979f28</a>)</li> </ul> <hr /> <p>This release is also available on:</p> <ul> <li><a href="https://www.npmjs.com/package/tsx/v/4.22.1"><code>npm package (@latest dist-tag)</code></a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/privatenumber/tsx/commit/1ce846335b7c445a3328c7d27f06424949356d97"><code>1ce8463</code></a> fix: resolve CommonJS directory requires inside dependencies (<a href="https://redirect.github.com/privatenumber/tsx/issues/803">#803</a>)</li> <li><a href="https://github.com/privatenumber/tsx/commit/dce02fc3b8b64a58d24560714902b16f89332f1f"><code>dce02fc</code></a> fix: decode typed loader source</li> <li><a href="https://github.com/privatenumber/tsx/commit/68f72f3304d8c3ff7048bde8571af9c163fcefa2"><code>68f72f3</code></a> fix: preserve entrypoint with TypeScript preload hooks</li> <li><a href="https://github.com/privatenumber/tsx/commit/69455cfefbfe71100a3c58d3ce7cea42445d9113"><code>69455cf</code></a> test: cover package exports for ambiguous ESM reexports</li> <li><a href="https://github.com/privatenumber/tsx/commit/35b700bd8620696df03827068af29dcd0d091a60"><code>35b700b</code></a> fix: preserve CJS JSON require in ESM hooks</li> <li><a href="https://github.com/privatenumber/tsx/commit/ef807dba6832260fb4cafd78d81f5469a733966b"><code>ef807db</code></a> chore: update testing dependencies</li> <li><a href="https://github.com/privatenumber/tsx/commit/3917090d4f61863ea6ea16e4a9a3722a112cc3f7"><code>3917090</code></a> test: document compatibility test taxonomy</li> <li><a href="https://github.com/privatenumber/tsx/commit/de8113ffa8edbcd4e05fa218324c3e8c2a4afdbe"><code>de8113f</code></a> refactor: centralize Node capability facts</li> <li><a href="https://github.com/privatenumber/tsx/commit/c1f62db45ada60b24ceb3dfdf7f64173d9a15396"><code>c1f62db</code></a> test: consolidate tsconfig path edge coverage</li> <li><a href="https://github.com/privatenumber/tsx/commit/4e08174ec10276ac71c9a69eb28426ad702d0c76"><code>4e08174</code></a> test: consolidate loader hook coverage</li> <li>Additional commits viewable in <a href="https://github.com/privatenumber/tsx/compare/v4.21.0...v4.22.4">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new releaser for tsx since your current version.</p> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
6f142a60ce |
build(deps-dev): bump @types/node from 22.19.11 to 22.19.21 (#7748)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.19.11 to 22.19.21. <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> |
||
|
|
b15fc221ca |
build(deps): bump @aws-sdk/client-s3 from 3.994.0 to 3.1072.0 (#7752)
Bumps [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) from 3.994.0 to 3.1072.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/aws/aws-sdk-js-v3/releases">@aws-sdk/client-s3's releases</a>.</em></p> <blockquote> <h2>v3.1072.0</h2> <h4>3.1072.0(2026-06-18)</h4> <h5>Documentation Changes</h5> <ul> <li><strong>client-ec2:</strong> Documentation updates clarifying CancelCapacityReservation cancellable states (<a href="https://github.com/aws/aws-sdk-js-v3/commit/e3723ba73e2f2d307254d49ec73c5b3d91b8d892">e3723ba7</a>)</li> </ul> <h5>New Features</h5> <ul> <li><strong>client-compute-optimizer:</strong> This release surfaces two new metrics Volume IOPS Exceeded and Volume Throughput Exceeded into EBS volume rightsizing recommendations. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/ded6618d5249ab413bd90b26d4cea91d5f4b9b8f">ded6618d</a>)</li> <li><strong>client-application-auto-scaling:</strong> Adds support for ECS high-resolution predefined scaling metrics (ECSServiceAverageCPUUtilizationHighResolution, ECSServiceAverageMemoryUtilizationHighResolution) enabling 20-second metric periods for faster scaling (<a href="https://github.com/aws/aws-sdk-js-v3/commit/95b3513a224a678fb92dc623f149d24adb96ae7b">95b3513a</a>)</li> <li><strong>client-cognito-identity-provider:</strong> In order to support the new TLS Self-Service feature, this change adds SecurityPolicyType to CustomDomainConfigType. During CreateUserPoolDomain and UpdateUserPoolDomain this is used to select a custom domain's TLS enforcement, and for DescribeUserPoolDomain it informs users about the current TLS. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/e89377876aa392ea403636b6821cdb3df253648b">e8937787</a>)</li> <li><strong>client-sagemaker:</strong> Adds support for automatic AMI patching on HyperPod clusters. Customers can configure patching strategies to automatically apply security patch with zero job termination. Customers can also specify an AMI version at instance group level and update cluster software to a certain AMI version. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/fd33a5e46ca314f064b9149900abe4e451661b5e">fd33a5e4</a>)</li> <li><strong>client-ecs:</strong> Amazon ECS services now support high resolution (20 second) CloudWatch metrics for CPUUtilization and MemoryUtilization. Use these metrics for faster service auto scaling. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/93055ac93bffca3e2957b2d67cb24ecdc784457a">93055ac9</a>)</li> <li><strong>client-healthlake:</strong> Adding New Configurations to the FHIR Create Datastore. The new configurations include NLP Configuration, AnalyticsConfiguration, ProfileConfiguration (<a href="https://github.com/aws/aws-sdk-js-v3/commit/494fa59f48705e23ab79da259046966831183c71">494fa59f</a>)</li> <li><strong>client-gamelift:</strong> Amazon GameLift Servers has launched support for customizing Linux capabilities in container fleets. You can now specify additional Linux capabilities for containers in a container group definition, giving you finer control over the default Docker capabilities available to your containers. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/93cefd905d4fc0c649b1d7ed69f4c8f0d79d3371">93cefd90</a>)</li> <li><strong>client-eks:</strong> Adds support for configurable control plane egress routing in Amazon EKS, allowing you to route control plane egress traffic through your VPC and control how the control plane reaches resources in your network such as webhook servers and OIDC providers. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/693db62958c6818b4cb847887b8e36a66347c119">693db629</a>)</li> <li><strong>client-lambda:</strong> Converging and fixing existing documentation gaps in Lambda SDK (<a href="https://github.com/aws/aws-sdk-js-v3/commit/6555a565348a308dad7a51c85457c2bcee87feb8">6555a565</a>)</li> <li><strong>client-synthetics:</strong> CloudWatch Synthetics adds support for multi-location canaries. Customers can now monitor their endpoints from multiple locations with centralized management from a primary location. The SDK includes new parameters for configuring multiple locations and tracking their state. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/f2c8b480812b5ba2d1e173a8a074df6d72654239">f2c8b480</a>)</li> <li><strong>client-cloudwatch-logs:</strong> Added optional startFromHead parameter to FilterLogEvents enabling descending timestamp order (newest first) when set to false. Default true preserves existing ascending order. Reverse sorting requires a startTime on or after Jan 1, 2024. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/1be63ed942af46df978e55df4bec6fb6c9d16e60">1be63ed9</a>)</li> <li><strong>client-batch:</strong> Adds Support for ordered allocation strategies- BEST-FIT-PROGRESSIVE-ORDERED or SPOT-CAPACITY-OPTIMIZED-PRIORITIZED (<a href="https://github.com/aws/aws-sdk-js-v3/commit/0e57e53b1e0914a03b5b7c7d346245a1e6b6da11">0e57e53b</a>)</li> </ul> <hr /> <p>For list of updated packages, view <strong>updated-packages.md</strong> in <strong>assets-3.1072.0.zip</strong></p> <h2>v3.1071.0</h2> <h4>3.1071.0(2026-06-17)</h4> <h5>New Features</h5> <ul> <li><strong>client-partnercentral-selling:</strong> Cosell Resonate AND Prospecing API Launch with ARN correction (<a href="https://github.com/aws/aws-sdk-js-v3/commit/7e8c98abe070924fbbd1ea2abc183f0715f80945">7e8c98ab</a>)</li> <li><strong>client-compute-optimizer-automation:</strong> This launch adds IfExists comparison operators to Compute Optimizer Automation rule criteria, so a rule can include recommended actions whose specified attribute isn't present. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/ab2c616d167a0796fba91e44d1118a6a8baee60d">ab2c616d</a>)</li> <li><strong>client-bedrock-agent:</strong> Launching Bedrock Managed Knowledge Bases. Added support for resource-based policies on Knowledge Base resources, enabling cross-account access for Managed Knowledge Bases. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/de0affe4ad738b7f07d91574e2b2cfd83a447d44">de0affe4</a>)</li> <li><strong>client-securityagent:</strong> Updated AWS Security Agent SDK model with new APIs for threat modeling, code review, security requirements, and additional integration providers. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/9c3d3351842902b1ea1e8be52c4e7f40b868daae">9c3d3351</a>)</li> <li><strong>client-opensearch:</strong> Adds support for configuring IAM Identity Center options on existing OpenSearch applications via the UpdateApplication API. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/94f06a20a15ab75302088d5f3c31d708a8256e5c">94f06a20</a>)</li> <li><strong>client-glue:</strong> This release adds support for Search and Discovery in AWS Glue, letting you and your applications search Data Catalog assets such as table and enrich them with business context and glossary terms. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/b394fc0b39c814d5f72593dfc4db5ff5c2cbe643">b394fc0b</a>)</li> <li><strong>client-bedrock-agentcore-control:</strong> AgentCore Gateway now supports inference targets to LLM providers (direct config or built-in connectors), HTTP passthrough targets with session stickiness, runtime target API schemas, AWS WAF web ACL association with configurable fail-open or fail-close modes, and interceptor payload filtering. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/75f1d588d526de04060ebd653ca1a96e7ea75ff6">75f1d588</a>)</li> <li><strong>client-devops-agent:</strong> Adds support for Remote A2A (Agent-to-Agent) agent registration and management. Adds new Release Readiness Review and Release Testing capabilities. Adds support for Git managed skills in AWS DevOps Agent. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/ebc040e1f3fc292d3eee1a9b146c972338e14807">ebc040e1</a>)</li> <li><strong>client-bedrock-agentcore:</strong> AgentCore Harness service will be Generally Available at NYS 2026 with this Treb release. Harness will support invoking specific endpoints via the qualifier parameter, AWS Skills for pre-built agent capabilities, and improved validation for skill git source URLs. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/5bf9fcccc3b4cc204df57caea2adcf254c5d3846">5bf9fccc</a>)</li> <li><strong>client-ecs:</strong> Releasing the ability to bring-your-own task-definition for CreateExpressGatewayService and UpdateGatewayExpressService (<a href="https://github.com/aws/aws-sdk-js-v3/commit/b7b9cb4f46a34c4ab0fedf2138a9a5ba17bdd731">b7b9cb4f</a>)</li> <li><strong>client-mq:</strong> This release adds private networking support for Amazon MQ for RabbitMQ. You can now associate AWS RAM resource shares with your broker and retrieve shared resource details using the new DescribeSharedResources API. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/e96af4503bfea9a6f211bc905b8e949af6cc38d7">e96af450</a>)</li> <li><strong>client-bedrock-agent-runtime:</strong> Adds new AgenticRetrieveStream API for managed knowledge bases to use conversation history and autonomously plan for multi-hop multi-KB reasoning with built-in evaluation and access-control. Updates Retrieve API for access-control-based filtering for managed knowledge bases. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/557f7b3246fb6530fb8dcb481f1035d7827d2a1e">557f7b32</a>)</li> </ul> <h5>Tests</h5> <ul> <li><strong>core:</strong> <ul> <li>prebuild before integration and e2e (<a href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8111">#8111</a>) (<a href="https://github.com/aws/aws-sdk-js-v3/commit/363f3fb7165d327e3ca24b3d7beffb19cc528c31">363f3fb7</a>)</li> <li>prebuild core before unit tests (<a href="https://redirect.github.com/aws/aws-sdk-js-v3/pull/8108">#8108</a>) (<a href="https://github.com/aws/aws-sdk-js-v3/commit/5f789e7fe2089eacff868a6e1d0b6c2c11313bbc">5f789e7f</a>)</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md">@aws-sdk/client-s3's changelog</a>.</em></p> <blockquote> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1071.0...v3.1072.0">3.1072.0</a> (2026-06-18)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1070.0...v3.1071.0">3.1071.0</a> (2026-06-17)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1069.0...v3.1070.0">3.1070.0</a> (2026-06-16)</h1> <h3>Features</h3> <ul> <li><strong>client-s3:</strong> Added support for annotations. You can now attach up to 1000 annotations (up to 1 MB each) directly to objects and create, retrieve, list, and delete them using new annotation APIs. Also added support for configuring an annotation table in S3 Metadata. (<a href="https://github.com/aws/aws-sdk-js-v3/commit/c555874690846b81904a2c0c1e96130bd03bbeaa">c555874</a>)</li> </ul> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1068.0...v3.1069.0">3.1069.0</a> (2026-06-15)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1067.0...v3.1068.0">3.1068.0</a> (2026-06-12)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <h1><a href="https://github.com/aws/aws-sdk-js-v3/compare/v3.1066.0...v3.1067.0">3.1067.0</a> (2026-06-11)</h1> <p><strong>Note:</strong> Version bump only for package <code>@aws-sdk/client-s3</code></p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/501cd332619533ae96f154d7c226dc2f7bf8d615"><code>501cd33</code></a> Publish v3.1072.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/3ce820aa54c953459eb58abe4f06e28ba4ceb87d"><code>3ce820a</code></a> Publish v3.1071.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/4f2cfe1cfc420d0b5bfa226ae6619dd67de73ccc"><code>4f2cfe1</code></a> Publish v3.1070.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/c555874690846b81904a2c0c1e96130bd03bbeaa"><code>c555874</code></a> feat(client-s3): Added support for annotations. You can now attach up to 1000...</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/7058d13814795c6ff06a960077269458520bf161"><code>7058d13</code></a> Publish v3.1069.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/67981c5a65d6dd797a065df034a8d0fcdaa9b7bd"><code>67981c5</code></a> chore(scripts): tuning the build graph (<a href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8095">#8095</a>)</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/0632f6dc8842caaa916c5f43a5043342ff9ba6bb"><code>0632f6d</code></a> Publish v3.1068.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/0a3246f174335af55a6981b4891f0f4c10dfe4c4"><code>0a3246f</code></a> Publish v3.1067.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/4b11912aef8adc845f81b7e9922bd180c5cf1d90"><code>4b11912</code></a> Publish v3.1066.0</li> <li><a href="https://github.com/aws/aws-sdk-js-v3/commit/e4ef6c57d8fd97d15e0a7a27a24396990d704307"><code>e4ef6c5</code></a> test: use crypto.randomUUID for resource names in e2e tests (<a href="https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3/issues/8091">#8091</a>)</li> <li>Additional commits viewable in <a href="https://github.com/aws/aws-sdk-js-v3/commits/v3.1072.0/clients/client-s3">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> |
||
|
|
b29b47ae4a |
build(deps-dev): bump @types/multer from 2.0.0 to 2.1.0 (#7751)
Bumps [@types/multer](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/multer) from 2.0.0 to 2.1.0. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/multer">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> |
||
|
|
6cfc6731d9 |
test(recovery): fix race condition in workspace validation comment check (#8294)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The heartbeat service manages agent run lifecycles, including workspace validation before launching git-sensitive local adapters > - When workspace validation fails, `escalateStrandedAssignedIssue` in the recovery service sets the issue to `"blocked"` and then asynchronously posts a system comment > - A test added in PR #7644 verifies the comment appears, but queried the database immediately after `waitForValue` resolved the issue status — creating a race between the status write and the comment write > - The test was passing before PR #8284 (pnpm lockfile refresh) but began failing after, suggesting the lockfile update shifted async scheduling enough to expose the window > - This pull request wraps the comment check in `waitForValue`, consistent with two identical polling patterns already used in the same test file (lines 1159-1162 and 1232-1235) > - The benefit is a consistently-passing test that unblocks dependabot PR #8155 from auto-merging via CI ## Linked Issues or Issue Description Refs PAP-72. Unblocks PAP-68 (dependabot PR #8155 which has auto-merge enabled and was blocked by this test failure). ## What Changed - `server/src/__tests__/heartbeat-process-recovery.test.ts`: replaced direct `db.select()` + `expect(comments.some(...))` with a `waitForValue` polling loop that waits until a comment containing `"workspace failed validation"` appears, then asserts it is truthy - No production code changed ## Verification The specific test `blocks a git-sensitive local adapter before launch when a project-workspace-linked issue is missing its project id` previously failed with: ``` AssertionError: expected false to be true src/__tests__/heartbeat-process-recovery.test.ts:1429:94 ``` After this fix: the test polls with a 3-second timeout and returns once the comment row exists. The comment IS written by `escalateStrandedAssignedIssue` — this was purely a timing issue in the test assertion. CI on this PR serves as the confirmation run. ## Risks Low risk — test-only change. No production code is modified. The `waitForValue` helper is already used 10+ times in the same test file with the same 3-second timeout; this use follows the identical pattern. ## Model Used - Provider: Anthropic - Model: Claude Sonnet 4.6 (`claude-sonnet-4-6`) - Context window: 200k tokens - Tool use: yes (file read, bash, edit tools) - Reasoning mode: extended thinking ## 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 run tests locally and they pass (CI will verify) - [x] I have added or updated tests where applicable (this IS the test fix) - [x] If this change affects the UI, I have included before/after screenshots (N/A) - [x] I have updated relevant documentation to reflect my changes (N/A) - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green (pending CI run) - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups (in progress) - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |