mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-09 16:35:27 +02:00
codex/plugin-task-execution
2085
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2d45f42e47 | fix(ui): refine mobile task surfaces (#13122) | ||
|
|
5cb4f061dd |
fix(ui): simplify provider notices and hide completion calls (#13109)
## Thinking Path
> - Paperclip shows agent work in task feeds.
> - Native tools and provider notices appear in that feed.
> - A routine completion call adds no useful action for the user.
> - A provider notice needs readable text to explain its warning.
> - This change hides the completion call and displays the notice
summary.
> - Saved run events remain available for inspection.
## Linked Issues or Issue Description
**What happened?**
The feed showed paperclip_finish as a normal tool call. Provider notices
showed
a generic name or a large key-value table instead of a clear warning
message.
**Expected behavior**
Hide the routine completion call from the task feed. Show a warning
icon,
a short severity heading, and the full notice summary across the row.
**Steps to reproduce**
1. Open a native Codex task that calls paperclip_finish.
2. Inspect its tool activity in the task feed.
3. Inspect a run with a repository-trust provider notice.
**Paperclip version or commit**
Reproduced on the implementation checkout. Replayed onto master at
|
||
|
|
2991a59b17 |
fix(adapters): prevent engine fallback and preserve usable runtime defaults (#13105)
## Thinking Path > - Paperclip manages agents that must write work and report task outcomes through its API. > - Local adapters select an execution engine and its permission settings. > - A higher ACP Node requirement can make an unchanged installation lose access to its default engine. > - The adapter then silently selects CLI, which can change permissions and block API access. > - This pull request keeps the engine choice fixed and reports missing prerequisites before work starts. > - It also gives explicit Codex CLI runs usable defaults and keeps managed services on a supported Node runtime. ## Linked Issues or Issue Description Refs #12215. Related changes: #11792 raised the Node requirement; #13094 addressed separate runner networking behavior. This change fixes the engine-selection and managed-launcher paths. **What happened?** An unchanged agent could switch from ACP to CLI after an upgrade. Codex CLI then used read-only permissions with networking disabled. The run could finish without updating its task. Repeated recovery attempts used the same unavailable setup. Managed updates also skipped the Node check and did not refresh old launchers. **Expected behavior** An unavailable engine must fail with a clear setup error. It must not silently select another engine. Explicit CLI runs must be able to write workspace files and call the API unless the operator configures stricter settings. Managed updates must validate Node and keep child tools on that runtime. **Steps to reproduce** 1. Run an ACP-default agent under Node 22 after the ACP minimum rises to 24.11. 2. Leave the engine unset and disable the approval/sandbox bypass. 3. Observe the old adapter select CLI and fail to write task disposition through the API. 4. Start a managed service with an old launcher and a supervisor PATH that selects a different Node for child tools. ## What Changed - Remove automatic engine fallback for Codex, Claude, Gemini, and Kimi. Check prerequisites for default and explicit ACP selections. - Return a configuration error with proof that provider work did not start. Stop automatic continuation retries for this error. - Enable Codex ACP workspace networking at the actual turn boundary. Upstream mode presets otherwise force it off even when config.toml enables it. Preserve explicit network denial and read-only mode. - Set workspace-write and network access defaults for explicit Codex CLI runs. Preserve explicit sandbox modes, profiles, and network restrictions. - Pin the validated Node directory in managed launcher PATH. Refresh legacy launchers during installs and npm/Git updates. - Reject updates on unsupported Node. Keep update checks, dry runs, and rollback available. - Synchronize the qualified Codex ACP executable identity across server, TypeScript runner, Rust runner, and provider-pack launch paths. - Add regression tests and update engine and installation documentation. ## Verification - [Full CI passed on the final head](https://github.com/paperclipai/paperclip/actions/runs/34387099695): typecheck, build/native runner verification, all general and serialized test shards, all browser shards, release registry, canary dry run, and policy checks. - Greptile: 5/5 on `2c1d6e2815830a5cd39e36c8a082cc0c4441b6c0`, with no unresolved review findings. Security gates are green. - Full workspace typecheck and build also passed locally. The final deployed Linux build passed. - Full Codex, Claude, Gemini, and Kimi source test suites: 804 passed, 2 skipped. Installer, updater, and launcher tests: 47 passed. Installed ACP turn-boundary tests: 3 passed. ACP packaging tests: 14 passed. Focused recovery classification tests also passed. - Real Linux Codex CLI runs, both fresh and resumed, wrote a workspace file and reached the control-plane health API with the new defaults. - Explicit read-only and network-disabled control probes retained those restrictions. - A real ACP run on the final deployed Linux build wrote a file and reached the control-plane API with HTTP 200, without engine fallback. The same probe failed DNS before the turn-policy patch. - Executable-identity and installed-policy contracts: 12 passed. Affected native server tests: 197 passed. Runner factory tests: 21 passed. Rust qualification and native provider integration tests: 11 passed. - Deployed the production changes to a Linux service on Node 24.20 after a verified database backup. Health, bootstrap readiness, static UI, executable/cwd identity, and guarded restart checks passed. The restart lost no runs. - Corrected stale Kimi skill-default and Gemini remote-archive fixtures; both suites pass. ## Risks - Default or legacy auto engine settings now fail when ACP is unavailable. Operators who intend to use CLI must select it explicitly. - Codex CLI now permits workspace writes and networking by default, and ACP workspace-write turns permit networking by default. Explicit operator sandbox settings remain authoritative. - Old managed launchers keep their pinned Node until they are reinstalled under a supported runtime. An old updater cannot repair itself; the documentation gives the current installer command. - Custom service wrappers and global/source installations must configure their runtime PATH. No database migration is required. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository inspection, shell execution, and test tools. The exact serving model identifier and context-window size are 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> |
||
|
|
8cfd30fb07 |
feat(ui): add composer Stop and simplify task controls (#13104)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The task composer is where operators direct running agents. > - Operators need to stop work without leaving the conversation. > - Existing pause controls already hold task trees and interrupt both runner types. > - This pull request connects the composer to those controls and removes repeated feedback. > - Operators can pause work quickly and still queue messages while agents run. ## Linked Issues or Issue Description **What existing behavior does this improve?** Task pause, resume, and cancellation in the task page and composer. **Current behavior** The empty composer cannot stop a running task. Task controls require extra confirmation and reason text. Pause can show several notifications for the task already on screen. **Proposed behavior** Show Stop while this task runs and the composer is empty. Text or attachments switch it to Send. Stop and the menu use the same manual pause hold. Parent pauses include descendants. Keep task cancellation in the menu with a compact confirmation. Show one quiet pause row and gray cancelled-run details. **Reason and benefit** Operators can interrupt execution with one click. Drafts and queued messages keep their existing behavior. The UI waits for actual termination, including native cancellation acknowledgment. **Breaking changes** No endpoint, schema, or task-status change. Pause no longer asks for confirmation or a reason. Resume now honors the existing wake-agents option. Task notifications are suppressed for the task and subtree currently in view. Related UI work: #8228 changes navigation and composer shortcuts. This PR covers execution controls. No duplicate Stop-button PR was found. The change improves existing controls and does not duplicate a roadmap milestone. ## What Changed - Add Stop, pending feedback, duplicate-click protection, and inline errors to the composer. - Share the pause mutation across the composer, active-run controls, and menu. - Poll affected runs after a pause request. Require native cancellation acknowledgment. - Remove pause confirmation and shared reason fields. Reduce cancel confirmation to its task count and actions. - Honor wake-agents for executable tasks only. Preserve the pause when recovery review is needed; show partial wake failures inline. - Preserve explicit legacy reconciliation decisions while their continuation waits for dispatch. - Suppress notifications for visible task trees. Use quiet pause and cancellation feedback. - Add interactive stories using production controls and native/legacy end-to-end tests. ## Verification - User reviewed the running feature and revised Storybooks in the browser. - Rebased focused checks passed: 295 original targeted tests, 161 updated route/page/notification/status tests, and 26 recovery integration tests. - Both isolated runner journeys pass on the final revision (1.7 minutes). Coverage includes queueing, parent and child interruption, persisted holds, no automatic continuation, reconciled resume, cancellation, terminal exclusions, and no Stop toast. - Native coverage uses real runnerd with a deterministic provider fixture. Legacy coverage checks actual process termination. Live hosted-provider execution was not tested. - Repository typecheck and build, Storybook build, and token gates passed after rebase. The final server typecheck/build also passed. - The broad local run completed its general-server stage with 7,219 passing tests, 48 skipped, and two failures from cached pre-fix source and a stale native provider fixture. Both failed tests pass in fresh final-head reruns after rebuilding the fixture; the script did not continue to its later local stages. CI runs all test groups on the final revision. - Final revision: all 31 applicable CI checks passed; Storybook visual regression was skipped by its workflow conditions. Greptile: 5/5, zero unresolved comments. - Review `Tasks / Execution Controls` in Storybook. Type and clear a draft, stop a run, expand cancellation details, and test the menu on desktop and mobile. ## Risks - Stop pauses descendants for a parent task. This is the existing pause contract. - A held task can remain active if interruption fails. The UI shows an error instead of claiming termination. - Resume can start multiple assignees when wake-agents is selected. Backlog, blocked, and terminal tasks stay excluded. Existing execution reconciliation remains mandatory where required; Resume never invents action-outcome evidence. - Notification suppression uses the visible task and cached subtree. Notifications for unrelated work remain enabled. ## Model Used OpenAI GPT-6 through Codex. The exact runtime snapshot and context-window limit are not exposed in this session. Used reasoning, tool calls, code execution, and browser 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] 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> |
||
|
|
622376e995 |
fix(ui): remove action buttons from agent list (#13101)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The agents list helps operators scan names, roles, and status. > - Each row also shows task, heartbeat, trace, pause, and overflow controls. > - These controls add a second line to every row and crowd the list. > - This pull request removes the action bar from list rows. > - Operators can still use agent detail pages for those actions. ## Linked Issues or Issue Description Related: #7543 introduced list actions. #13011 moved the row actions onto a separate line. No duplicate fix was found. **What happened?** The `/agents/all` list shows Assign Task, Run Heartbeat, Run with provider trace, Pause or Resume, and an overflow menu below each agent. **Expected behavior** The agent list should show agent information without this action bar. **Steps to reproduce** 1. Open `/agents/all` in an organization with agents. 2. Select the list view. 3. Inspect the controls below each agent name. **Paperclip version or commit** Reproduced in source at |
||
|
|
bf753b997a |
fix(connections): keep task context through Cloud enrollment and OAuth (#13098)
## Thinking Path
> - Paperclip lets people manage agent work from tasks.
> - Agents can request app access in a task card.
> - Some apps first require Paperclip Cloud enrollment.
> - Enrollment could leave the task, and OAuth could lose the task
interaction ID.
> - This PR keeps enrollment in a separate window and retains the
interaction ID through OAuth.
> - The task can then recognize the connection and continue
automatically.
## Linked Issues or Issue Description
**What happened?**
A first Gmail connection could leave the task dialog during Cloud
enrollment. Setup resumed on the Apps page. Gmail connected, but the
task card could remain pending because OAuth did not retain its
interaction ID.
**Expected behavior**
Keep the task open and preserve its access choices. Resolve the card
after the server verifies connection access. Continue the agent
automatically.
**Steps to reproduce**
1. Start a fresh source test-drive instance without Cloud enrollment.
2. Ask an agent to read Gmail.
3. Open Connect on the task card.
4. Complete Cloud enrollment and Gmail authorization.
5. Check whether the task card updates without selecting the connection
again.
**Paperclip version or commit**
Reproduced on
|
||
|
|
82f662656a |
fix(runner): restore legacy Git access and independent networking (#13094)
## Thinking Path
> - Paperclip runs agents for people with different GitHub accounts.
> - Managed operations must use the intended person's eligible
connection.
> - A failed duplicate connection must not hide a healthy grant for the
same account.
> - Legacy hosts also need their existing Git configuration when managed
access is not configured.
> - Runner networking and local Git operations must not depend on GitHub
broker availability.
> - This pull request separates those policies and improves failure
diagnostics.
## Linked Issues or Issue Description
**What happened?** New runs always cleared host Git credentials and
installed managed launchers. Network permission depended on GitHub
environment variables. A launcher failure could stop even local `git
status`. A newer unhealthy duplicate could take precedence over a
healthy connection, and generic health errors were shown as reconnect
requirements.
**Expected behavior:** Use a healthy eligible managed connection for the
intended account. Preserve host authentication only for unconfigured
standard-trust local or SSH execution. Permit local Git during broker
failures and keep network permission independent of GitHub credentials.
**Steps to reproduce:** Configure healthy and unhealthy grants for one
GitHub account, dispatch an agent, and execute Git commands. Separately
run an unconfigured legacy host with existing GitHub CLI authentication.
Stop the broker and run local `git status`.
**Paperclip version or commit:** Master at
|
||
|
|
e9a5a07ab4 |
feat(ui): add task status badges and inline blocker removal (#13097)
Add navigable status badges to task relationships and a separate blocker remove button with stable hover geometry. Keep Storybook previews passive and cover navigation, removal, and query refresh rendering with regression tests. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
cd4c4ed205 |
fix(ui): stabilize task loading and live feeds (#13095)
Coordinate initial conversation reveal, preserve message identity and reading anchors during live updates, and bound transcript reads with recoverable retries. Cover desktop/mobile navigation and rich task loading with actual-route browser tests. Verified all Linux CI gates, 5,575 local UI tests, eight layout browser scenarios, and recorded native Codex walkthroughs. Greptile: 5/5; all review findings resolved. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
35fdc0c66b |
fix: make task recovery durable and preserve current requests (#13075)
Make task recovery durable and preserve the latest user request across native and legacy continuations. Keep routine recovery quiet and prevent replay when action outcomes are uncertain. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
5acf56658b |
feat(onboarding): first task opens as a chat with a chief of staff (#13068)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Onboarding ends by handing a new user to their first agent on a seeded first task > - Today the wizard asks for a mission up front, the UI composes what the agent is told, and the agent starts running before the user says anything > - New users get a cold, ticket-shaped start, and nobody can edit the agent's brief or persona without a code change > - This pull request makes the first task a short chat: a four-step wizard, a chief-of-staff persona, a greeting plus a two-option opening card, server-owned markdown texts, and no run until the user answers > - It also gives question cards one consistent action row (Cancel / Skip / Next), makes agent hires idempotent within a run, and turns the Paperclip Runner flag on by default for self-hosted instances > - The benefit is a first run the user steers, with texts a board operator can edit as markdown ## Linked Issues or Issue Description No public GitHub issue exists for this change. The feature request fields follow. Related PRs and issues: - Refs #11043 — an earlier draft of the first-task onboarding experience. This PR supersedes it. - Refs #11280 — a report about the onboarding first-task route test. This PR extends that test file. ### Subsystem affected Onboarding wizard, the seeded first task and its texts, task-chat question cards, agent hiring, and the instance experimental settings. ### Problem or motivation The onboarding wizard collects a mission through two extra steps and a questionnaire. The UI then composes the first agent's instructions and the first task description from those answers. The first task wakes the agent at once, so the agent runs and posts before the user types a word. Board operators cannot change the greeting, the brief, or the persona without editing TypeScript. Question cards in chat behave differently per adapter, and a single-select pick submits on click. A misread hire response could create a duplicate agent that the creating agent cannot remove. ### Proposed solution Reduce the wizard to four steps and stop the UI from authoring agent texts. Move the greeting, the brief, the chief-of-staff persona, and the opening question into markdown and JSON files that the server loads at runtime. Seed the persona onto the first agent through an explicit hire marker. Do not wake the first task until the user answers the opening card or types. Give every question card the same Cancel / Skip / Next actions. Add an experimental toggle that switches the single-task proposal between one confirmation card and a plan document with a checkbox card. Make agent hires idempotent within a run. ### Alternatives considered - Keep the mission questionnaire and feed it into the brief. Rejected: the agent asks better questions in chat, and the wizard gets shorter. - Keep the first task open-ended with a plain composer. Rejected: a two-option card gives the user a clear first move. - Derive the plan-document behaviour from the user's intent only. Rejected in favour of an explicit experimental toggle so operators can choose. - Key the "pick does not submit" behaviour off the presence of a submit label. Rejected: several adapters set a submit label on single-select cards, and their cards would change behaviour. ### Roadmap alignment `ROADMAP.md` lists no planned core work on onboarding or the first task. This change refines the existing flow and does not duplicate planned work. ## What Changed - Wizard: four steps (Name your organization, Create your first agent, Connect a model, Review). The front door and both mission steps are removed with their state and saved-progress keys. The UI no longer composes the first agent's instructions or the first task description. - Server-owned texts: the greeting, the brief with two proposal variants, the chief-of-staff persona, the opening question, and a README live in `server/src/onboarding-assets/first-task/` and load at runtime. The create route stores the assembled brief and ignores any client description. - Persona seed: an `onboardingFirstAgent` marker on the hire lets the server seed the chief-of-staff persona over the first agent's entry file. Board-authored hires only. The persona tells the agent the hire response shape and to list agents before it acts on an unclear result. - No auto-run: the first task does not queue an assignment wake. The stranded-assignment reconciler leaves it idle until a user comment or an answered card exists. - Opening card: the server seeds an `ask_user_questions` card right after the greeting with two options: "Interview me and propose a plan and an agent team to execute it." and "I have a task in mind" with free text. Answering wakes the agent. - Experimental toggle `enableFirstTaskPlanProposal` (default off): the single-task proposal is one confirmation card, or a plan document plus a checkbox card when on. - Question cards: every `ask_user_questions` card renders Cancel, Skip, and Next (the submit label on the last question). Skip hides on required questions. Picking an option no longer advances or submits by itself. - Wizard guards: the dashboard's agentless offer ignores a cached empty agent list while a refetch is in flight. The hire step adopts an agent that already carries the typed name instead of hiring "Name 2". - Agent hires are idempotent within a run: a retry of the identical request under the same run id returns the existing agent with `200` and `idempotent: true`. The fingerprint covers the whole validated request, so a corrected payload is a new hire. Lookup, create, and activity record run under one lock per company and run, so overlapping retries cannot both create. - The Paperclip Runner experimental flag defaults to on for self-hosted instances. Cloud keeps its declared default: a managed instance whose tenant row and managed overlay omit the flag resolves it to off. - Question cards: a send that finds an earlier required answer missing returns to that question with a message instead of failing silently. - The two onboarding e2e specs follow the new wizard: the front door and growth intake shots are gone, and the planning-mode spec dismisses the opening card before it reads the composer. - Docs: `docs/board-operator/editing-first-task-texts.md` explains how to edit the texts and the toggle. ## Verification Commands, run from the repo root: ``` pnpm -r --filter './packages/*' --filter '!@paperclipai/paperclip-runner' build pnpm --filter ./packages/shared typecheck pnpm --filter ./ui typecheck pnpm --filter ./server exec tsc --noEmit pnpm check:token-gates pnpm --filter ./ui exec vitest run OnboardingWizard onboarding QuestionForm InteractionCard ProtocolCard TaskChatComposer Dashboard feature PAPERCLIP_IN_WORKTREE=false pnpm --filter ./server exec vitest run onboarding-first-task heartbeat-process-recovery agent-hire-idempotency instance-settings agent-skills-routes issue-onboarding onboarding-greeting --testTimeout=90000 ``` Results on this branch: - Typecheck is clean for shared, ui, and server. - Token gates: 4 of 4 clean. - UI: 344 tests pass across 23 files. - Server: all suites pass. The first test in `agent-skills-routes` has its own 10 s cap and needs about 15 s on my laptop for the app cold start. It passes with a longer cap. This PR does not change that cap. Manual steps on a dev instance: 1. Open `/onboarding`. Confirm four steps: Name your organization, Create your first agent, Connect a model, Review. 2. Finish the wizard. Confirm the first task shows the chief-of-staff greeting and the opening card with two options. Confirm no run starts. 3. Pick "Interview me…". Confirm no run starts. Press Continue. Confirm a run starts and an interview card of 3–4 questions arrives. 4. On a fresh organization, pick "I have a task in mind", type a task, and press Continue. Confirm a proposal arrives as one confirmation card. 5. Turn on Settings → Experimental → "First task: propose with a plan document" and repeat step 4. Confirm a plan document and a checkbox card arrive. 6. Visit the dashboard after the hire. Confirm the wizard does not reopen and one agent exists. 7. Open any question card. Confirm Cancel returns the plain composer with the card still pending, Skip advances an optional question, and Next moves to the next question. Design reference with flow diagrams, chat mock-ups, and live captures: https://pages.paperclip.ing/first-task-flow/proposed/ ## Risks - `pnpm dev` now builds the runner daemon because the Paperclip Runner flag is on by default. Developers without a Rust toolchain must set `PAPERCLIP_RUNNER_BINARY` or turn the flag off. Self-hosted instances that never set the flag now let qualified agents use the runner. - The wizard drops the mission steps and their saved-progress keys. A user who is mid-wizard on an older build restarts at step 1 after an upgrade. Existing organizations are not touched. - The first task no longer runs on its own. A user who neither answers the card nor types sees no agent activity. This is intended. - The persona seed applies only to hires that carry the marker from the wizard. API hires are unchanged. - Hire idempotency is scoped to one run id and to the exact request. Retries across runs, or with a changed payload, still create a second agent. The lock is per server process, which matches how an instance serves its API. - Single-select question cards no longer submit on pick. Users of adapters that relied on that behaviour now press Next. - No database migrations. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - Claude (Anthropic) through Claude Code. `claude-fable-5-1` with extended thinking, tool use, and code execution wrote most commits. `claude-opus-4-8` wrote the toggle, texts, wizard, and idempotency commits, as the `Co-Authored-By` trailers show. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
e200104727 |
feat: review connection actions from tasks (#13063)
Bring governed connection reviews into task history and composer approvals. Share resolution with Connections, add scoped remembered permissions, and resume agents through durable outcome receipts. Keep cards compact, collapse raw results, isolate untrusted provider output, bound continuation payloads, and reconcile missed live events. Add Storybook coverage, browser journeys, and service regression tests. Verification: all PR CI gates passed, Greptile 5/5, security scans passed, five connection-review browser journeys passed, and real native Codex approval/continuation was verified against the local MCP fixture. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
2043e0c735 |
fix: repair runner configuration, macOS execution, and artifact galleries (#13062)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent adapters select a provider, a model, and a runtime. > - Runner conversion rejected existing Claude agents. The model list mixed providers. > - The native Claude runner rejected custom models and could not launch on macOS. > - This pull request fixes conversion, model selection, and verified macOS execution. > - It also groups configuration fields consistently across adapters and opens artifact images in the task gallery. > - Operators can change an agent configuration and run the selected model on their Mac. ## Linked Issues or Issue Description **What happened?** Converting an existing Claude agent to Paperclip Runner failed with a Codex-only restriction. ACPX Claude showed unrelated models and required `claude-sonnet-5`. Its native runtime rejected macOS. Configuration mixed common model settings with process controls. Artifact cards labeled “Open gallery” navigated to attachment URLs instead of opening the task gallery. **Expected behavior** Conversion keeps agent identity and compatible settings. ACPX Claude uses the normal Claude catalog and accepts typed model IDs. Codex uses the native runner. The verified Claude runtime can launch on macOS ARM64 and x64. Common configuration sections place the same fields together across adapters. Artifact images open in the shared task gallery with navigation and downloads. **Steps to reproduce** 1. Open the configuration of an existing Claude agent. 2. Convert it to Paperclip Runner. 3. Select ACPX Claude and a different catalog model or a typed model ID. 4. Save the agent and run a disposable task on macOS. 5. Inspect configuration and advanced run-policy controls across adapters. **Paperclip version or commit** The bugs were reproduced on `165ca56a22adb60e5fda56045442d9c8498116a8`. This branch was rebased onto `7ed122911`. **Deployment mode** Built from source. Local test-drive instance on macOS ARM64 with an isolated database. Related work: #11798 addresses unsupported ACP session options in the existing adapter path. #13048 addresses working-folder preservation. This change fixes native runner configuration and launch behavior. ## What Changed - Remove the Codex-only conversion restriction. Preserve agent identity, instructions, directories, credentials, and compatible model settings. Reset incompatible sessions while retaining history. - Show ACPX Claude and native Codex as distinct provider choices. Remove ACPX Codex from advertised configuration. Normalize legacy configurations before fresh runs without rewriting historical run descriptors. - Select model catalogs and cache entries by provider. Support refresh and typed model IDs. Pass exact Claude IDs through session creation, model changes, and recovery. - Add verified macOS ARM64 and x64 Claude SDK snapshots. Bound executable allocation and total snapshot size. Preserve package checks, dependency isolation, process ownership, cancellation, and Linux descriptor loading. - Probe local runtime readiness. Report remote platform checks as incomplete until the remote runner verifies its runtime. - Surface actual model rejection and allow correction and retry. - Repair missing ACPX goal-capability helpers exposed by the post-rebase live test. Persist and restore the optional capability without breaking session startup. - Put Agent identity first and intentionally remove the Capabilities editor, as requested. This is removal of UI editing, not relocation: preserve existing capability metadata and API compatibility without adding another editor. Use the themed select for configurable permission modes, with normal text instead of monospace. - Put model and provider under Adapter. Give environment variables their own section. Fold command and arguments under Configuration. Fold lifecycle, timeout, and interrupt grace under Advanced Run Policy. Hide single-option permission controls. - Open image and video artifact cards in the existing task gallery, including cards in the artifacts panel. Chat attachment images use the same gallery. Preserve standalone media previews and download links. ## Verification - Rebased focused UI/API/database suites: 293 tests passed. - Rebased native runtime and ACPX suites: 242 passed, 7 skipped. - Repository typecheck, build, and token gates passed for the runner changes. Gallery follow-up UI typecheck, build, and token gates also passed. - Follow-up UI suites passed (86 tests), packaging checks passed (14 tests), and the final focused runtime suites passed (126 passed, 7 skipped). - Linux container isolation and lifecycle fixtures passed before rebase (57 passed, 2 skipped). Rust ACPX provider-session tests passed after rebase (8 tests). - Browser tests completed actual Claude and native Codex tasks on macOS ARM64. They covered conversion, catalog refresh, a non-default catalog model, a typed `haiku` ID, save/reload, cancel, follow-up session continuity, invalid-model errors, and recovery. - Final-revision live tests completed a typed Claude task, a follow-up with the same provider session, and a native Codex task on macOS ARM64. - Browser tests confirmed the moved interrupt-grace field saves and survives reload. Cross-adapter tests cover Claude, Codex, Gemini, process, gateway, and schema forms. - Full local run: 7,080 passed, 30 skipped, and two timeouts. Both timeout suites passed on isolated rerun (84 tests); the failures were the plugin login-worker exit diagnostic and the runner real-server vertical slice. - Final follow-up checks: 50 registry tests and 45 snapshot/installation tests passed (6 platform-specific skips). Oversized executable rejection is covered before allocation or reading; unsupported-platform tests invoke the real installation probe. - Runner head `ddb5101c483a297f74875ab96b3c66035b002d50`: all CI gates green, including full runner verification, repository build, typecheck, general/serialized server suites, browser tests, and canary dry run. [CI run](https://github.com/paperclipai/paperclip/actions/runs/34286178670). - Greptile: 5/5 on that runner head. All four review threads resolved. Superagent, Socket, and Snyk checks green. - After snapshot hardening, another real Claude task completed on this Mac using the rebuilt runtime. - Gallery follow-up: 148 focused tests passed, covering artifact selection, shared attachment collections, deduplication, image/video cards, standalone previews, downloads, and closing. Live browser verification completed on the settings follow-up: artifact selection, 6-image pagination with wrapping, download action, and closing all stayed on the same task URL. All checks passed on gallery head `96136da58ff195bf6ca00b281eb3022ad12d7bd8`: [CI run](https://github.com/paperclipai/paperclip/actions/runs/34287987536). Greptile returned 5/5 on that exact head with no unresolved threads. - Final settings polish: 96 focused tests, UI typecheck/build, and token gates passed. A real browser walkthrough verified readable permission options, identity placement, Capabilities removal, and permission save/reload. Original test-agent permission mode restored. All 31 checks passed on final head `e46540d6bf32bfb0566dca16b2f4a75ba437618c`: [CI run](https://github.com/paperclipai/paperclip/actions/runs/34292797886). Greptile returned 5/5 with no unresolved threads. ## Risks - Capabilities intentionally has no editable UI field after this change. Existing values remain readable and API-compatible; removing the field does not erase stored metadata. - macOS launch now copies verified package files into private snapshots. The implementation must retain isolation and clean up snapshots on exit. - Runtime provider or model changes reset the current session. Historical runs remain available. - The macOS x64 SDK executable digest was verified, but a live Intel Mac run was not available. Linux verification used container fixtures, not a real Claude task. - Remote environment tests report a warning when only the platform has been checked. They do not claim package readiness from the server host. ## Model Used OpenAI Codex, based on GPT-6. The exact served model identifier and context-window limit are not exposed in this session. Used reasoning, repository inspection, code execution, Rust and TypeScript tests, and browser automation. ## 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 (focused suites and both timeout suites on rerun; full-run counts above) - [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> |
||
|
|
7ed122911b |
Add end-to-end session goals to Paperclip Runner
Add capability-aware slash-goal controls, durable provider goal state, PRP v2 negotiation, autonomous goal execution, and safe local session recovery. Integrate with current master, preserve provider session identity, and verify the browser goal/chat/replacement/clear workflow and unsupported-agent rejection. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
e095b84dab |
feat(connections): connect services from native task feeds (#13058)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents use connections to reach external services. > - A fresh native task can have no service tools installed. > - The agent needs a way to discover services and ask the responsible person for access. > - This pull request brings the existing connection-intent flow into native task execution. > - The person can connect from the task, and the agent can continue with updated tools. ## Linked Issues or Issue Description **Subsystem affected** Native runner tool authority, connection intents, task interactions, and shared connection setup. **Problem or motivation** A task that needs an unconnected service cannot finish its work. Leaving the task to configure access also loses context. A resolved request must survive a restart and resume the correct agent once. **Proposed solution** Expose connection discovery and access requests as server-owned native tools. Render a durable task card and use the shared setup dialog. Persist outcome delivery and start a fresh provider session after access is ready. **Alternatives considered** Sending the person to the Connections page adds navigation and does not solve continuation. Polling for authorization consumes runs and can create duplicate requests. **Roadmap alignment** This extends the existing connection-intent runtime and setup experience. It reuses the shared access model and the native runner. Related: #12345, #12347. The service-slug fix in #12906 is related but separate. Companion evaluation PR: https://github.com/paperclipai/paperclip-evals/pull/21. ## What Changed - Expose `connections_search` and `connection_request` with server-bound company, task, agent, and responsible user. Preserve the legacy entry points. - Discover catalog services and authorized custom connections. Check installation, identity, health, and executable permissions before reporting ready. - Keep pending cards through ordinary messages. Reuse requests and retire stale ownership. Put Connect at the right of Not now. - Reuse the shared setup flow in a task dialog. Keep access additive and default to the requesting agent. Recover from cancelled or blocked OAuth windows with a new-tab fallback. - Persist outcome delivery with an idempotent wake key. Resume in a fresh session and recheck ownership before dispatch. - Add native browser fixtures, offline Storybook states, server contracts, and evaluation fixtures. Update guidance and documentation. ## Verification - `pnpm build`: passed after replaying the change on current master. - `pnpm -r typecheck`: passed. - `pnpm check:token-gates`: passed. - `pnpm --filter @paperclipai/ui build-storybook`: passed. - New continuation-policy regression cases: 16 passed. - Docker-backed PostgreSQL regressions passed for requester-only OAuth access, assignment-only expiry, terminal expiry, and credential-free setup metadata. - Shared setup and task-card UI tests: 121 passed, including configured MCP reconnect URL recovery and preserving user edits across refetch. - Storybook browser checks: all 119 passed on the latest reconnect fix. - `pnpm test:run`: 4,734 tests passed in the first server group, but embedded PostgreSQL startup failures and resulting cleanup errors prevented a complete local pass. All Linux CI lanes passed on the latest reviewed commit. One external-object route test returned an unexplained 500 on the first run; it passed twice locally and the failed shard passed on retry without code changes. - Earlier feature-checkout evidence: three deterministic native browser journeys passed, including restart delivery and an actual fixture tool result. Legacy scripted coverage also passed. All 59 added stories were inspected in light and dark themes. - Live Notion testing recorded successful provider reads. The manual test used a local-trusted instance. It does not prove authenticated/cloud deployment or every provider journey. - Native browser rerun reached the embedded PostgreSQL startup limit before bootstrap, so the latest checkout’s full native browser journey remains unverified. Both OAuth page/task regression cases passed against isolated Docker-backed PostgreSQL 17. They verify no premature task access, requester-only completion, additive retries, and reconnect preservation. - Applied both new migrations twice to isolated PostgreSQL 17. Foreign keys remained intact, duplicate active delivery keys were rejected, and failed delivery records did not block retries. Reviewer path: start a fresh test drive, enable the native runner, use an agent that can perform work directly, and ask it to summarize a Notion page. Connect from the card, then verify the resumed provider call and source-linked answer. The default test-drive CEO is instructed to delegate, so it can introduce an unrelated hiring step. ## Risks - Two additive migrations create durable deliveries and a partial unique wake index. They are idempotent. The wake index can require a maintenance window on large tables because migrations run in a transaction. - OAuth and continuation cross asynchronous boundaries. Tests cover ownership changes, retries, additive access, and restart delivery; live provider behavior still varies. - The latest requester-scope fix has not yet been exercised through live OAuth. GitHub, API-key, authenticated-user, and all recovery journeys are not claimed as verified. ## Model Used OpenAI GPT-6-based Codex assisted with implementation, tests, and review using tools and code execution. The runtime does not expose the exact model version, context window, or reasoning setting. Live evaluation used `gpt-5.6-luna`; manual native testing used `gpt-5.6-sol`. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used and disclosed unavailable runtime details - [x] I have checked ROADMAP.md and confirmed this extends existing connection work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the feature issue template - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [ ] I have run all required tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation - [x] I have considered and documented risks - [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> |
||
|
|
5128b4f323 |
fix(claude): default unset models to Opus 5 (#13055)
Resolve unset Claude models to Opus 5 across CLI and ACP execution, preserve explicit and provider-specific overrides, and show the default in agent configuration. Verified 212 focused tests after merging master, UI typecheck and token gates, and all CI checks. Greptile reviewed the final head at 5/5. Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
ebaeba40ee |
feat: simplify agent onboarding and configuration (#13011)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Operators create agents and configure their runtimes in the board UI. > - The old creation flow presents several choices and a large form before an agent can start. > - The existing onboarding controls already provide clear provider connection steps. > - This pull request uses those controls in a new-agent wizard and organizes the full configuration pages. > - Operators can connect, test, save, and assign a first task while keeping the existing configuration tools. ## Linked Issues or Issue Description Related: #10974. That earlier open PR also reorganizes agent configuration. This PR follows the reviewed Storybook designs for agent creation and the current configuration tabs. **What existing behavior does this improve?** Agent creation, provider connection, runtime tests, and full agent configuration. **Current behavior** The creation dialog leads to a large manual configuration form. Provider login controls differ from onboarding. Environment variables and secret access appear in separate places. **Proposed behavior** Choose a name and adapter. Connect Claude or Codex through the existing onboarding controls. Configure and test the runtime, save the agent, and open a task dialog with that agent assigned. Use the same design on the existing configuration tabs. **Reason and benefit** The first setup asks for fewer decisions. The full editor keeps instructions, skills, runtime controls, secret access, permissions, keys, and revisions available in clear sections. **Breaking changes** The board creation and configuration layouts change. The test-environment API adds an optional, allowlisted `testCredentials` field for one-shot probes. Database contracts stay the same. Native ACPX tests now reject unsupported local platforms before a CLI login can mask the runtime restriction. ## What Changed - Added a new-agent wizard with numbered steps, adapter branding, provider connections, editable model choices, runtime tests, and confirmation. - Added Codex app-server, Claude ACPX, and OpenCode runner choices. - Stored API credentials through existing secret APIs and persisted references in agent configuration. New setup keys are isolated from credentials used by existing agents. - Preserved external-agent invitations beside the wizard, including optional messages, one-time prompts, and clipboard fallback. - Added OpenRouter provider and secret bindings for Pi and OpenCode. - Added adapter-specific prerequisite fields for Cursor, Gemini, Kimi, and Hermes. Cursor Cloud keys are saved as new organization secrets. - Fixed Cursor Cloud repository field mapping, omitted empty remote environment values, and added useful model and repository error messages. - Preserved complete MCP assignments when multiple valid profiles contain more than 250 tools in total. Generated profiles retain exact tool selectors. - Added service branding and deployment-aware adapter choices. Cloud setup offers Claude, Codex, and OpenCode; local native runners require the experimental setting. - Made the agent list responsive at intermediate widths. - Applied the reviewed design to the real agent configuration pages. Kept the instruction editor, skills, and existing mutations. - Combined secret access and environment variables under one Save and Discard action. - Added interactive Storybook screens for setup, configuration, confirmation, authentication, and test results. - Fixed Pi provider-error parsing and thinking-effort persistence. Native ACPX validates Linux x64 on the actual local, SSH, or sandbox target. - Redacted the complete transient probe-credential field from HTTP error logs, including rejected provider names. ## Verification - Current head `df0292fe6` has a fresh Greptile 5/5 review with no unresolved findings. All 31 executed CI checks passed, including the aggregate verification gate and all browser E2E shards. Storybook visual regression is skipped by its workflow; the local Storybook build passed. - Browser tests completed real assigned tasks with direct Codex, Claude, OpenCode, Pi, and native Codex. - Verified external-agent invitation generation and automatic prompt copying in the live browser. - Pi and OpenCode used an existing OpenRouter secret. Browser checks covered save and reload, instruction edits, skill selection, environment-variable Save and Discard, and assigned task creation. - Invalid Claude API credentials remained on the connection step with an error. A live Pi/OpenRouter invalid-key probe returned a provider failure and left the user-secret inventory unchanged (zero entries before and after). - Full workspace typecheck and build passed after rebasing onto current master. After review fixes, server and UI typechecks, token gates, and the full build passed again. Storybook built successfully. - All 5,542 local UI tests passed. The Cursor Cloud and Pi adapter regressions passed all 24 tests. Review regressions passed 69 server tests and all 18 agent-list tests. - The local full test command ran 6,971 general server tests successfully. Editing review fixes during that long run caused nine tests to use stale modules; fresh isolated runs passed. An unrelated embedded-Postgres fixture hit the host shared-memory limit; its 15 affected tests passed when the fixture groups ran separately. - Local workspace groups passed after rerunning 18 CLI tests sequentially to avoid host database limits and parallel-load timeouts. The local full command stopped at the general server phase, so serialized server verification comes from the five passing CI shards. - Browser testing at 390px confirmed that the agent action menu opens and the page has no horizontal overflow. CI browser E2E shards passed. - Review the `Onboarding / New agent` and `Agents / Configuration refresh` Storybook groups. In the real app, create an agent, run its connection test, save it, assign a task, and reload its configuration. ## Risks - This changes the main agent setup and configuration UI. Regression tests cover routing, persistence, secret bindings, and form actions. - Native Claude ACPX requires Linux x64. Direct Claude works on macOS. Remote checks execute a bounded platform probe and reject unsupported or unverified targets. - A native OpenCode task reached the provider context limit because of its tool payload. Its provider connection test passed. Direct OpenCode completed a task. This existing native execution limit is not fixed here. - Claude and Codex connection keys use the existing user-secret store. Other runtime setup keys use distinct organization secrets. Existing credentials are never rotated. Probes do not store entered keys. Failed agent creation removes newly staged credentials. - Cursor Cloud has not completed a live task. Its authenticated account still needs GitHub repository access. The live run passed MCP provisioning, remote environment validation, and explicit Auto model selection before the repository prerequisite blocked execution. - Generated runtime MCP profiles can exceed the public profile-edit request limit. They still contain exact catalog selectors and preserve permission boundaries. - No database migration, dependency, lockfile, or workflow changes are included. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository tools, shell execution, and browser automation. The runtime did not expose the exact model ID or context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [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> |
||
|
|
db85bf4b7a |
fix(ui): simplify GitHub repository access controls (#13047)
## Thinking Path > - Paperclip helps people manage AI agents and their connected apps. > - GitHub permissions show which repositories an account can access. > - The page adds an account dropdown and search above the repository list. > - These controls add clutter to a view meant to show the full access list. > - This change removes both controls and their filtering state. > - People see all repositories directly, with the existing scrolling and access controls. ## Linked Issues or Issue Description Refs #12998. **Current behavior** GitHub permissions show an “All accounts” dropdown and a “Search repositories” input above the repository list. **Proposed behavior** Show the full repository list directly. Keep the scroll limit, repository links, private-repository icons, refresh button, and GitHub configuration links. **Reason and benefit** Remove unnecessary controls from the access summary. Users manage repository permissions on GitHub. ## What Changed - Remove the account dropdown, search input, filtering state, and unused imports. - Rename the GitHub configuration button to “Add More Repos on GitHub”. - Render every returned repository and simplify the empty-list message. - Update the existing multi-account test and permissions documentation. ## Verification - All 55 AppDetail tests passed. - `pnpm check:token-gates` passed. - Full `pnpm build` and `pnpm -r typecheck` passed. All 31 CI checks passed on `cb9b8bb14a880d926393c62821265fbd2d8c5d31`. Storybook visual regression was correctly skipped. - Fresh Greptile review on the same commit: 5/5, with no unresolved findings. ## Risks Users can no longer narrow this list by account or search text. The list still scrolls and shows each repository’s full owner/name. This change does not alter GitHub permissions or credential selection. ## Model Used OpenAI GPT-6 through Codex, with code editing and shell verification tools. The exact model variant and context-window size are 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> |
||
|
|
be6bb768b1 |
fix(ui): restrict company navigation to accessible memberships (#13039)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The board selects a company before it loads that company's inbox and tasks. > - Instance administrators can list companies where they have no membership. > - The board treated that directory as a list of companies the user could enter. > - This pull request gives navigation a list based on the existing company access check. > - Users can select their companies without landing on an inbox that rejects their access. ## Linked Issues or Issue Description Fixes #6090. Refs #4855 for the related account-recovery case; this PR does not grant company membership. **What happened?** An instance administrator can select a company where they have no membership. Its inbox then shows “User does not have access to this company.” Company directory visibility and access to company contents use different rules. **Expected behavior** Company navigation should show only companies the current user can enter. A stored selection for an inaccessible company should fall back to an accessible company. A direct link to an inaccessible company should use the existing unavailable-company page. **Steps to reproduce** 1. Create Company A and Company B with separate owners. 2. Sign in as an instance administrator who belongs only to Company A. 3. Select Company B through a stored selection or a link with its prefix. 4. Observe that the board accepts the company selection, but company-scoped requests return 403. Related: #10524 lets cloud users enter additional companies where they hold memberships. This fix preserves that access and excludes companies where they have no membership. ## What Changed - Added `scope=accessible` to `GET /api/companies`, using the existing `hasCompanyAccess` predicate. - Changed the board navigation list to request that scope. Instance Access uses a separate unscoped, account-keyed directory so administrators can manage all companies. Membership edits refresh navigation. - Reject empty, unknown, and repeated scope values with 400. Directory loading errors offer a retry before access controls are shown. - Added route tests for cloud, session, board-key, local trusted, non-member, and agent access. - Added client and component tests for navigation/admin request isolation, grants outside the navigation list, self-membership refresh, directory failure recovery, and forbidden administration. - Updated the API guide and OpenAPI document. ## Verification - Latest commit: 36 focused UI tests passed. The broader UI shard passed all 281 files / 2,533 tests after correcting an asynchronous test assertion. - Server authorization and OpenAPI regression suites: 31 tests passed. - UI typecheck and `pnpm check:token-gates`: passed. - `pnpm -r typecheck` and `pnpm build`: passed after review fixes. - Full local test runner: exercised the supported shards. Several unrelated suites hit embedded PostgreSQL startup failures or startup timeouts under local load. The UI regression issue found in the broad run was corrected and its full UI shard passed. These local limitations are not reported as a green full-suite result. - [GitHub CI](https://github.com/paperclipai/paperclip/actions/runs/34233416473): all checks green on `4e1698cd4` — all server and workspace test shards, all browser end-to-end shards, typecheck/release registry, build, canary dry run, policy, and Docker context integrity. Security checks also passed. - Greptile: 5/5 on the latest commit; both initial findings addressed and all review threads resolved. ## Risks - The UI now excludes companies visible only through instance administrator status. Company membership continues to control access to contents. - Additional companies with active memberships remain available. - The client and server changes must ship together. An older server ignores the new query parameter and retains the previous behavior. - No database migration or permission grant changes. ## Model Used - OpenAI GPT-6 through Codex, with reasoning, repository inspection, code editing, and test execution. The exact served model identifier and context window are 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> |
||
|
|
b97101893f |
feat(projects): select multiple GitHub source repositories (#13010)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Projects give tasks a common source repository and execution context. > - The current project form asks for a raw URL and unrelated metadata. > - Teams need to select several repos from GitHub connections they can use. > - This pull request implements the reviewed project form and repository editor. > - The server checks credential ownership and shared audiences before discovery. > - Existing workspace URLs and runtime identity rules remain compatible. ## Linked Issues or Issue Description **Problem or motivation** Project creation accepts one raw repository URL. It does not help users select repos from their usable GitHub connections or attach several repos together. **Proposed solution** Add a shared GitHub repository picker to project creation and Configuration. Support multiple selections, transactional persistence, and the existing GitHub setup flow. Simplify the project form and Configuration tab as reviewed. **Alternatives considered** Keep a raw URL field or add a separate repository table. The existing workspace collection already supports several repositories and keeps legacy URLs compatible. **Roadmap alignment** This builds on the shipped MCP Tool Gateway and Apps capability. It does not change runtime credential delegation. Related work: #11662 addresses the existing dialog's viewport limits. #4552 addresses generic Git URLs; this change preserves those URLs in existing workspaces. ## What Changed - Add company-scoped repository discovery from usable personal and shared GitHub grants, with provider-ID deduplication, PAT pagination, and partial failure handling. - Document the repository endpoints and board access requirements in OpenAPI. - Validate new selections and save projects with multiple repository workspaces in one transaction. Preserve legacy URLs and existing selections whose access was lost. - Implement the reviewed Create project dialog, shared repository editor, scrolling, and mobile layout. - Move repositories above environment variables, remove Status and Goals controls and env help paragraphs, move Created to the bottom, and redirect Overview to Configuration. - Reuse GitHub setup in dialogs, preserve project drafts, and verify popup completion through the API. - Replace the configuration story's DOM adapter with explicit production composition. Keep the reviewed mobile and short-viewport stories. ## Verification - Passed: `pnpm build`, `pnpm -r typecheck`, `pnpm build-storybook`, and `pnpm check:token-gates`. - Passed: focused repository access, database persistence, configuration, and connection setup tests. - Passed: `pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/project-repositories.spec.ts`. - The browser tests use a real temporary server/database. They cover create, forty persisted repos, mobile scrolling, save/reload, legacy URL editing, and rejection without a partial project. - GitHub responses and popup completion use deterministic fixtures. No real GitHub account was authorized by the test suite. - All CI general, serialized server, and browser test shards pass on the final commit. - The local full-suite run overlapped review edits and was stopped; fresh repository, OpenAPI, UI/CLI, and connection tests pass. Unrelated local worker, built-in-agent, and routine timing/socket failures passed isolated reruns. - Final commit `1b3308dca`: all CI gates pass, including build, runner verification, typecheck, canary dry run, and security checks. Greptile is 5/5 with no unresolved review threads. - Storybook visual regression is opt-in and was skipped by CI; the Storybook build passed locally. ## Risks - Repository discovery depends on provider availability. Failed connections are reported while successful results stay usable. - Selections identify source workspaces; they do not grant agents new credentials. The existing primary-workspace and responsible-user identity rules still apply. - No database migration is needed. Existing API status, goals, dates, and manual workspace URLs remain supported. ## Model Used OpenAI Codex, based on GPT-6, with repository inspection, code execution, and browser tools. The runtime does not expose a more specific model deployment ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [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> |
||
|
|
d8b9580531 |
fix(ui): debounce recent task ordering (#13007)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The recent tasks sidebar helps operators return to active and
completed work.
> - Task detail refreshes update the activity timestamps used to sort
that list.
> - Older responses can undo newer activity. Concurrent updates can move
rows repeatedly.
> - This pull request preserves the newest observed activity and
debounces row moves.
> - Operators can select a stable row while task text and live state
stay current.
## Linked Issues or Issue Description
**What happened?**
Recent task rows can repeatedly swap positions when two tasks receive
updates. Older detail responses can also move a task below another task
after a newer comment promoted it.
**Expected behavior**
Rows remain stable during an update burst. The final activity order
appears after one second of quiet. Old responses never reduce the
recorded activity time.
**Steps to reproduce**
1. Enable the streamlined UI and open multiple tasks.
2. Send alternating updates to two tasks in the recent list.
3. Observe row order while those updates arrive and while older detail
data refreshes.
**Paperclip version or commit**
Base commit:
|
||
|
|
1cc45086d3 |
feat: use the responsible person's GitHub for shared agent operations (#13005)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Several people can send instructions to the same agent and task. > - A fixed GitHub token in the provider process can keep the first person's access after another person's message is accepted. > - Task ownership cannot select credentials for each accepted instruction or preserve the identity of an operation already in progress. > - This pull request records ordered execution identity contexts and resolves credentials when managed Git, gh, or GitHub tools start. > - The benefit is automatic personal GitHub access for shared agents, with durable continuation rules and no teammate credential fallback. ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting: orchestration, connection grants, database, runtime adapters, native runners, and run details. **Problem or motivation** A shared agent must use the person whose instructions it has accepted. A queued message must retain its author. A retry or approval without new instructions must retain the originating identity. GitHub must remain optional for ordinary work. **Proposed solution** Persist execution identity separately from task ownership. Give new processes a run-scoped broker capability and token-free managed launchers. Capture identity at operation start. Keep an explicit dedicated-agent grant as an override. Show redacted diagnostics in run details. **Alternatives considered** Per-task ownership, fixed provider tokens, and mutable repository author configuration do not handle accepted steering or concurrent operations. A manual account-selection action would add unnecessary setup to each turn. **Roadmap alignment** This completes the existing Multiple Human Users, MCP Tool Gateway & Apps, Secrets Manager, and Self-healing Runs capabilities. The implementation follows the maintainer-approved plan. Related work: Refs #12843, Refs #12907. Existing proposals #4618 and #8945 cover per-agent or per-worktree author configuration. This change instead follows the accepted human instruction across runtime types. Refs #11831 for governed personal connection delegation; this change preserves connection audience checks and does not use standing delegation as a personal credential fallback. ## What Changed - Add durable, ordered identity contexts and active run references. Preserve message authors through consolidation, steering, retries, delegation, approvals, routines, and restart. - Add an authenticated operation-time GitHub credential broker and local/remote managed git and gh launchers. Keep personal tokens out of the long-lived provider process. - Resolve GitHub gateway and server-side Git operations through the same responsible-person or dedicated-grant selection rules. - Make absent and unavailable GitHub credentials non-blocking at generic startup. Clear host and prior-person credentials. Keep anonymous Git access where supported. - Add run-detail identity history and the dedicated-account warning. Keep task ownership and queue-versus-steer decisions unchanged. - Preserve personal OAuth declarations through connection edits. Retain exact selected grants in the gateway. - Fix continuation races found during real acceptance: verify a warm owner before credential rotation, and wait for bounded durable runner suspension before the next run starts. - Make migrations replay-safe. Retain identity through agent/run deletion, remove it with its company, and clean terminal launcher directories before releasing execution environments. Document coordinated release and rollback. ## Verification - Full workspace typecheck, build, and token gates passed. The complete local suite passed in its normal test groups: 17,120 passing tests, including all 143 serialized server suites. After integrating the newly merged runner API work, full local typecheck and build passed again, along with 890 focused integration tests. All 31 checks on the integrated revision passed, including build, browser E2E, release registry, canary dry run, typecheck, security and all test suites. Greptile is 5/5 with all review threads resolved. - Current focused checks passed: 142 native executor tests, 67 runtime lifecycle tests, 9 durable identity tests, 75 credential/routine tests, 19 low-trust/resumption tests, and the executable migration replay test. - Authenticated browser acceptance with two Paperclip users and two GitHub accounts on one shared native agent passed. Real commits and pushes followed A → B accepted steering → queued A continuation in the same saved conversation. GitHub commit author and committer identities matched all three operations. Both runs succeeded and task ownership stayed unchanged. - Real GitHub MCP calls switched from A to B after accepted steering. A delegated subtask retained its originating identity across a server restart. - Disabling B's GitHub connection left ordinary work successful. Managed gh was unauthenticated and the provider had no inherited GH_TOKEN or GITHUB_TOKEN. - The browser displayed run-detail diagnostics and the exact dedicated-account warning. A final controller-restart check followed by another-person continuation retained the conversation, selected the correct GitHub login and Git author, and removed each terminal launcher directory. - Company-lifetime migration and all five previously failing CI suites passed locally (167 tests). Same-token gateway A → B → A and six broker/launcher boundary tests passed. - Remote callback, launcher, sandbox, and runtime contract tests passed. Both native and legacy Codex completed actual Daytona executions on the integrated revision ([campaign results](https://github.com/paperclipai/paperclip/actions/runs/34155056509)). The remote package-manager shim staging regression also passed locally. ## Risks - Deploy the migrations, server broker, launchers, and runner artifacts together. Existing processes finish with their original contract. New managed processes need the broker endpoint for GitHub operations. - Finish or stop new managed executions before rolling application code back. Keep the additive schema and identity history during rollback. - Scripts that require a persistent raw GH_TOKEN must use managed git, gh, or GitHub gateway tools. Run capabilities authorize code executing within that run to acquire its current identity; this is not hostile-code isolation within one execution principal. Managed commands prevent automatic credential carryover; arbitrary code deliberately copying a credential is outside that boundary. - Uncertain steering acknowledgement deliberately holds new credential acquisition until reconciliation. Already-started operations retain their captured identity. - GitHub private access and provider outages can still fail the specific operation that needs them. Dedicated grant failure does not fall back to personal access. ## Model Used OpenAI GPT-6 through Codex assisted implementation, review, shell execution, and browser acceptance. The exact model variant and context-window size are not exposed in this session. Tool use included TypeScript and Rust tests, database integration tests, GitHub CLI, and authenticated browser control. ## 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> |
||
|
|
f6a211479f |
fix: share current CLI runtimes across sandbox adapters (#12994)
## Thinking Path - Paperclip Runner needs its runtime preinstalled for fast sandbox startup. - Native and local adapters should launch one current CLI installation per provider. - An older global copy can shadow that installation, and exact native compatibility pins must match it. - Update the qualified releases and binary digests, expose shared CLI entrypoints from the provider pack, and prefer the image-owned bin directory. - Keep dependency installation in the image build; task startup only discovers, links, and verifies artifacts. ## Linked Issues or Issue Description **What happened?** Remote native startup rejected a stale global Codex, while CLI-only images lacked runnerd entirely. **Expected behavior** An image-baked runtime starts without uploading binaries or installing packages. All adapters share the same current provider CLI. **Steps to reproduce** Start a native remote task with the old global Codex and the updated runtime available only under `/opt/paperclip-runner/bin`. **Paperclip version or commit** Discovery behavior at `54a99d884`. **Deployment mode** Docker with a remote sandbox. ## What Changed - Prefer `/opt/paperclip-runner/bin`, then the user's local bin directory, then PATH. Existing metadata and version validation remains in force. - Qualify Codex 0.153.4, OpenCode 1.18.29, and Claude SDK 0.3.263 / CLI 2.1.263. Update binary digests, TypeScript/Rust checks, registry defaults, and the displayed OpenCode version together. - Share Codex and Claude's native executable with the ACP bridges through exact dependency overrides. Preserve the separately qualified ACP bridge implementations and their security patches. - Expose shared provider-pack CLI launchers; fail the pack build if Codex ACP resolves a separate Codex installation. Update the eval image's other agent CLIs to current stable releases and remove duplicate global provider installs. - Document the single-current-CLI policy in source comments and development guidance. Latest stable releases are resolved at review/build preparation and pinned; task startup never auto-updates. ## Verification - Native-session and adapter-registry suites: 158 tests passed. - Provider suites: 88 tests passed, 7 Linux-only checks skipped on macOS. One existing macOS temporary-path alias assertion passed when rerun with canonical `TMPDIR=/private/tmp`. - Package-contract and OpenCode materialization tests: 11 passed. - Full typecheck, build, and token gates passed. Rust native-provider/recovery tests: 19 passed. - Broad local suite: 5,974 passed, 23 failed, 41 skipped. Failures are in unchanged macOS workspace/path/port and connection suites; focused runtime tests pass. All latest-head Linux PR checks passed, including the full test shards, typecheck, build, runner verification, browser suites, and canary dry run. - The standalone fleet image built with one current provider CLI each and passed native Codex/Claude binary-integrity checks. A disposable Daytona sandbox reported ready in 798 ms; its baked runner completed an API-key `gpt-5.6-luna` turn in 2,430 ms and returned the expected marker with a usage receipt. No runtime artifacts were uploaded or installed. - The normal shared `codex exec` entrypoint also completed an API-key `gpt-5.6-luna` turn in 2,321 ms. - Both image builds verify the complete generated lockfile against a reviewed SHA-256 before package installation or lifecycle execution. Root lockfile changes remain CI-owned. Merge and rollout remain on hold for operator review. ## Risks - Updating provider CLIs changes their behavior for all adapters; version probes and live native smoke testing are required before image promotion. - The image-owned directory takes precedence. Its entries must launch the same shared CLI as the global PATH, not a private older/newer copy. - Application qualification pins and the deployed image must move together. No startup fallback installation is added. - No schema or authentication-policy changes. ## Model Used OpenAI GPT-6 (Codex). The session does not expose a more specific model ID or context-window size. Used reasoning, repository inspection, code execution, and browser verification. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
932ddb7b37 |
feat: browse GitHub repository access across organizations (#12998)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub connections give agents access to approved repositories. > - One GitHub identity can use installations across several organizations. > - The permissions page linked to one installation and showed an unfiltered list. > - Users could not easily find another organization or inspect a large selection. > - This change adds account filtering, search, and access configuration links. > - Users can inspect repository access in one compact view. ## Linked Issues or Issue Description Refs #12993. Related repository-catalog work in #11228 and #11234 was checked. This change only improves the existing GitHub connection permissions page. **What existing behavior does this improve?** The GitHub connection permissions page and its repository display metadata. **Current behavior** The page links directly to an existing installation. The repository list has no account filter, search, height limit, or private-repository marker. Refresh access occupies a separate section. **Proposed behavior** Show all authorized repositories by default. Filter by account or organization and search by name. Open GitHub's account chooser to configure access across organizations. Show GitHub icons and private-repository locks. Keep refresh beside configuration and limit the visible list to about ten rows. **Reason and benefit** Users can find repositories across organizations and configure missing access without creating another GitHub identity. Large repository lists no longer fill the page. **Breaking changes** None. Repository display metadata gains an optional private flag. Older snapshots remain valid and gain the flag after access refresh. No SQL migration is required. ## What Changed - Add an All accounts view, account filter, search, and empty states. - Link both configuration controls to GitHub's app account chooser. - Place an accessible refresh icon beside the configuration button. - Keep the repository heading and list in one section. - Add GitHub icons and private-repository locks. - Cap the scrollable list at ten rows using a design token. - Persist GitHub's private flag only when the provider returns a boolean. - Recover missing legacy app configuration from GitHub installation metadata. - Update tests and the GitHub connection runbook. ## Verification - Focused tests passed: 54 permissions-page tests and four GitHub metadata tests. - UI and server typechecks passed before submission. Token gates passed. - Browser checks verified account filtering, search, empty results, and the configuration destination. - The live list contained 40 repositories. Its final height was 272 pixels, which fits ten single-line rows with gaps. Scrolling retained all rows. - A live access refresh populated 30 private-repository lock icons from GitHub metadata. - Full workspace typecheck and build passed. The broad local suite stopped in the general-server group with 18 failed files. Failures include macOS temporary-path handling and embedded PostgreSQL startup. That run also overlapped the legacy fix and retained a stale GitHub module; the final focused run passed all 58 tests. Clean-runner CI is tracked separately. - Latest-head review is 5/5 with the legacy chooser finding resolved. All CI checks passed on commit `0ff2b63f348f5c87d8b7df6e43388f60f5d872d9`, including build, typecheck, all test shards, browser tests, and canary dry run. ## Risks - Older repository snapshots lack visibility metadata until refreshed. Unknown visibility does not display a lock. - The account filter lists authorized installation owners. Users add other organizations through GitHub's chooser. - Filtering changes only the displayed list. GitHub remains authoritative for repository access. ## Model Used OpenAI GPT-6 (`gpt-6-astra`) via Codex. Reasoning, code execution, and browser tools were used. The exact context window size was not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
bac60d9d31 |
fix: preserve GitHub sign-in and show connected repository access (#12993)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - GitHub connections give agents an account with selected repository access. > - Fresh local instances enroll with production Paperclip Cloud. > - Enrollment could finish while the GitHub OAuth profile remained disabled. > - Setup then switched to a personal access token form without explanation. > - This change preserves sign-in intent and shows the connected account and repositories. ## Linked Issues or Issue Description Related: #12907, #12943, #12947. Existing open GitHub connection work was checked. No duplicate was found. **What happened?** After Cloud enrollment, a fresh test-drive asked for a GitHub key. Production did not advertise the managed GitHub profile. Staging did. The permissions page also omitted the authenticated username and repository names. **Expected behavior** Continue with GitHub OAuth when available. Explain unavailable sign-in and allow retry otherwise. Show the GitHub username and complete accessible repository list. **Steps to reproduce** Start a fresh test-drive. Choose GitHub and complete instance enrollment while the Cloud GitHub profile is disabled. Open an existing GitHub connection's permissions page. ## What Changed - Preserve managed sign-in intent when the gallery omits its profile. - Refresh the selected gallery entry on retry without resetting the audience. - Fetch all pages of GitHub installations and repositories. - Store only repository IDs, full names, and installation IDs in grant metadata. - Show the GitHub username, repository list, management link, and refresh action. - Discard the repository snapshot after newer installation lifecycle events. Preserve snapshots verified after delayed events. - Lock and re-read grant metadata when applying installation events or saving refreshed access. Patch only webhook fields for other events. Reject snapshots if access changed during the external fetch, using unique access revisions even when timestamps collide. - Show repository installation recovery for managed OAuth even when the app also offers an advanced PAT method. - Update tests and the GitHub connection runbook. No SQL migration is required. ## Verification - Local typecheck, build, and token gates passed. All latest-head CI gates passed, including the complete test matrix and browser suites. Greptile is 5/5 with no unresolved findings. - All 382 focused setup, permissions, metadata, service, and webhook tests passed across final runs. One socket-hang-up test passed on rerun with the full service suite. Final service, metadata, and webhook checks passed all 230 tests. - The broad local suite was stopped after failures. Seven workspace-runtime exposure and control-conflict failures reproduce on base commit `54a99d884`. The broad run also overlapped local iteration; final focused tests and clean-checkout CI are tracked separately. - Browser: a fresh production-backed instance completed enrollment, retried after profile enablement, reached GitHub consent, recovered from a missing installation, and completed OAuth. - Browser: the permissions page showed the authenticated username and the selected private test repository. A real `get_me` call returned the same account. Reading the selected repository passed; reading an unselected private repository failed with 404. - Browser: a second fresh instance completed enrollment and OAuth without a PAT form or unavailable state. Its username and repository list survived reload and refresh. A real get_me call on the final code returned the displayed account. ## Risks - Repository names are now stored in company-scoped grant metadata and shown with that credential. They are display data, not authorization data. - Large selections require more GitHub API calls. A failed later page rejects the refresh rather than reporting a partial list. - Older grants and webhook-invalidated snapshots require Refresh access to load the list. - Cloud profile enablement is separate deployment configuration. This PR does not change OAuth scopes or GitHub App permissions. ## Model Used OpenAI GPT-6 (`gpt-6-astra`) via Codex. Reasoning, code execution, and browser tools were used. The exact context window size was not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
ae03465ad4 |
fix(onboarding): drop the sign-in card's Cancel, and resume after Back (#12958)
The card carried a Cancel beside its instruction, directly above the step's own Back. Two ways out of one screen is one too many. Removing it was only safe if returning genuinely resumed the running session, and writing the test for that disproved the premise: coming back started a second login rather than adopting the first, which the server's per-owner lease rejects. Cancel was not duplicative — it was the only way out of a login the customer could no longer reach. The cause was the cache. The active-session read is a useQuery with no staleTime, so on the second mount it answered instantly from the first mount's cached null: isFetched was true, the resume effect concluded there was nothing to adopt, and autoStart began a new login while the refetch was still in flight. Both panels did it, and it was pre-existing on master. Both reads now refuse the cache, so the resume works and the removal is safe because of it. Removing the button also stranded the chain behind it: handleCancel in both panels, the onCancel prop on AdapterLoginPanel, and the wizard's wiring. The panel chrome's own Cancel is untouched. An abandoned login is collected on a five-minute timer (DEVICE_LOGIN_TIMEOUT_MS) with the reaper as the restart-safe backstop, and the lease is keyed on adapterType, so a source switch does not contend. Both covered by tests. |
||
|
|
856813ba3a |
fix(connections): distinguish local setup from provider handoff (#12947)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Connections give those agents access to external services. > - Connection setup first asks who may use the credential. > - Some providers need a local method selection before OAuth starts. > - The Access button said it would open GitHub even when it opened another local step. > - This pull request names the actual next action and shows the external arrow only for a provider handoff. > - Users can distinguish local setup from leaving Paperclip. ## Linked Issues or Issue Description Refs: #12943 The browser audit found a second, separate clarity problem. GitHub showed "Continue to GitHub" twice: once to open its local method selection and once to start OAuth. The first label promised the wrong action. This change fixes that label without adding or removing a setup step. ## What Changed - Use "Continue" when Access opens another local OAuth setup step. - Keep "Continue to <provider>" and the external arrow when Access starts OAuth directly. - Test GitHub defaults, pre-enrollment setup, direct Notion OAuth, and dialog behavior. - Document the two GitHub button actions. - Preserve the external-handoff arrow in the direct-OAuth Storybook fixture. ## Verification - Targeted connection tests: 114 passed. - `pnpm --filter @paperclipai/ui typecheck`: passed. - `pnpm --filter @paperclipai/ui build`: passed. - `node scripts/check-token-gates.mjs`: passed. - `git diff --check`: passed. - After the Storybook review fix: 100 connection-flow tests, UI typecheck, token gates, and Storybook build passed; visually confirmed the Gmail handoff arrow and local GitHub step labels. - Actual test-drive browser: confirmed default personal identity and Any agent; clicked Continue to the local method screen; switched PAT and OAuth; returned to Access with selections intact; cancelled without a duplicate connection. - Live OAuth, local MCP identity, and a real staging sandbox task passed during the audit. This patch does not change those paths. - Full local suite has known unrelated macOS path/runtime test failures from the audit. All CI passed on head `936ce09f4e1faaf09f9fb778c2cd4c65c2a41972`, including typecheck, build, all test shards, browser tests, and canary dry run. Greptile: 5/5; no unresolved comments. ## Risks - Low risk. This changes button text and an icon cue only. There is no new schema, permission, consent, or credential behavior. - Providers with multiple methods now say Continue before their method screen. Direct OAuth providers keep their existing wording. ## Model Used - OpenAI Codex assisted with code, tests, terminal checks, and actual browser verification. The runtime does not expose the exact model ID or context-window size, so those details are unavailable. ## 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 references) - [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 (targeted tests; full-suite caveats above) - [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> |
||
|
|
d293dd3d14 |
fix(connections): refresh expired pending enrollment links (#12943)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - Managed connections deliver credentials to an approved instance.
> - A self-hosted instance starts with a time-limited approval link.
> - The setup page cached that link and reused it after expiry.
> - This pull request lets the existing server choose a valid enrollment
link.
> - Users can recover without another setup step or a service restart.
## Linked Issues or Issue Description
Related: #12891 (one-time enrollment) and #12907 (sandbox GitHub
identity).
No duplicate open enrollment-recovery PR or issue was found.
**What happened?**
After a pending Cloud enrollment expired, Continue opened the same
expired
approval link. Cloud returned ENROLLMENT_NOT_AVAILABLE. Returning to
setup and
selecting Continue repeated the failure.
**Expected behavior**
Continue must ask the server for a valid enrollment. The server must
reuse a
live pending enrollment and replace an expired one. Existing approved
instances
must not need another approval.
**Steps to reproduce**
1. Start GitHub setup on a fresh self-hosted instance.
2. Start Cloud enrollment but leave it unapproved until the link
expires.
3. Return to step 2 and select Continue.
4. Before this change, the browser opens the expired link again.
**Paperclip version or commit**
Reproduced from master commit
|
||
|
|
05735b3d87 |
fix(ui): show continuation actions in confirmation receipts (#12939)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Task interactions let an operator approve completion or ask an agent to continue. > - The server stores the continue choice as a rejected completion request so it can resume the same task. > - The task feed ignored the configured action label and showed the generic text `Declined request`. > - The generic text made a successful three-turn continuation look like a failed request. > - This pull request keeps the server state and shows the action that the operator selected. > - The benefit is an accurate task feed for legacy Codex and Runner Codex. ## Linked Issues or Issue Description **What happened?** A rejected confirmation always appeared as `Declined request`. The feed did not use a custom rejection action such as `Continue work`. **Expected behavior** The resolved receipt and success toast must show the selected custom action. Confirmations without a custom action must keep the current fallback text. **Steps to reproduce** 1. Create a completion confirmation with `rejectLabel` set to `Continue work`. 2. Select `Continue work` and enter a continuation note. 3. Open the completed task feed. 4. Observe that the old UI says `Declined request` instead of the selected action. **Paperclip version or commit** `539c9212f4b98e37643f5a8e3b603f1b5845b5d7` **Deployment mode** GitHub Actions Runner E2E with warm Daytona sandboxes. ## What Changed - Show `Selected “Continue work”` when a rejected confirmation has that custom action label. - Use the same action-aware text in the success toast. - Keep `Declined request` as the fallback for confirmations without a custom rejection label. - Make the legacy warm-turn prompt ask if the task is ready to complete. - Require both warm Daytona matrix cells to show two continuation receipts and no generic decline receipt. ## Verification - `pnpm exec vitest run ui/src/pages/IssueDetail.test.tsx ui/src/lib/issue-thread-interactions.test.ts ui/src/components/task-chat/TaskChatInteractionCard.test.tsx` - `pnpm test:e2e:runner:unit` - `pnpm test:e2e:runner:typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm --filter @paperclipai/ui build` - `pnpm check:token-gates` - Paid `daytona-warm-continuity` campaign: both three-turn cells passed on attempt 1 ([workflow run](https://github.com/paperclipai/paperclip/actions/runs/34052047946)); the downloaded evidence aggregates locally as 2/2. The trusted report job did not publish because default branch `pnpm-lock.yaml` was transiently behind its manifest. - `pnpm typecheck` reached an unrelated `plugin-workspace-diff` dependency type error after the current master manifest and lockfile resolved different versions. The focused UI and runner checks pass. ## Risks - Low risk. The database state and continuation behavior do not change. - A custom rejection label now appears in resolved receipts and success toasts. - The paid warm Daytona suite has a stricter browser assertion. ## Model Used - OpenAI Codex, GPT-5, with reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used with version and capability details - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked existing issues or described the issue in this PR with the bug template fields - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal task identifier - [x] I have run focused tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated the relevant E2E fixture and assertions - [x] I have considered and documented the risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
539c9212f4 |
fix(onboarding): keep the pasted code on screen, and make the auto-copy real (#12921)
The Claude card cleared its field the instant the paste was submitted, so the code appeared and vanished in the same breath and the seconds that followed had no feedback at all - it read as the paste having been dropped. The code stays now; the field is disabled and the step's button carries the status. Scoped to the onboarding chrome: the panel in the agent form stays open long after its login and has its own status area, so clearing is still right there. The OpenAI card's auto-copy took its latch before the attempt rather than on success, so the first refusal was permanent - and the first attempt is the one most likely to be refused, since it fires while the card is still arriving. It also ran with an empty code on the paths where the row renders before the server's one-time prompt has a value, which wrote nothing and then said Copied! over whatever the clipboard already held. It now waits for the document to have focus, retries when focus returns, guards against a second attempt while one is in flight, and only latches once a write has actually landed. The arc's question is a quarter larger, 36px to 45px, as a token with its own leading. paperclipai/paperclip-cloud#400 moves the signup wizard's matching heading by the same quarter - the two flows are pinned to each other on purpose. |
||
|
|
0c1e7504c0 |
fix(runner): persist warm Daytona workspaces across turns (#12904)
## Thinking Path > - Daytona preserves a stopped sandbox filesystem, but deleting or replacing a sandbox removes its only remote copy. > - Warm reuse therefore improves latency but cannot be Paperclip's durability boundary. > - The host execution workspace must remain authoritative after every successful turn, while same-run recovery must avoid overwriting unexported remote work. > - Result proposal, workspace export/merge, and terminal completion need a durable, replayable ordering so a crash never starts a duplicate provider turn. > - A paid browser acceptance suite must exercise both legacy Codex and Runner Codex for three real turns on one continuously warm Daytona sandbox. ## Linked Issues or Issue Description Refs #12901. Runner Codex did not previously export successful Daytona workspace changes back to the authoritative host workspace. That made warm reuse depend on Daytona's remote filesystem and left deleted/replacement sandboxes without a reliable reconstruction path. The existing paid fixture also lacked a focused three-turn continuity case for both Codex adapters. ## What Changed - Persist versioned, atomic native workspace-sync descriptors and durable seeds in `PAPERCLIP_HOME`, without credentials or a database migration. - Classify fresh, warm, replacement, and same-run-recovery workspace preparation explicitly; ambiguous lease/root/digest evidence fails closed. - Finalize native workspace export/merge after semantic result proposal and before run completion, with idempotent replay that never submits a second provider turn. - Surface legacy Codex workspace restoration failures instead of masking them, while preserving an earlier provider error when both fail. - Keep healthy reusable Daytona leases warm for legacy and native adapters, stamp finalized workspace generations, and retain existing cleanup behavior for per-turn or unhealthy leases. - Preserve Runner Codex's provider process/session across warm turns, including bounded post-terminal tail draining and exact authority rotation. - Add the exact paid `daytona-warm-continuity` matrix: - `legacy-codex × daytona × warm-three-turn` - `runner-codex × daytona × warm-three-turn` - Drive all three turns through the browser, verify ordered file continuity and stable lease/workspace/runtime identities, capture per-turn timings, and delete the sandbox immediately after assertions. - Document `pnpm test:e2e:runner -- --suite daytona-warm-continuity`; no package script was added. ## Verification - `pnpm typecheck` — passed, including migration safety (no migration added) - Focused server/runner Vitest coverage — 144 passed - `pnpm test:e2e:runner:unit` — 114 passed - `pnpm test:e2e:runner:typecheck` — passed - `pnpm --filter @paperclipai/paperclip-runner test:codex` — 66 passed, 1 helper ignored - `native-session-executor.test.ts` — 139 passed, including safe fail-closed cleanup after remote runner identity capture failure - Paid local browser acceptance, exact post-rebase Linux/amd64 runner binary: - Runner Codex — passed in 1.7m; 3 runs; lease outcomes `created, resumed, resumed`; 10/10 matchers; cleanup passed - Legacy Codex — passed in 2.7m; 3 runs; lease outcomes `created, resumed, resumed`; 10/10 matchers; cleanup passed - [Protected paid GitHub Actions campaign](https://github.com/paperclipai/paperclip/actions/runs/34026735033) against `7da42a91b95fa7fb2df126668ef7e37afb3b2b9d` — passed 2/2: - Runner Codex — 3 runs; lease outcomes `created, resumed, resumed`; evidence and cleanup passed - Legacy Codex — 3 runs; lease outcomes `created, resumed, resumed`; evidence and cleanup passed - Merge/enforcement, S3 history, and Pages publication jobs passed - Paid result artifacts were scanned for both provider credentials; neither secret was present. - Current PR checks — 31 passed, 1 expected Storybook skip; Greptile 5/5; Superagent security scan passed - `git diff --check origin/master...HEAD` — passed - Confirmed no `package.json`, lockfile, migration, or SQL changes. ## Risks - Workspace synchronization now sits on the terminal-success path, so a remote export failure deliberately prevents false success. Retryable state retains its lease/seed; loss of the only unexported remote copy fails closed. - Warm provider reuse has strict identity and quiescence checks. Mismatched or ambiguous evidence blocks reuse rather than risking concurrent provider work. - The paid suite incurs Daytona and Codex cost only in the existing protected scheduled/manual workflow and explicitly destroys its sandbox after each cell. ## Model Used OpenAI Codex with GPT-5 agentic reasoning, repository inspection, real browser E2E execution, Rust/TypeScript test execution, and GitHub Actions diagnostics. ## 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 linked an existing issue or described the issue in-PR - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name contains no internal ticket id - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have documented the dedicated suite invocation without adding a package script - [x] I have considered and documented risks above - [x] All Paperclip CI gates are green on the current revision - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups on the current revision - [x] I will address all reviewer comments before requesting merge |
||
|
|
3796c6f259 |
fix(connections): project GitHub identity into sandbox runners (#12907)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Managed GitHub connections resolve a responsible user's or dedicated agent's identity into an audited, run-scoped credential projection. > - An enrolled instance could retain a hidden managed setup method after Cloud stopped advertising it, producing a blank, disabled setup step. > - Native runner processes also dropped the resolved GitHub projection before the provider shell, so `gh` and Git could not use the selected identity in Daytona. > - Daytona already provides the outer isolation boundary. Applying Codex's inner Linux sandbox there both duplicated containment and failed because nested user namespaces are unavailable. > - This change repairs setup fallback, carries only the bounded GitHub projection across each runner boundary, and allows only a controller-selected managed sandbox transport to act as the outer sandbox. ## Linked Issues or Issue Description **What happened?** An enrolled self-hosted instance could show a blank GitHub setup step when its managed profile was unavailable. Separately, a native Codex run in Daytona could resolve a managed GitHub connection on the Paperclip host but lose it before the provider shell. Once projected, Codex's nested sandbox failed before commands could run because Daytona does not expose the user-namespace operation used by the inner sandbox. **Expected behavior** Setup must select an advertised customer method when the managed method is unavailable. A Daytona run must receive the exact managed GitHub identity selected for that run, support `gh` and HTTPS Git, and rely on Daytona as its outer sandbox without weakening local or SSH execution. **Steps to reproduce** 1. Enroll a self-hosted instance while Cloud does not advertise the managed GitHub profile and open GitHub setup. 2. Observe the blank second step and disabled action. 3. Configure a native Codex agent with a Daytona environment and a responsible-user GitHub grant. 4. Run `gh api user` or HTTPS Git from the agent shell. 5. Observe missing GitHub environment projection or nested-sandbox startup failure. **Paperclip version or commit** The setup bug reproduces on `1dceee9a4`; the runner proof was developed from the same branch and verified at the latest head below. **Deployment mode** Self-hosted Paperclip enrolled with Paperclip Cloud, using the Daytona sandbox-provider plugin and native Paperclip runner. ## What Changed - Wait for connector enrollment hydration, retain a hidden managed method only while enrollment is needed, and otherwise select an advertised customer fallback. - Add a single bounded GitHub credential-environment projection for `GH_TOKEN`, `GITHUB_TOKEN`, the process-only Git helper token, GitHub commit identity, and at most 32 controller-generated Git config entries. - Forward that projection through the durable controller, Codex app-server transport, and Rust provider child without placing token values in arguments or config. - Allow Codex shell inheritance only for the exact projected GitHub keys and enable provider network access only when the managed credential exists. - Derive outer-sandbox authority exclusively from a managed `sandbox` transport; strip the same flag from configured, host, local, and SSH environments. - Define a named external-sandbox permission profile that Codex resolves to `dangerFullAccess` for default-mode Daytona turns while plan mode remains read-only. - Add regression tests for setup fallback, credential projection, local/SSH/sandbox authority separation, provider forwarding, and permission-profile selection. ## Verification - `pnpm exec vitest run ui/src/pages/apps/AppsConnect.test.tsx` — 96 passed. - `pnpm exec vitest run src/drivers/codex/codex-security-config.test.ts src/drivers/codex/app-server-transport.test.ts src/control-plane/durable-prp-control-plane.test.ts` from `packages/paperclip-runner` — 31 passed. - Focused native-session executor tests — 3 passed. - `pnpm --filter @paperclipai/paperclip-runner typecheck` — passed. - `pnpm --filter @paperclipai/server typecheck` — passed. - `cargo test --manifest-path packages/paperclip-runner/runner/Cargo.toml --locked -p paperclip-runner-core --lib` — 194 passed. - Real Codex app-server configuration probe accepted `paperclip-runner-external-sandbox` and reported `sandbox.type=\"dangerFullAccess\"` while using the named profile. - [Signed Daytona image workflow](https://github.com/paperclipai/paperclip/actions/runs/33995270328) built commit `86571f7997e7100e47bd131aac1f1e773112a0ce`; the isolated environment was pinned to `sha256:ecef21105f8de382d75787e59439d936be239b77ae74a31c8ed3a17cde39b023`. - Live isolated Daytona proof passed: the three projected token variables were non-empty and equal; the host-scoped Git credential helper returned the same token without printing it; `gh api user` resolved `cryppadotta`; authenticated `git ls-remote https://github.com/paperclipai/paperclip.git HEAD` returned `1dceee9a4e75b13456760bb54c752deb2dba1d79`; no repository mutation occurred. - The persisted 28,476-byte run log contains no GitHub token shape, bearer header, credential-bearing URL, or private-key marker. - Latest-head pull-request CI and reviews provide the remaining full-suite gate. ## Risks - This deliberately gives shell Git and `gh` access to the run's resolved GitHub identity. It is the audited class-3 behavior required by the GitHub connection design and is outside per-tool Ask-first controls. - The credential source is the trusted broker projection, which overwrites configured environment values. The helper is scoped to HTTPS `github.com`, revalidates protocol and host, and never places its token in command arguments, URLs, or files. - Managed Daytona sandboxes become the containment boundary for default-mode provider commands. Local and SSH targets retain the inner Codex workspace sandbox, and plan mode remains read-only everywhere. > 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, with reasoning, browser control, shell access, and code execution. The product did not expose the context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
be407f3456 |
fix(onboarding): hide the probe's diagnostics while the hire is in flight (#12902)
After a successful sign-in, a block of amber diagnostics flashed up and vanished as the step advanced. They are the identity and target INFO checks every environment test reports: they make the result a warn without blocking anything, and the step rendered any non-pass result, so they owned the screen for the window between the probe returning and setStep(5). Gated on loading rather than the connect phase. A blocking result stops the hire and handleGiveHeartbeat clears loading in the finally after its early return, so a genuine block still shows its checks while a hire in flight shows none. The button needed no change: step 4 forces the footer's loading to false and takes its label from connectCta, which reads Connecting for that whole window. |
||
|
|
60469a08e0 |
feat(agent-login): resume an active login session and permit concurrent login terminals (#12861)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Agent authentication uses server sessions, plugin workers, and browser login panels. > - A page reload loses an active login session, and one worker permits only one login terminal. > - These limits cause lost work and prevent two owners from logging in through one worker. > - This pull request lets the browser resume active sessions and lets workers serve concurrent login terminals. > - The benefit is reliable login recovery with a bounded process-wide route limit. ## Linked Issues or Issue Description **What existing behavior does this improve?** It improves agent credential login recovery and concurrent login terminal handling. **Subsystem affected** Cross-cutting (multiple of the above). **Current behavior** A page reload loses the active login session. A shared plugin worker rejects a second login terminal. **Proposed behavior** The browser reads and resumes the owner's active session. A worker supports multiple login terminal routes under a process-wide ceiling. **Reason and benefit** Owners keep login progress after a reload. Two owners can log in through one worker without removing the route limit. **Breaking changes** None. The change adds owner-scoped read routes and changes login terminal concurrency. ## What Changed - Replace the single worker login route with maps keyed by host route and worker session identifiers. - Add a process-wide login route ceiling and release each reserved slot on every exit path. - Add owner-scoped active-session reads with consistent negative responses and private cache control. - Keep the device-login prompt while the session has an active public status. - Add a durable setup-token cancel fallback for a lost in-memory session. - Resume active sessions when the agent configuration or onboarding panel mounts. - Remove routine unmount cancellation and keep explicit Cancel behavior. ## Verification - `pnpm --filter @paperclip/server test` — server route, service, and plugin-worker-manager suites. - `pnpm --filter @paperclip/plugin-sdk test` — worker RPC host suite. - `cd ui && npx vitest run src/components/AgentConfigForm.render.test.tsx src/components/OnboardingWizard.test.tsx`. - `cd ui && npx tsc -b`. - `tests/e2e/onboarding.spec.ts` — reload during login. - CI must pass on this pull request. ## Risks The change affects agent authentication and the sandbox-to-host boundary. Route cleanup must release every reserved slot. Owner checks must prevent cross-owner session access. Tests cover route cleanup, owner scope, reload recovery, and concurrent worker routes. ## Model Used Codex, OpenAI GPT-5, tool use and code review support. The implementation author owns the exact model details for the code changes. ## 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 described the issue in-PR with the relevant issue-template fields - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented 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> |
||
|
|
ca9c17df60 |
test(ui): flush passive effects with React act in CompanySkills tests (#12878)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work.
> - The user interface tests verify company skill installation flows.
> - The install-preview dialog sets state through passive React effects.
> - The local test helper flushed render work but did not flush passive
effects.
> - Timer hops did not guarantee that React completed those effects
before user actions.
> - This pull request delegates the helper to React act and removes the
timer hops.
> - The benefit is deterministic CompanySkills tests without a
product-code change.
## Linked Issues or Issue Description
**What happened?**
The CompanySkills install-preview dialog tests used a timer hop after
opening the dialog. The timer could run before React completed passive
effects. A later click then used stale dialog state.
**Expected behavior**
The test helper must flush passive effects before the test interacts
with the dialog. The tests must pass without a race between timer
callbacks and React scheduler tasks.
**Steps to reproduce**
1. Run the CompanySkills test file many times from the ui directory.
2. Observe intermittent failures that report an empty agent list or a
null slug.
3. Run the same tests with React act to flush passive effects.
**Paperclip version or commit**
Commit
|
||
|
|
342c01fee8 |
fix(connections): simplify GitHub access details (#12893)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Connections show the identity and access that agents use > - The GitHub permissions page showed several operational fields in one large status card > - That card made the repository actions harder to scan > - A dedicated GitHub identity also named its agent without linking to the agent > - The permanent shell Git warning also competed with the controls it explained > - This pull request replaces the card with two compact action rows, links the agent label, and reveals the warning only when an action permission is changed > - The benefit is a shorter page with direct navigation to the controls that matter ## Linked Issues or Issue Description Related: #12891 **What existing behavior does this improve?** The GitHub connection permissions view. **Subsystem affected** `ui/` — React and Vite board UI. **Current behavior** The view shows installation, token, webhook, event, and refresh metadata in a large card. The dedicated-agent text is not interactive, and a shell Git warning is always visible even before the user interacts with action permissions. **Proposed behavior** Show one repository-management row and one access-refresh row. Link the dedicated-agent text to that agent. Hide the shell Git warning until the user changes an action permission, then show it in the Actions section. **Reason and benefit** The two actions are easier to find. Users can open the dedicated agent directly, and see the shell Git limitation at the moment it becomes relevant. **Breaking changes** None. This change removes secondary display fields from this view. It does not change GitHub credentials, grants, or API data. ## What Changed - Replaced the GitHub status card with repository and refresh rows. - Kept the token-backed all-repositories warning inside the repository row. - Added explicit labels for selected, all, mixed, and empty repository access. - Added a direct link from “Used only by” to the dedicated agent. - Moved the shell Git/`gh` warning into the Actions section and reveal it only after a permission-change attempt. - Added render coverage for the rows, removed fields, links, actions, and contextual warning. ## Verification - `pnpm exec vitest run ui/src/pages/apps/AppDetail.test.tsx` — 50 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm --filter @paperclipai/ui build` — passed. - `pnpm check:token-gates` — passed. - Verified the live page initially hides the shell warning, then shows it after changing an action permission; restored the test permission afterward. ## Risks Low risk. This is a display-only change. The existing management URL, refresh action, and action-permission mutations are unchanged. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5.6-sol`, extended reasoning, tool use, code execution, browser control, and multi-file repository editing. The context window size was not provided. ## 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> |
||
|
|
5da6499860 |
fix(connections): reuse one-time cloud enrollment (#12891)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Managed connections let agents use provider credentials without exposing those credentials to the control plane UI > - A self-hosted instance must first establish a trusted credential destination with Paperclip Cloud > - The GitHub connection flow repeated that trust decision before provider consent > - The local setup route also lost step 2 after enrollment and could display the PAT identity defaults before enrollment > - This pull request makes enrollment a one-time instance decision and sends later provider starts directly to provider consent > - The benefit is a shorter flow with one clear Paperclip approval and no required service restart ## Linked Issues or Issue Description Refs #12843. Companion Cloud change: [paperclipai/paperclip-cloud#391](https://github.com/paperclipai/paperclip-cloud/pull/391). ## What Changed - Made `stage=setup` authoritative during initial route hydration and enrollment return. - Added a contained one-time enrollment screen with provider-specific copy. - Accepted a provider `authorizationUrl` from Paperclip Cloud only when it matches the exact GitHub or Google OAuth endpoint. - Preferred the direct provider URL while retaining the legacy confirmation URL fallback. - Preserved the company-bound identity and agent-access draft across the full-page enrollment callback, including cold company-context hydration. - Kept GitHub defaulted to “My GitHub account” and “Any agent,” including before Cloud advertises the managed method. - Updated GitHub identity and agent-access copy for responsible-person and dedicated-agent behavior. - Labeled the provider action “Continue to GitHub.” - Added parser, routing, cold-hydration, access-restoration, visibility, fallback, defaults, and copy tests. ## Verification - `pnpm exec vitest run server/src/services/paperclip-cloud-connector.test.ts ui/src/pages/apps/AppsConnect.test.tsx` (114 tests passed) - `pnpm check:token-gates` - `pnpm -r typecheck` - `pnpm build` - Live browser proof used a new data directory on `127.0.0.1:3117` and the exact Cloud PR revision on staging. - The fresh flow selected “My GitHub account” and “Any agent,” showed one enrollment approval, returned to local step 2, and connected GitHub without a second Paperclip confirmation or login. - The connected screen showed one selected repository, a long-lived token, installation metadata, a successful access refresh, and healthy webhook delivery. - Gmail on the same instance went directly to Google consent without another Paperclip approval. - Restarting the same data directory preserved enrollment. A second new data directory required exactly one new approval. - A final fresh-data-dir rerun selected a dedicated GitHub identity for Ada before enrollment, approved the instance once, returned to step 2, retained Ada after a Back check, connected directly through GitHub, and finished with “Used only by Ada,” one selected repository, and a long-lived token. - Port 3100 remained untouched throughout the proof. ## Risks - The new Cloud field is additive and restricted to the exact GitHub and Google OAuth origins and paths, with no embedded credentials or URL fragment. - An older Cloud response still works through `confirmationUrl`. - A self-hosted instance still requires one signed Cloud enrollment. Managed Cloud instances do not render the enrollment screen. - Provider authentication and consent remain mandatory after instance enrollment. - No schema migration is included in this pull request. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5.6-sol`, extended reasoning, tool use, code execution, browser control, and multi-file repository editing. The context window size was not provided. ## 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 |
||
|
|
a7ed22e3dd |
refactor(onboarding): reconcile the arc column's width comment with its width (#12875)
The shell carried two comments arguing opposite things: the older made the case for a 64px inset and said 40px was too wide, the newer made the case for the 40px the code uses. The older one had also drifted from the code independently - it described 68px sides and a 424px column while the file used --sz-64px, a 432px column. One comment now: 40px sides, a 480px column, the measure the connect sequence is drawn to and which the arc shares. The earlier objection is kept and marked untested, with a note that if step 1 or step 3 reads loose the fix belongs in those steps' content rather than the shared shell. Comment-only; no behaviour change. |
||
|
|
f2349990cc |
feat(onboarding): the connect step's sign-in as one continuous sequence (#12863)
Picking a source starts the sign-in: the row collapses to the answer, the card opens where the credential link was, and the footer button walks Sign in -> Waiting for code -> Connecting before the step advances. Back unwinds it a beat at a time. Nothing mounts to change layout - the card and the link are always rendered and their heights animate, with inert holding the a11y line - because a mount changes the page in one frame and no easing can smooth a step already taken. Review fixes in the same branch: the displayed-code panel now reports its prompt upward (the OpenAI path could not leave the loading beat without it), the two-second hold is a cancellable beat rather than a dropped timer, unwinding a sequence that never opened a card no longer starts a login to cancel it, and the key field regains focus-on-open. |
||
|
|
5b56d430e9 |
feat(ui): refine core navigation and task detail (#12854)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The main navigation and task detail view are core operator surfaces. > - Several controls used different hover states, popover layouts, and spacing rules. > - Recent task actions also needed a compact menu and correct inbox archive behavior. > - These differences made the interface feel inconsistent and caused some content to look crowded or clipped. > - This pull request aligns these surfaces with the Paperclip design tokens and current interaction patterns. > - The benefit is a simpler and more consistent operator experience in light and dark modes. ## Linked Issues or Issue Description **What happened?** Profile and organization popovers used inconsistent layouts. Navigation controls used different hover and selected backgrounds. Task warnings and the composer could crowd nearby content. Archiving a recent task could also remove it from more than the inbox. **Expected behavior** Popover menus should use the same compact visual language. Navigation controls should share readable hover and selected tokens. Task detail content should keep consistent spacing. Archiving should hide a task from the inbox while keeping it in the task list. **Steps to reproduce** 1. Open the main sidebar in light or dark mode. 2. Open the profile and organization menus. 3. Hover navigation items, the organization trigger, the profile trigger, and the feedback flag. 4. Open a task with a warning banner and a long thread. 5. Use the recent task overflow menu and archive a task. **Paperclip version or commit** Reproduced on `master` before this branch. **Deployment mode** Local dev (`pnpm dev`). ## What Changed - Rebuilt the profile and organization popovers with compact token-based layouts. - Matched organization popover width and alignment to the profile popover. - Unified sidebar hover and selected states in light and dark modes. - Added a recent task overflow menu with rename, archive, and pause or restart actions. - Kept archived tasks in the task list while removing them from the inbox. - Improved warning banner and composer spacing in task detail views. - Added and updated focused UI tests for the changed behavior. ## Verification - `pnpm check:token-gates` passed. - `pnpm --filter @paperclipai/ui typecheck` passed. - The seven affected UI test files passed with 216 tests. - `pnpm --filter @paperclipai/ui build` passed. - GitHub CI passed the full build, typecheck and release registry, general test, serialized server, canary dry-run, and end-to-end matrices. - Greptile reviewed commit `6e296be85` at 5/5 with no outstanding actionable findings. ## Risks - Risk is limited to sidebar presentation, recent task actions, and task detail layout. - The recent task archive action now follows inbox-only archive semantics. - No database schema or public API contract changed. > I checked [`ROADMAP.md`](ROADMAP.md). This pull request does not duplicate planned core work. ## Model Used - OpenAI Codex, GPT-5.6. The model used high reasoning, tool use, and code execution. The context window size was not exposed. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Scott Tong <scott@scottsmbpm5max.lan> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
0ffc091473 |
feat(connections): add durable GitHub identities and webhooks (#12843)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents need source control access for repository work > - A shared token cannot preserve the responsible person's identity or an agent's dedicated identity > - GitHub App tokens also need durable refresh, repository access checks, and webhook delivery > - Paperclip already has managed connections, encrypted grants, run secret leases, and merge-confirmation behavior > - This pull request extends those systems with GitHub identities instead of adding a parallel credential system > - The benefit is durable GitHub access with explicit identity, repository, runtime, and webhook boundaries ## Linked Issues or Issue Description No public GitHub issue describes this connection change. This description follows the feature request template. **Subsystem affected** Connected Apps, connection grants, secret resolution, native Git runtime setup, webhook processing, and the Apps UI. **Problem or motivation** Users need to connect GitHub once and let agents use the correct GitHub identity. A run should use a dedicated agent account when one exists. Otherwise, it should use the responsible person's account. The connection must survive token expiry, repository access changes, and temporary instance downtime. **Proposed solution** Add user-owned and agent-owned GitHub grants to the existing connection model. Resolve one identity for MCP, Git, `gh`, health checks, and webhook bindings. Store provider tokens in the existing encrypted secret system. Refresh expiring token pairs under the existing lease and compare-and-swap path. Register signed Cloud webhook bindings and process normalized pull request and installation events through a durable local inbox. **Alternatives considered** An organization-wide GitHub token would lose person and agent attribution. Environment variables alone would bypass the managed connection and grant model. A new GitHub-only credential store would duplicate the existing secret and access systems. GitHub App installation tokens and private-key custody remain outside this first version. **Roadmap alignment** This change implements the Connected Apps direction. It also extends the shipped MCP Tool Gateway, per-agent secret access, and action-attribution systems. It does not add a repository catalog. The open repository catalog work in [#11234](https://github.com/paperclipai/paperclip/pull/11234) is related and complementary. ## What Changed - Added agent-owned connection grants and a per-agent credential policy with company and subject constraints. - Added a managed GitHub App method while keeping the personal access token method as an advanced fallback. - Added durable access-token and refresh-token handling with proactive rotation and one automatic recovery after a provider `401`. - Added GitHub identity and installation summaries without storing repository-name lists. - Added signed Cloud webhook binding, event lease, acknowledgement, local idempotency, pull request merge processing, and installation access handling. - Added one identity resolver for MCP, native Git, `gh`, checkout, health checks, and webhook bindings. - Added a class-3 run projection for `GH_TOKEN`, `GITHUB_TOKEN`, a `github.com`-only credential helper, SSH-to-HTTPS rewrite, and GitHub noreply commit attribution. - Added personal and dedicated-agent setup choices plus identity, repository, continuity, and webhook status in the Apps UI. - Added schema migrations, tests, and connection documentation. ## Verification - The current head is fully green in GitHub CI, including build, typecheck, all serialized/general server shards, all browser shards, policy, canary dry run, review, and security checks. - Live staging proof completed with a non-expiring GitHub App user token, selected-repository installation, repository add/remove refresh, managed MCP, native `gh`, HTTPS clone/push/delete, GitHub noreply commit attribution, signed merged-PR webhook acceptance, durable Cloud-to-instance delivery, and installation-access event processing. Temporary branches and temporary repository access were removed afterward. - `pnpm check:token-gates` passed. - `pnpm -r typecheck` passed before and after the rebase onto `origin/master`. - `pnpm build` passed. - The focused connector suite passed 285 tests after the rebase. - The full stable suite passed 5,790 tests and failed 22 tests across 8 general server files. The failures reproduced as shared-runner environment issues. They included `/tmp` versus `/private/tmp`, closed database connections, and invalid high ephemeral ports. The focused connection tests pass in isolation. ## Risks - Migrations add agent grant subjects and a durable connection-event inbox. Migration numbering and safety checks pass. - A raw GitHub user token enters the agent process for Git and `gh`. Per-tool Ask-first controls cannot limit those shell operations. The UI warns users about this boundary. - GitHub App user tokens can be non-expiring. Paperclip performs a continuity check every 30 days, but provider revocation still requires a reconnect. - The webhook path accepts only signed and bounded payloads. It stores a minimal normalized record and no raw provider payload. - GitHub repository permissions remain authoritative. Removed access can make a cached repository count temporarily stale, but runtime access fails immediately. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex, `gpt-5.6-sol`, extended reasoning, tool use, code execution, browser control, and multi-file repository editing. The context window size was not provided. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [ ] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [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> |
||
|
|
77312ee2d9 |
feat(codex): add GPT-6 Astra support (#12851)
## Thinking Path > - Paperclip is the open source app that people use to manage AI agents for work. > - The Codex local adapter supplies model metadata to the server and the user interface. > - OpenAI now lists `gpt-6-astra` as a supported Codex model. > - Paperclip did not list this model or its model-specific controls. > - This pull request adds the model through the existing adapter metadata path. > - The benefit is that agents and task overrides can use the exact model ID and supported controls. ## Linked Issues or Issue Description **Subsystem affected** `packages/adapters` and `ui` **Problem or motivation** Paperclip does not expose `gpt-6-astra` in Codex model selectors. Operators cannot select and save the model through the normal agent and task forms. **Proposed solution** Register the exact model ID in the Codex local adapter. Use the adapter as the source for the model-specific reasoning options. Preserve the current default model. Forward the saved model, reasoning effort, and fast-mode controls through both Codex execution lanes. **Alternatives considered** A user-interface-only model list would duplicate adapter metadata. A model alias would not match the official model ID. Both options were rejected. **Roadmap alignment** This is a small adapter compatibility update. It does not duplicate a planned item in `ROADMAP.md`. ## What Changed - Added `gpt-6-astra` to the Codex local adapter model registry and fast-mode support list. - Added the official Astra reasoning efforts: `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`. - Used the adapter metadata in agent and task model selectors. - Preserved supported effort choices when the model changes. Cleared an effort only when the new model does not support it. - Added tests for registration, user-interface selection, configuration persistence, and CLI and ACP forwarding. ## Verification - `pnpm exec vitest run packages/adapters/codex-local/src/index.test.ts packages/adapters/codex-local/src/server/acp.test.ts packages/adapters/codex-local/src/server/codex-args.test.ts packages/adapters/codex-local/src/ui/build-config.test.ts ui/src/lib/codex-reasoning-effort.test.ts ui/src/components/AgentConfigForm.render.test.tsx ui/src/components/IssueProperties.test.tsx ui/src/components/NewIssueDialog.test.tsx ui/src/lib/issue-assignee-overrides.test.ts` passed 245 tests. - `pnpm -r typecheck` passed. - `pnpm check:token-gates` passed all four gates across 939 files. - `pnpm --filter @paperclipai/ui build` passed and supplied isolated user-interface build proof. - `pnpm build` passed. - `pnpm test:run` passed 5,812 tests and failed 24 workspace-runtime tests in this isolated host. The failures use invalid generated ports above 65,535, incomplete nested-worktree fixture configuration, or `/tmp` path aliases. The focused tests for this change all pass. GitHub CI must pass before review handoff. - GitHub CI run `33918372718` passed all required checks and the aggregate verify gate on exact head `6ac6be2cee0a5996c82bdf674fcb7f46cb4c5fde`. - Independent engineering review approved the exact remediation head after 170/170 reviewer tests passed. - Greptile reported 5/5 with no open review threads on exact head `6ac6be2cee0a5996c82bdf674fcb7f46cb4c5fde`. - The model ID and capabilities were checked against the [official OpenAI Codex model list](https://developers.openai.com/codex/models). ## Risks - Low risk. The change adds one model and model-specific selector options. It does not change the default model. - OpenAI can change model capabilities later. The adapter metadata must stay aligned with the official Codex metadata. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used - OpenAI Codex with model ID `gpt-5.6-sol`, a 272,000-token context window, reasoning, tool use, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
bf95a7eae2 |
fix(ui): stabilize active-run steering queue (#12834)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The issue detail page shows a live agent run and accepts follow-up instructions. > - A follow-up must stay in a stable queue until the user sends, reorders, or removes it. > - Native runners can receive a steering event in the active run. > - Legacy runners must interrupt the active run and start a follow-up run. > - The current UI moved comments between the queue and the transcript and could show duplicate text or ambiguous chronology. > - This pull request makes the queue projection durable, keeps each message in one clear place, and labels when queued input was actually steered or delivered. > - The benefit is predictable steering with stable ordering, no duplicate messages, and visible causal timing. ## Linked Issues or Issue Description Refs #11374. Refs #12591. **What happened?** During an active run, a new follow-up could first appear as a transcript bubble and then move into the steering queue. After a steer or remove action, it could appear again. Progress text could also repeat the final response text. Once consumed, a queued bubble displayed only its original submission time even though it moved to its later causal slot, and a native run split by steering looked like two unrelated runs. **Expected behavior** An active-run follow-up must appear in the queue immediately. A native steer must move it once into the active run. A legacy interrupt must move it once into the follow-up run. A removed item must stay removed. Progress text that is identical to the final response must appear once. Consumed follow-ups must show both queue and steer/delivery times, and post-steer native segments must identify themselves as continuations of the same run. **Steps to reproduce** 1. Start a long-running task. 2. Send two or more follow-up messages while the agent is active. 3. Reorder the messages and remove one message. 4. Send the first queued message as steering. 5. Observe the queue and transcript during and after both runs. **Paperclip version or commit** The problem reproduced on commit `da1e40302`. **Deployment mode** Local development with the embedded database. ## What Changed - Project queued comments into the steering well for native and legacy live runners. - Send native steering to the active run and use interrupt-and-follow-up for legacy runners. - Keep optimistic queue order stable across refreshes and roll back failed actions. - Remove discarded comments from the transcript cache and keep them removed when the queue becomes empty. - Collapse only the final progress occurrence matching the durable response, including across steered transcript segments. - Show `Queued … · Steered …` for same-run input and `Queued … · Delivered …` for successor-run input at their causal positions. - Label settled and live post-steer segments `Continued after steering` and time them from the steer boundary. - Add regression tests for queue display, steering, fallback interrupt, reorder, remove, rollback, duplicate text, causal timestamps, and live/settled continuation headers. ## Verification - Ran the final focused steering/chronology UI suite with 233 passing tests. - Ran the activity-service regression suite with 5 passing tests. - Ran the broader queue-focused UI suite with 298 passing tests before the final chronology refinement. - Ran `pnpm -r typecheck` successfully. - Ran `pnpm build` successfully. - Ran `pnpm check:token-gates` successfully. - Tested native steering in a real browser with a 90-second baseline wait and a three-second steering correction. - Confirmed that the old final response did not appear before the steered response. - Tested three queued messages in a real browser. - Confirmed that reorder changed delivery order and that the removed message was never sent or shown again. - Tested a legacy runner in a real browser. - Confirmed that it used the interrupt fallback and showed the follow-up once. - Reloaded a saved mixed-steer/successor-run thread and confirmed the causal timestamps and continuation header render in the correct positions. - The complete macOS suite reaches five unrelated platform assertions in workspace-runtime tests. Two compare `/var` with `/private/var`. Three require Linux `/proc` listener data. GitHub Actions provides the authoritative Linux run. ## Risks - Low risk. The change is limited to issue-chat queue projection and transcript presentation. - The server run-history API adds only a read-only `contextIssueId` projection; the database schema does not change. - Optimistic actions restore the prior UI state when a request fails. ## Model Used - OpenAI Codex with GPT-5, extended reasoning, browser automation, shell tools, and code execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
af3023f1e3 |
fix(runner): repair paid provider startup paths (#12769)
## Thinking Path > - Paperclip manages AI agents that perform work. > - Paperclip Runner connects durable task runs to local provider processes. > - The full-stack paid matrix exposed failures after the runner integrity repair. > - Verified JavaScript entrypoints lost their relative module graph when Linux executed them through descriptor paths. > - Returned provider startup errors also remained pending and became indeterminate after recovery. > - Sparse Codex tool lifecycle events lost the `write_document` identity before task transcript projection. > - This pull request repairs those three boundaries and makes the structured-question fixture deterministic. > - The benefit is repeatable provider startup, exact failure replay, and correct inline Plan placement. ## Linked Issues or Issue Description Refs #12721 and #12700. **What happened?** The paid runner matrix failed ACPX and OpenCode startup before provider session creation. The runner journal then replaced the original startup error with an indeterminate recovery result. Native Codex saved a Plan but rendered it only as a fallback card. A legacy Claude waiting reply could also echo the reserved terminal marker before the answer arrived. **Expected behavior** Verified JavaScript providers must start from immutable descriptor-backed artifacts. Returned startup failures must persist as terminal failed command results. Native tool lifecycle updates must preserve the `write_document` boundary. Pre-answer fixture output must not contain the reserved terminal marker. **Steps to reproduce** 1. Run the local provider cells in the Runner Full-Stack E2E workflow. 2. Observe ACPX and OpenCode fail during `session.open` before provider execution. 3. Observe recovery report `execution_indeterminate` instead of the original startup error. 4. Run the native Codex Plan cell and observe the fallback Plan card after the tool activity row. 5. Run the legacy Claude structured-question resume cell and observe an early marker echo in waiting prose. **Paperclip version or commit** `0f9452101740835ce0b1488a204bf48acd5bafc3` **Deployment mode** Local development with the paid GitHub Actions acceptance workflow. ## What Changed - Bundle the ACPX sidecar and OpenCode proxy as self-contained Node ESM entrypoints before hashing and verified descriptor launch. - Anchor ACPX dynamic provider package resolution at a controller-derived provider-pack root and keep that root out of the provider child environment. - Persist executor-returned startup errors as redacted durable failed command results while retaining indeterminate recovery for true process death. - Coalesce sparse native tool items by stable ID so a late `write_document` name, input, and result reach the transcript boundary once. - Forbid the structured-question fixture from spelling or announcing its reserved terminal marker before the user answers. ## Verification - Rust and TypeScript regression tests cover durable failed replay, true crash ambiguity, bundle closure, package-root derivation, environment filtering, exact Codex tool lifecycle coalescing, and prompt determinism. - Local execution is intentionally limited to formatters and static diff checks. GitHub Actions will run tests, type checks, builds, and security checks. - After ordinary CI is green, scoped paid cells will validate one ACPX launch, one OpenCode launch, native Codex Plan projection, and legacy Claude structured resume before a complete matrix rerun. - Prior failing matrix: https://github.com/paperclipai/paperclip/actions/runs/33682434315 ## Risks - Bundling changes the bytes covered by provider launch hashes. Provider-pack generation already hashes the final built files. - ACPX still loads qualified provider packages dynamically. The controller supplies a normalized package root, while existing version, digest, path, and descriptor checks remain active. - Durable `failed` is terminal. Replays return the same redacted result and do not execute the provider effect twice. > For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and discuss it in `#dev` before opening the PR. Feature PRs that overlap with planned core work may need to be redirected — check the roadmap first. See `CONTRIBUTING.md`. ## Model Used OpenAI Codex based on GPT-5 with agentic reasoning, repository inspection, code editing, Git, parallel subagents, and GitHub Actions coordination. The exact deployed snapshot and context-window size are not exposed to this task. ## 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 linked related public work or described the bug in this PR - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [ ] I have run tests locally and they pass (intentionally deferred to GitHub Actions) - [x] I have added or updated tests where applicable - [x] No documentation change is required for this runtime repair - [x] I have considered and documented the 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 |
||
|
|
27622c156a |
fix(ui): recover expired Cloud tenant sessions (#12826)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Cloud serves each tenant through a browser session and an HttpOnly cookie. > - A parked tenant tab can outlive that tenant session. > - The active SPA then receives a tenant-session 401 from its API calls and shows the internal error code. > - A page reload already enters the secure Cloud document and OIDC handoff and keeps the requested tenant route. > - This pull request detects only the two Cloud tenant-session 401 codes and starts that existing handoff once. > - The benefit is that an expired tenant session recovers without exposing tokens or showing temporary API errors. ## Linked Issues or Issue Description **What happened?** A Paperclip Cloud tenant tab can stay open after its HttpOnly tenant session expires. The next API request returns `401 tenant_session_required` or `401 tenant_session_invalid`. The SPA shows the internal error code in the full page or in sidebar data consumers. A manual page refresh clears the error. **Expected behavior** The tenant tab must enter the existing Cloud session handoff when an API request reports an expired tenant session. The handoff must keep the current route and query. The UI must not show the internal tenant-session error code. **Steps to reproduce** 1. Open a Paperclip Cloud tenant route. 2. Keep the SPA open until the tenant session expires. 3. Let the page make an API request. 4. Observe the tenant-session 401 in the page or sidebar. 5. Refresh the page and observe that the existing Cloud handoff restores the session. **Paperclip version or commit** The problem reproduces on `master` at commit `b5f862376`. **Deployment mode** Paperclip Cloud tenant deployment. ## What Changed - Added one tenant-session recovery coordinator for exact top-level Cloud error codes. - Reloaded the top-level document once and shared one pending promise across concurrent failures. - Applied recovery before normal error handling in the shared API client, auth API, and health API. - Applied the same recovery to direct audit CSV exports and provider trace downloads. - Preserved ordinary self-hosted 401 behavior and avoided automatic mutation replay. - Added tests for exact detection, concurrent failures, auth-session behavior, health bootstrap, and direct-fetch behavior. ## Verification - `pnpm exec vitest run --config vitest.config.ts src/lib/tenant-session-recovery.test.ts src/api/client.test.ts src/api/auth.test.ts src/api/health.test.ts src/api/heartbeats.test.ts src/api/audit.test.ts` from `ui/` — 30 tests passed. - `pnpm --filter @paperclipai/ui typecheck` — passed. - `pnpm check:token-gates` — passed. - `pnpm -r typecheck` — passed. - `pnpm build` — passed. - `pnpm test:run` — the changed UI tests passed, but the full local macOS run also hit existing failures in untouched server worktree and temporary-path tests. - GitHub verification — 30 checks passed, no checks failed, and the Storybook job was intentionally skipped because this PR has no visual changes. - Greptile — 5/5 on `fbba29a2f`, with no open findings. ## Risks - Low risk. Detection requires HTTP 401 and one exact top-level Cloud error code. - The recovery promise intentionally stays pending because document navigation replaces the active SPA. - If the Paperclip ID session has also expired, the existing Cloud sign-in flow remains authoritative. - This change does not modify APIs, cookies, token lifetimes, database state, or Cloud server code. > 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. The agent runtime identifies the model as GPT-5. The context-window size is not exposed. Reasoning, repository editing, shell execution, test execution, and GitHub CLI tool use were enabled. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b5f8623761 |
feat(onboarding): the API key field is the same card as the sign-in (#12820)
Flipping "Use API key instead" changed the shape of the connect step rather than its content: #12801 redrew the sign-in as a borderless 12px-radius card with 44px rows, and the key field stayed a bordered `rounded-md` box with a 28px control tucked to the right. Two visual languages in one canvas, one toggle apart. The field's own note already argued against exactly that — the two are alternatives to one question and have to read as two answers, not two kinds of thing. The reasoning held; only its target moved, and matching by restating measurements is what let it drift. It composes `OnboardingLoginCard` and the shared row input now, so there is nothing left to keep in sync. The environment variable takes the slot the sign-in cards use for their sentence, in mono, still answering what a paster cannot answer for themselves: where this step will put the key. Supporting changes: `instruction` widens to `ReactNode`, and the row input's classes move to an exported `onboardingCardInputClass`. The tests pin the sharing rather than the appearance — the two inputs carry the byte-identical class string, and the key field's shell is the same element the sign-in renders. Both fail against the old bordered box. |
||
|
|
2a5aa5e213 |
feat(ui): viewer=full document deep link opens the maximized side pane (#12812)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agents ask humans for decisions through approval cards, and a chat gateway plugin can forward those cards to Slack with an "Open task" button > - The button opens the bare task page; to read the document under approval, the reviewer must click four more times (open the side pane, open the Artifacts tab, open the artifact, maximize the pane) > - Approvals are the highest-frequency human touchpoint, so each removed click matters > - This pull request adds a `viewer=full` option to the existing `#document-<key>` deep link; the link now opens the target document and maximizes the side pane > - The benefit is one-click access from an external notification to a full-size reading surface for the document under approval ## Linked Issues or Issue Description **What existing behavior does this improve?** The issue page already supports `#document-<key>` deep links. They open the document in the side pane, but at the pane's default width. **Current behavior** An external link cannot request the maximized (full-size) document view. A reviewer who follows an approval notification must maximize the pane by hand each time. **Proposed behavior** `#document-<key>&viewer=full` opens the document and maximizes the side pane. Plan documents open in the Plan tab, maximized. Mobile keeps the full-screen sheet. Unknown `viewer` values are ignored, so old links and new links stay compatible in both directions. **Reason and benefit** Chat notifications about approvals can now land the reviewer directly on a full-size view of the document they must read. This removes four clicks from every approval review. **Breaking changes** None. The parameter is optional and additive. Links without it keep today's behavior. ## What Changed - `ui/src/lib/document-annotation-hash.ts`: parse and build an optional `viewer=full` parameter in document hashes. - `ui/src/lib/issue-document-deep-link.ts`: thread a `maximize` flag on properties-pane routes; the continuation-summary route is unchanged. - `ui/src/context/PanelContext.tsx`: add a one-shot panel maximize request (`requestPanelMaximize` / `clearPanelMaximizeRequest`). - `ui/src/components/PropertiesPanel.tsx`: the resizable panel host consumes a pending request once it is visible and laid out, then clears it. - `ui/src/pages/IssueDetail.tsx`: request the maximize on the desktop deep-link path only; mobile keeps the sheet. - Tests for all of the above. ## Verification - `cd ui && pnpm typecheck` — clean. - `cd ui && pnpm vitest run src/lib/document-annotation-hash.test.ts src/lib/issue-document-deep-link.test.ts src/components/PropertiesPanel.test.tsx` — 31/31 green. - New cases cover: `viewer` parse/build round trip, unknown values ignored, maximize routing for document and plan tabs, a pending request consumed on mount, and a request held while the panel is hidden. - Manual check: open an issue with `#document-<key>&viewer=full` in the URL; the pane opens on that document, maximized. Remove the parameter; the pane opens at its normal width. ## Risks - Low risk. The parameter is optional; no data, schema, or API changes. - The maximize request lives in React context as a one-shot flag. It is cleared on first consumption, so a stale request cannot re-maximize the pane on later navigations. - If a link carries `viewer=full` on a web build older than this change, the parameter is ignored and the document still opens. ## Model Used - Claude Fable 5 (`claude-fable-5`), Anthropic. Agentic coding session with extended thinking and tool use (file edits, shell, test runs). ## 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 - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
54dd0f4868 |
feat(agents): grant new agents hire permission by default (#12814)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Agent permissions control which agents can create or hire other agents (`canCreateAgents`) > - Today only CEO-role agents get this permission by default; every other agent starts without it > - Teams that want agents to delegate and build out their own teams must flip the toggle on each hire, and most operators want delegation to work out of the box > - This pull request makes `canCreateAgents` default to enabled for new standard-trust agents, while low-trust agents keep a disabled default > - The benefit is that agent teams can grow without per-agent permission toggling, while low-trust containment and checkout protection stay intact ## Linked Issues or Issue Description Related (not fixed by this PR): #8064 also decouples an authority from `agents:create`. **Subsystem affected** Server agent permissions (`server/src/services/agent-permissions.ts`), authorization (`server/src/services/authorization.ts`), the shared `agentPermissionsSchema` validator, and the UI trust-preset helper. **Problem or motivation** New agents cannot hire other agents unless an operator enables `canCreateAgents` on each one. Only CEO-role agents get the permission by default. This blocks delegation-by-default workflows. Operators must toggle the permission for every hire. **Proposed solution** Default `canCreateAgents` to `true` for newly created agents. Apply and persist the default at creation only. Stored rows without an explicit value stay fail-closed at read and enforcement time. Keep the default at `false` when the agent's permissions record marks it low-trust (the `low_trust_review` preset or a trust boundary). Explicit values always win. Decouple `tasks:manage_active_checkouts` from `canCreateAgents` so the default-on flag does not let a peer agent write over another agent's checked-out issue. **Alternatives considered** Granting the default only at the route layer would leave stored rows and enforcement out of sync. Keeping the checkout authority coupled to `canCreateAgents` would void the active-checkout write protection once the flag is default-on. A per-company setting adds configuration surface without a clear need; explicit per-agent overrides already exist. **Roadmap alignment** Governance and trust-preset work already separates standard-trust from low-trust agents. This change follows that line: capability by default for standard trust, containment by default for low trust. ## What Changed - `normalizeAgentPermissions` now takes a `create`/`stored` context. Creation writes get the new default: enabled unless `permissionsImplyLowTrust()` detects the low-trust review preset or a trust boundary. Stored rows without an explicit value normalize to disabled (fail-closed). The role parameter is gone. - `agentPermissionsSchema` no longer injects `canCreateAgents: false` when the field is omitted. The server-side default applies instead. - `authorization.ts` normalizes raw agent rows for `agents:create`, so enforcement matches what the API reports for legacy rows. - `tasks:manage_active_checkouts` no longer rides on `canCreateAgents`. CEO role, explicit grants, and the manager chain remain the paths. - `agents:create` is denied outright inside any resolved low-trust execution context (agent, project, issue, or run policy). The default-on flag can never reach the legacy creator allow there. - The UI trust-preset helper sets `canCreateAgents: false` when an agent is switched to the low-trust preset, instead of carrying the old value forward. - `doc/CLI.md` describes the new default for `teams install`. - Tests pin the default matrix (standard, low-trust, explicit overrides) on the server and in the UI helper. ## Verification - `cd server && npx vitest run src/__tests__/agent-permissions-service.test.ts src/__tests__/agent-permissions-routes.test.ts src/__tests__/low-trust-red-team-routes.test.ts src/__tests__/authorization-service.test.ts` — 143 tests pass. - Broader sweep: 18 suites that touch `canCreateAgents` (hire, pending-approval, teams catalog, portability, built-in agents, plugin-managed agents) pass locally. - `cd ui && npx vitest run src/lib/trust-policy-ui.test.ts src/components/TrustPresetSection.test.tsx src/pages/NewAgent.test.tsx src/pages/Agents.test.tsx` — passes. - Typecheck is clean for the changed files in `packages/shared`, `server`, and `ui`. ## Risks - Behavioral shift: agents created after this change persist `canCreateAgents: true` unless low-trust. Pre-existing agents keep their stored value. Legacy or malformed permission records without an explicit value stay fail-closed at read and enforcement time; they never gain the authority retroactively. - Low-trust runs can no longer create agents at all, even when the agent carries an explicit `canCreateAgents: true`. Before this change, that combination could hire. The red-team suite and a new authorization test pin the denial. - Narrowing: a non-CEO agent with `canCreateAgents: true` loses implicit `tasks:manage_active_checkouts`. The manager chain and explicit grants still provide it. This narrowing is deliberate; without it, the default-on flag would let any peer bypass active-checkout write protection. - No migrations. No API shape changes. Low-trust defaults are covered by the red-team regression suite. ## Model Used - Claude Fable 5 (`claude-fable-5`), Anthropic — via Claude Code CLI with extended thinking and tool use (code search, editing, local test execution). ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
c38b59484c |
fix(ui): remove the Account badge and version line from the account menu (#12818)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The web UI has a sidebar account menu that opens from the user's name in the lower left > - The menu header shows an "Account"/"Local" badge and a "Paperclip <sha>" (or "Paperclip v<version>") build line next to the user's identity > - These labels add noise to the header and repeat information that is available elsewhere: the email line already shows the sign-in state, and the opt-in "Server" debug section in the same menu shows the running commit > - This pull request removes the badge and the build line so the header shows only the user's name and email > - The benefit is a cleaner account menu that shows only identity information ## Linked Issues or Issue Description No existing issue. Related: #9637 (closed) added the source-sha rendering that this PR removes from the menu header. Description follows the enhancement template: **What existing behavior does this improve?** The sidebar account menu popover. Its header shows the user's name, an "Account" or "Local" badge, the email, and a build identifier line ("Paperclip <short sha>" with branch/commit links for source builds, or "Paperclip v<version>" for release builds). **Current behavior** The popover header mixes identity information with deployment and build metadata. The badge and the version line take space and do not help daily use. **Proposed behavior** The popover header shows only the user's name and email. Build information stays available in the "Server" section at the bottom of the same menu when the server-info debug view is enabled in experimental instance settings. **Reason and benefit** Less visual noise in a menu that users open often. No information is lost: sign-in state is clear from the email line, and the running commit remains visible through the server-info debug view. **Breaking changes** None. The `SidebarAccountMenu` components no longer accept the `serverGit` and `version` props; both call sites in the two `Layout` variants are updated in this PR. ## What Changed - `ui/src/components/SidebarAccountMenu.tsx` and `SidebarAccountMenu.production.tsx`: remove the "Account"/"Local" badge and the full version block (source-build branch/commit links and the release-version fallback); drop the now-unused `serverGit`/`version` props, the sha-parsing helper, and the `Badge` import - `ui/src/components/Layout.tsx` and `Layout.production.tsx`: stop passing the removed props at all four call sites - `ui/src/components/SidebarAccountMenu.test.tsx`: delete the source-build sha test; the sign-out test now pins that the popover contains neither "Account" nor "Paperclip v" - `ui/storybook/stories/navigation-layout.stories.tsx`: stop passing the removed `version` prop in the account-menu story ## Verification - `pnpm vitest run ui/src/components/SidebarAccountMenu.test.tsx ui/src/components/Layout.test.tsx` — 36 tests pass - `tsc --noEmit` for the `ui` package passes - Manual: open the app, click your name in the lower left. The popover header shows only name and email. ## Risks - Low risk. UI-only removal with no data or API changes. - Users who relied on the header sha to identify a source build must enable the experimental server-info debug view to see the running commit in the same menu. > 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 (Anthropic), Claude Fable 5, model ID `claude-fable-5`, extended thinking enabled, via Claude Code CLI with tool use (file edit, shell, test runner) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge |
||
|
|
1a74719309 |
feat(onboarding): the connect step signs in from its own button (#12801)
Connect starts the sign-in; the card that appears is the sign-in rather than an offer of one; success advances to Review rather than reporting itself. The two logins end in different places and the button says which: Claude submits a code back here, so it spins on "Connecting"; OpenAI finishes in another tab, so it stays a still, disabled Next until the poll lands. AdapterLoginPanel grows autoStart / onCancel / onConnected / chrome rather than a second implementation — the session start, both polls, the server deadline, the one-shot completion read and the unmount release are the parts onboarding needs unchanged. Every prop is off by default, so the agent form and the new-agent page render what they did before. Claude's code auto-submits on the paste, not on every change: isValidBrowserCode accepts any printable ASCII from one character up, so a value-driven submit fired on the first keystroke of anyone who typed. Also orders the OpenAI card and the settings displayed-code panel code-above-link, with the instruction worded to match, and releases the displayed-code session on unmount so an abandoned login stops holding the one-per-owner reservation. |