mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-06 21:05:21 +02:00
6eaf218924f0a89faf1c02eb0d6877a6c5c8a2cb
22
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6395cae072 |
fix(runner): ship provider pack in the standard Docker image (#14854)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Remote OpenCode and ACPX runs need a provider pack from the application build. > - Cloud now builds its application image from the standard production image. > - The provider pack was added only to the legacy cloud image target. > - The standard image therefore cannot supply the pack to downstream Cloud images. > - This pull request adds the pack to the production image and lets the cloud target inherit it. > - Remote runs can then use the pack that matches the application source commit. ## Linked Issues or Issue Description Refs #13827. Refs #14024. The standard production image does not include the remote provider pack. Downstream Cloud images inherit that omission. Remote OpenCode and ACPX runs fail with `runner_remote_provider_artifact_incompatible` and ask for `PAPERCLIP_RUNNER_REMOTE_PROVIDER_PACK_PATH`. ## What Changed - Build and copy the provider pack into the standard production image. - Set the pack path and check that an unprivileged user can read its artifacts and execute Node. - Let the legacy cloud target inherit the pack from production. - Add regression checks for production packaging and cloud inheritance. - Document stamped image behavior and the default pack path. ## Verification - The 12 focused Docker stamp and provider-pack reuse tests pass on commit `4a11f8d52aead55f85527c8e82c6d7f2644ce0da`. - The new packaging regression failed against the old Dockerfile and passed with the fix. - On the current commit, `pnpm build` and `pnpm -r typecheck` pass. All seven standard-image contract tests also pass. - The current-head CI build, typecheck, test, browser, and native Runner checks passed. The local full suite hit one chat-channel assertion failure; that exact test passed in isolation. The remaining local run was stopped after CI completed to avoid duplicating its full suite. An earlier run on the pre-rebase base had a heartbeat comment batching timeout; the external chat wait integration suite passed all 142 tests in isolation. - [The stamped preview image build passed](https://github.com/paperclipai/paperclip/actions/runs/36885002850/job/110446106393), including the production-stage provider pack build, copy, and unprivileged artifact readability/executable check. Publication, compatibility validation, and deployment of this exact commit to a staging QA instance passed. - Reproduced the exact missing-pack error on an existing staging image with Paperclip Runner, ACPX, and Claude in a remote Daytona computer. The legacy Claude adapter succeeds with the same account and computer. After deploying this commit, the same native task succeeded: it computed `5050` with a real remote shell command, wrote a proof file, read it back in a separate call, uploaded the file as a deliverable, and completed the task. The uploaded file contents and Done state persisted after a page reload. The run trace confirms Paperclip Runner, ACPX, and Claude. The first run took 2m 59s, including approximately 97s of remote artifact preparation. A second native run read the unchanged file from the prior run and completed successfully. Its startup took about 120s; this verifies repeated execution and file persistence, not fast provider-pack reuse. ## Risks - Stamped standard images now include the provider pack and its build cost. A pack build failure now fails the production image build. - Unstamped local builds still skip pack generation. Setting the path alone does not create a pack. - No database, provider authentication, or runner verification rules change. ## Model Used OpenAI Codex, GPT-6. The exact serving model identifier and context window are not exposed in this session. Capabilities used: repository inspection, code editing, shell verification, and browser testing. ## 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> |
||
|
|
f38b5693f6 |
fix: always enable keyboard shortcuts (#14643)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The web UI has keyboard shortcuts for the inbox, task lists, cases, and task detail, plus global shortcuts such as `c`, `/`, `?`, `[`, and `]` > - Shortcut enablement was an instance-wide General setting until #14141 moved it to a per-user preference that defaults to off > - The move did not carry the old instance value over, so every existing user lost shortcuts on upgrade and had to find a new toggle under Profile settings > - A toggle that only turns off a standard, input-safe feature costs a setting, a database column, two API routes, and a React context for little benefit > - This pull request removes both the instance setting and the personal preference and enables keyboard shortcuts for every signed-in user > - The benefit is one less thing to configure, no silent loss of shortcuts on upgrade, and less code to maintain ## Linked Issues or Issue Description Refs #14141 (the change that introduced the personal preference). **What existing behavior does this improve?** Keyboard shortcuts in the web UI stay off unless each user turns them on in Profile settings. **Subsystem affected** Web UI shortcuts, Profile settings, instance general settings, the `/api/auth/preferences` routes, and the `user` table. **Current behavior** Shortcuts default to off per user. #14141 moved the toggle from Instance settings → General to Profile settings and did not carry the old instance value over. Users who had shortcuts on lost them after the upgrade and had to find the new toggle. **Proposed behavior** Keyboard shortcuts are always enabled for every signed-in user. There is no instance setting and no personal preference. Shortcuts already ignore key presses inside text inputs and modal dialogs, so an opt-out is not needed. **Reason and benefit** Fewer settings, no silent loss of shortcuts on upgrade, and removal of a database column, two API routes, a query hook, and a React context that existed only to gate this feature. **Breaking changes** `GET` and `PATCH /api/auth/preferences` are removed. `PATCH /api/instance/settings/general` no longer accepts `keyboardShortcuts`; that schema is strict, so the key now returns 400. `instance.general.keyboardShortcuts` is no longer a valid `PAPERCLIP_HIDDEN_SETTINGS` key; the parser ignores unknown keys with a warning. ## What Changed - Removed the Keyboard shortcuts section from Profile settings, the `useUserPreferences` hook, `queryKeys.auth.preferences`, and `authApi.getPreferences` / `authApi.updatePreferences`. - Removed `GeneralSettingsContext`. The inbox, legacy inbox, task list, legacy task list, cases, and task detail pages no longer gate their key handlers. - Removed the `enabled` option from `useKeyboardShortcuts`. The app shell always registers the global shortcuts. - Removed `GET` and `PATCH /api/auth/preferences`, their OpenAPI entries, and the `currentUserPreferencesSchema` / `updateCurrentUserPreferencesSchema` validators. - Removed `keyboardShortcuts` from `InstanceGeneralSettings`, the general settings zod schema, the settings service defaults, and `HIDEABLE_GENERAL_SECTIONS`. - Added migration `0289_drop_user_keyboard_shortcuts`, which drops `user.keyboard_shortcuts`. - Updated `AGENTS.md`, `doc/SPEC.md`, `doc/SPEC-implementation.md`, and `docs/deploy/environment-variables.md`. - Parsed the stored general settings row with `instanceGeneralSettingsSchema.strip()` in the feedback vote path, so a retired key left in the row cannot reset the sharing preference to `prompt` and overwrite the stored choice. - Kept every bare global shortcut (`c`, `?`, `[`, `]`, `/`) out of open modal dialogs in `useKeyboardShortcuts`; only `/` had that guard before. - Updated the affected tests and added a Profile settings test that asserts the toggle is gone, a hook test for the modal dialog guard, and a feedback service regression test for the retired-key case. ## Verification - Typecheck passes for `@paperclipai/shared`, `@paperclipai/db` (including the migration numbering and safety checks), `@paperclipai/server`, and `ui`. - `pnpm exec vitest run server/src/__tests__/instance-settings-routes.test.ts server/src/__tests__/openapi-routes.test.ts server/src/__tests__/auth-routes.test.ts server/src/__tests__/sentry.test.ts` → 119 passed. - `pnpm exec vitest run ui/src/components/Layout.test.tsx ui/src/pages/ProfileSettings.test.tsx ui/src/pages/IssueDetail.test.tsx ui/src/pages/Inbox.test.tsx ui/src/pages/Cases.test.tsx ui/src/hooks/useKeyboardShortcuts.test.tsx ui/src/pages/Agents.test.tsx ui/src/pages/InstanceGeneralSettings.test.tsx` → 286 passed. - `pnpm exec vitest run packages/shared/src/settings-visibility.test.ts` → 16 passed. - `pnpm exec vitest run ui/src/hooks/useKeyboardShortcuts.test.tsx` → 7 passed. - `pnpm exec vitest run server/src/__tests__/feedback-service.test.ts` (embedded Postgres) → the new retired-key test passes with the fix and fails without it. - Manual: sign in with no settings changed, open the inbox, press `j` and `k` to move the selection, press `?` to open the cheatsheet. Open Settings → Profile and confirm there is no Keyboard shortcuts section. ## Risks - The migration drops a column. It uses `DROP COLUMN IF EXISTS`, and the column has no readers after this change. If you roll back to a build from before this PR after the migration has run, re-add the column first: `ALTER TABLE "user" ADD COLUMN "keyboard_shortcuts" boolean DEFAULT false NOT NULL;`. The older build's ORM selects that column when it loads users. - Any external client that still sends `keyboardShortcuts` to `PATCH /api/instance/settings/general` receives a 400. No in-repo client does. - Stored `instance_settings.general.keyboardShortcuts` values are stripped on read and ignored. - Users who never turned the toggle on now get shortcuts. The handlers skip text inputs, contenteditable regions, and modal dialogs, so typing is unaffected. ## Model Used Claude Fable 5.1 (`claude-fable-5-1`) in Claude Code, with extended thinking and tool use. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] 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 |
||
|
|
e2f1a66aa7 |
feat: support default-hidden experimental settings (#13980)
## Thinking Path > - Paperclip is the open source control plane for AI-agent companies. > - Operators can hide settings that their users must not change. > - The server shares the effective restrictions with the UI and settings API. > - An explicit list must change whenever a new experimental flag is added. > - This pull request adds a wildcard with named exceptions to the existing setting. > - Core applies the policy to its current catalog, so new flags stay hidden automatically. ## Linked Issues or Issue Description Related: #11823 introduced settings visibility. #13907 added workspace isolation visibility. I searched related PRs and issues and found no duplicate wildcard implementation. **What existing behavior does this improve?** Operator control of experimental setting visibility through `PAPERCLIP_HIDDEN_SETTINGS`. **Subsystem affected** Shared settings policy and its existing server health and mutation consumers. **Current behavior** Operators must name every hidden experimental toggle. A new Core flag can become visible until the operator updates that list. **Proposed behavior** `instance.experimental.*` hides current and future experimental toggles. Entries such as `!instance.experimental.enableEnvironments` leave named controls available. Explicit hidden keys and the hidden parent page take precedence over exceptions. **Reason and benefit** Operators can maintain a short list of allowed controls instead of a second copy of Core's full feature catalog. **Breaking changes** Existing explicit lists and unset configuration keep their behavior. The new syntax is opt-in. Older images ignore it, so operators must retain explicit restrictions until those images are upgraded. Visibility does not change feature values. ## What Changed - Expand the wildcard into concrete catalog keys in the shared parser. - Limit exceptions to known experimental controls and preserve explicit restrictions in either input order. - Test a synthetic future catalog addition, duplicate and invalid entries, API rejection, same-value echoes, and the effective health payload. - Document the syntax and the transition for deployments with mixed image versions. ## Verification - Targeted parser, future-catalog, health, and settings-route tests pass: 95 tests across four files. - `pnpm -r typecheck` passes, including Rust checks, with the installed Cargo directory on PATH. - `pnpm build` passes. - All current-head CI gates pass, including the full test shards, Rust, build, browser E2E, and canary dry run: https://github.com/paperclipai/paperclip/actions/runs/36083292578. One unchanged runtime-exposure cold-start test passed on its first retry. - The full local `pnpm test:run` did not pass on macOS/Node 25: the first server group reported 13,356 passed, 18 failed, and 99 skipped, with six failed files (including two failed suite setups). Failures were in unchanged runtime/company skill cache, chat/email connector fixtures, embedded-Postgres setup, and workspace cleanup tests. A standalone filesystem probe reproduced the read-only-directory rename permission failure. Missing connector fixture paths, database startup failures, and two integration assertions also occurred; the remaining local groups were not reached after this group failed. The corresponding CI lanes all pass. These local failures are not claimed as fixed by this PR. - Browser suites were not run because this changes the shared policy, not UI rendering or browser workflows. Health payload and route tests cover the shared UI/API contract. ## Risks A malformed exception remains hidden and is reported as unknown. Exceptions cannot override an explicit hidden toggle or parent page. Older images ignore wildcard syntax; keep their explicit list during a mixed-version rollout. No schema or feature-value changes are included. ## Model Used OpenAI GPT-6 through Codex, with reasoning, tool use, and code execution. The exact runtime 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> |
||
|
|
94a0aa7726 |
fix(ui): hide workspace isolation controls for managed hosts (#13907)
## Thinking Path > - Paperclip manages AI agents and their work. > - Workspace isolation keeps task checkouts separate. > - Managed hosts can enable isolation and hide its experimental toggles. > - Project, task, and routine forms still expose choices that override that policy. > - This pull request adds an operator visibility key for those controls. > - Workspace access stays available, and execution keeps its existing policy. ## Linked Issues or Issue Description **What existing behavior does this improve?** Operator control over workspace isolation settings in the UI. This follows the settings list cleanup in #13905. **Current behavior** Hiding the experimental isolation toggles leaves project policy editors, task selectors, routine and pipeline overrides, recovery actions, and workspace configuration visible. **Proposed behavior** Set `PAPERCLIP_HIDDEN_SETTINGS=workspaces.isolation` to hide these controls. Keep workspace navigation, status, files, and runtime access. Hide experimental toggles separately. Instances that do not set this key keep their controls. **Reason and benefit** Users on managed hosts should use the host's isolation default. A hidden form must not submit a stale draft that overrides it. ## What Changed - Add the UI-only `workspaces.isolation` key to the shared visibility registry. - Hide project workspace policy, task and subtask selectors, routine and pipeline overrides, and isolated re-issue actions. - Hide the workspace Configuration tab and redirect direct links to workspace issues. - Omit hidden new-task and routine overrides. Keep explicit task/subtask workspace launch context, saved policies, and automatic branch values for workspace routine runs. - Wait for the health visibility policy before showing controls. Keep workspace access and all execution APIs available. - Document the key and test visibility, form payloads, deep links, and unchanged workspace access. ## Verification - All 52 CI checks pass on `50cc770d33` (two expected skips). The branch is mergeable. Greptile is 5/5 with no unresolved comments. - `pnpm -r typecheck` passed. - `pnpm build` passed. - `pnpm check:token-gates` passed. - Targeted UI checks passed: 346 tests across 14 suites, including hidden project/task controls, stale task drafts, routine branch defaults, recovery actions, configuration deep links, and workspace access. - Shared settings-visibility tests passed: 11 tests. - `pnpm test:run` was run and stopped after reproducing five failures in unchanged server tests: two `chat-channels.integration` cases (linked-request provenance and direct external-chat finals) and three `company-skills-service` cases (runtime refresh, concurrent download, and explicit update). The earlier local run for #13905 showed the same failures. The full local suite is not claimed green. Targeted UI/shared checks pass. All PR CI shards, including the affected chat and skills suites, pass. - Reviewed the diff for secrets, private links, and run artifacts. ## Risks This key changes UI visibility only. It does not reject API calls or change feature values. Operators must enable isolation and its default through their existing policy mechanism. Older app versions ignore the new key until upgraded. Removing the key restores the controls. No schema changes. ## Model Used OpenAI GPT-6 (Codex), with reasoning, repository tools, and test execution. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either linked existing issues or described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket id - [x] I have run tests locally; targeted checks pass (full-suite limitation documented 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> |
||
|
|
be6f49a425 |
feat(runner): refresh shared coding harness runtimes (#13838)
## Thinking Path > - Paperclip runs agents through local adapters and the native runner. > - Both paths must use the same installed provider CLI. > - New models require current harness releases. > - The runner still pins Codex 0.153.4, Claude SDK 0.3.263, and OpenCode 1.18.29. > - Changing the image alone would fail the runner's exact version and executable checks. > - This pull request updates those dependencies, integrity checks, controller checks, and image pins together. > - Shared installations can then run the current models without a task-time download. ## Linked Issues or Issue Description Refs #13829, which updates model choices and reasoning controls. Searches found no open PR that updates these runtime pins. **Current behavior** The shared provider pack ships old CLIs. Claude Code 2.1.263 cannot run Opus 5.5, which requires 2.1.280. Remote controllers reject provider packs whose versions differ from their declared pins. **Proposed behavior** Use Codex 0.156.0, Claude Agent SDK 0.3.280 / Claude Code 2.1.280, and OpenCode 1.18.32 throughout the runner. Keep the reviewed ACP bridge patches and one shared CLI installation per provider. **Reason and benefit** Current harnesses support the new model IDs while preserving executable verification and remote provider-pack compatibility checks. ## What Changed - Update dependency overrides, the Codex ACP package patch, runtime profiles, and remote controller pins. - Verify the new Claude Linux x64 and macOS arm64/x64 executables and Codex Linux x64 executable against integrity-verified npm archives. - Refresh OpenCode version checks, fixtures, and the runner configuration label. - Refresh the eval image's Grok, Gemini, Kimi, Cursor, and GitHub CLI pins and archive hashes. Hermes remains current at 0.19.0. - Refresh the build-time lock digest from clean pnpm 9.15.4 resolution. Leave lockfile commits to repository automation. - Document model compatibility and the separation between CLI runtimes and patched ACP bridges. ## Verification - `pnpm -r typecheck` and `pnpm build` passed. - Rust workspace release tests passed. - Package/patch and OpenCode binary-materialization contract tests: 11 passed. - Real Codex 0.156.0 startup-ownership and paginated session-resume probes passed with isolated synthetic homes and no model turn. - Codex app-server `thread/start` preserved `gpt-6-sol` and `gpt-6-luna`; no `turn/start` was sent. An unauthenticated built-in catalog does not include those account-served entries. - Installed Claude integrity probes passed for `claude-opus-5-5` and `claude-fable-5-1`. - `pnpm --filter @paperclipai/paperclip-runner test:opencode:qualification` passed with the actual OpenCode 1.18.32 executable under Node 24 and Node 25. The loopback provider exercise covers health/version, session creation/read/delete, SSE, and a completed async prompt. - `pnpm check:token-gates` passed. - The targeted runner suite passed 130 tests. Three macOS failures in snapshot module lookup and OpenCode final-message selection also reproduce on the unchanged base; Linux CI will provide the platform check. - [Final Linux CI](https://github.com/paperclipai/paperclip/actions/runs/35798076399): all gates passed. Four jobs needed one retry after their CI workers received shutdown signals. The PR has 55 successful checks, two skipped checks, Greptile 5/5, and no unresolved review threads. - Changed runner configuration UI tests: 5 passed. - Full macOS `pnpm test:run` reached 13,094 passing server tests, 84 skipped, and 18 failures before the wrapper stopped. Failures involved skill-cache publication permissions, missing bundled connector skills in the worktree, and a conversation-reset timing case. The 10 cache permission failures reproduce on the unchanged base; both conversation-reset cases passed on a targeted retry. The wrapper did not reach its later workspace/serialized groups locally; Linux CI covers those groups. - The local Docker daemon did not respond, so no local Docker build was run. No billable model requests were made. ## Risks - Deploy the matching controller and provider pack together. Older controllers enforce their previous exact pins. - Current upstream CLIs can change behavior. Existing protocol tests and isolated real Codex probes cover the integration boundaries; authenticated model inference is not part of these checks. - ACP bridge package versions and executable digests stay unchanged because their executable bytes are unchanged. Only the underlying CLI/SDK dependencies move. - No schema migration. Revert the runtime and image pins together to roll back. ## Model Used OpenAI GPT-6 via Codex, with repository tools, code execution, and web research. The exact serving model ID and context window were not exposed by 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 for the changed surfaces and real-executable probes; full macOS-suite limitations are listed 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> |
||
|
|
20d26117c9 |
fix(chat): use the claimed Cloud origin for connector URLs (#13680)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Chat connectors publish callback URLs and links to the board. > - Cloud can assign a warm instance its final origin after the server starts. > - The signed runtime identity already tracks that change. > - The chat service kept a copy of the startup origin and continued to publish it. > - This pull request resolves the trusted origin when it creates each URL. > - New connector setup uses the claimed hostname without a server restart. ## Linked Issues or Issue Description **What happened?** Chat setup in a claimed warm instance used its old pool hostname in provider callbacks. Account confirmation and task links could also use the old hostname. **Expected behavior** Chat URLs follow the signed canonical origin after the claim. An explicit webhook ingress override still applies only to provider callbacks. Self-hosted URL precedence stays the same. **Steps to reproduce** 1. Construct the chat service with a pool origin. 2. Apply the Cloud claim without restarting the service. 3. Open Slack setup or create an account-linking intent. 4. Observe the startup hostname in the returned URL. **Paperclip version or commit** Reproduced on master at `9335b7db1`. **Deployment mode** Paperclip Cloud warm-instance claim. Related: #12766 introduced the signed canonical runtime identity. ## What Changed - Resolve the signed Cloud origin when building chat setup, account confirmation, and task URLs. - Use the same callback origin for Telegram registration and GitHub webhook recovery. - Preserve explicit webhook ingress and self-hosted configuration precedence. - Add regression coverage for existing and new endpoints across Slack, GitHub, Teams, and Telegram. - Document the origin precedence and the need to update callbacks already saved at a provider. ## Verification - Reproduced both new regression cases against the original code. - Full chat integration and signed Cloud identity suites: 1,015 tests passed after the production-code correction. - Five origin and ingress cases passed after review additions, including Telegram registration and GitHub webhook repair after a live claim. - Focused origin, ingress, callback, task-link safety, and tenant-isolation checks: 67 passed. - `pnpm -r typecheck` and `pnpm build` passed. Server typecheck and compilation passed again after the task-link validation correction. - A broad local `pnpm test:run` started before the correction was stopped after the final-commit CI suite passed. It is not counted as a passing local run. - Final-commit CI: 54 successful checks; two optional Storybook checks skipped. Greptile: 5/5 with all review threads resolved. - No live deployment or Slack app mutation was performed. ## Risks - Cloud chat URLs now follow the signed runtime identity. Request host headers cannot set this value. - An explicit webhook ingress override still takes precedence for callbacks. - Existing Slack app settings are external state. Operators must replace an old callback URL in Slack. - This change does not deploy the app or change gateway ingress policy. No schema migration is required. ## Model Used OpenAI Codex (GPT-6), with repository search, code execution, and automated tests. The exact model ID 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> |
||
|
|
889947c238 |
feat: add experimental native chat connectors (#13038)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - People also ask agents for work in their existing chat tools. > - Each external conversation needs one task and a current authorized source. > - Retries, Stop, and provider failures must not duplicate work or expose private data. > - The first chat PR establishes the opt-in provider and data contracts. > - This PR adds experimental channel integration and its durable control plane. > - Users can request work from connected channels and inspect delivery in Paperclip. ## Linked Issues or Issue Description Refs #13100 and #13092. This is the second of exactly two chat PRs. Foundation #13100 is merged and changed 143 files. Runner prerequisite #13092 is also merged. This PR changes 400 files against master, below the 500-file review limit. It contains no wireframe images or HTML galleries. ## What Changed - Add native Slack, GitHub, Microsoft Teams, Telegram, and Discord chat connections. Keep chat disabled unless the operator enables experimental chat connectors. Preserve the production GitHub tool connection and its normal setup path. - Bind each provider bot identity to one immutable Paperclip agent. Bind each admitted external conversation to one task. Paperclip owns tasks, runs, permissions, and audit records. - Add durable admission, per-conversation queues, questions, task controls, progress, final replies, images, files, and delivery receipts. Board comments remain internal unless explicitly sent to the channel. - Check current identity, provider reach, resource access, credentials, runtime generation, and exact source before provider effects. Keep private responses private. Never send raw reasoning, private logs, credentials, or tool arguments. - Hold uncertain sends for explicit audited resolution. Make Board Send-to-channel atomic and idempotent. Keep reconnect and setup credentials in Paperclip secret storage. - Preserve current native-runner authority across retries, lost acknowledgements, and recovery. Keep immutable input and completion contracts separate from newer user input. Receipt reconciliation cannot launch a provider. - Reconcile chat close/new ordering and provider-effect lock order. Audit resource access changes in the same transaction. Submit only the selected resource from each UI toggle so stale pages cannot undo unrelated access changes. - Drain Codex stdout before certifying process exit. Bound the drain with the existing shutdown grace. Preserve observed terminal authority without treating an undrained process as successful or reusable. - Incorporate master `018ca5da` with its ACP Stop, mobile task layout, runner packaging, and official lock changes. Preserve dedicated chat-answer continuations in both directions when ordinary queued comments are adopted after Stop. - Fence late adapter readiness behind an earlier Stop for the same run. Preserve verified cleanup for registered adapters. Handle single Stop, agent pause, duplicate Stops, and failure release without creating a false cancellation receipt. - Incorporate master's `6dd48cad4` wake-queue extraction. Preserve exact failed-chat retry authorization and lineage, retired question-source suppression, and the block on generic recovery that would discard the admitted source. Fresh deferred input retains its separate promotion path. - Incorporate master `2a05b5ed3` and its queue-admission extraction, simplified transaction ports, and separate runner CI job. Preserve exact durable receipts, actor separation, and dedicated-answer isolation through the new module. A failed receipt insert rolls back the accompanying deferred-wake merge. ## Verification Current head: `afe19299d06253cb628eb398e91d1200ea9f412a`, incorporating master `2a05b5ed3457ea33efd6895520447d1d97fe98d8`. The conflicts are resolved. This successor fixes two test-harness boundaries exposed by CI: per-case route-module preparation and actual durable-save completion before intentional runner termination. Production code and all existing test/turn deadlines are unchanged. [Exact-head Greptile review](https://github.com/paperclipai/paperclip/pull/13038#issuecomment-5587250594) is **5/5**, completed September 10 at 13:20:55 UTC, with no actionable findings or open review threads. [Fresh exact-head CI](https://github.com/paperclipai/paperclip/actions/runs/34481724341) passes **all 24 jobs**, including Build and both required aggregates. Normal exact-head guarded merge was attempted and rejected by the remaining branch approval policy: CODEOWNER review is required and no human approval is present. Normal **squash auto-merge is enabled** as of September 10 at 13:36:26 UTC. Requested CODEOWNERS have been notified; no approval bypass or self-approval was used. Earlier-head results below remain historical evidence, not qualification of this successor. - Final exact-head Linux evidence: 995/995 chat integration cases; 36/36 agent-skills routes; 35/35 runner live-session cases, including real process kill/resume; 1948 runner Vitest cases with three existing benchmark/platform guards; 870/870 API-authority cases; and 104 browser cases with four existing optional skips. Rust, conformance/replay, full repository build, typecheck, canary, all server/workspace shards, and both required aggregates pass with normal CI concurrency. Earlier failed attempts remain recorded below. - Latest test-only qualification: 141/141 route/permissions/authentication cases pass in separate cold forks, with plain server types and independent review clear. The real-runner suite passes 35/35, with plain runner types and independent review clear. A controlled premature-save acknowledgement fails as expected; matching ownership/effect/process evidence, rejected saves, real turn outcome, test abort, and pre-kill liveness are covered. No local reproduction of the original CI scheduling failure is claimed. The preceding [CI run](https://github.com/paperclipai/paperclip/actions/runs/34479680858) passes 21/24 jobs, including all 995 Linux chat cases and browser aggregate (104 passed, four existing optional skips); only Build, the skills serialized shard, and the required verification aggregate fail. Its exact-head Greptile review was 5/5. Both failed job logs are retained. - Final fixture qualification: all eight focused Discord cases and all 995 chat integration cases pass. The exact modal statement/PID is observed before taking the real connection lock; the test then proves its actual blocking relationship before mutation. Original SQL execution, provider behavior, negative assertions, and 1s/15s timeouts remain unchanged. Independent review is clear and test/production hashes remain frozen. The preceding [CI attempt](https://github.com/paperclipai/paperclip/actions/runs/34477184777) passed 22 jobs, including Build/runner, typecheck, canary, all other test shards, and browser aggregate (104 passed, four existing optional skips); the two fixture failures and failed verification aggregate remain recorded, not relabeled as a pass. - Current queue-module composition: 308/308 recovery/batching/queue/Stop tests; 995/995 full chat integration; 89/89 module tests, including real PostgreSQL receipt-insert rollback; 24/24 workflow/module-boundary tests; plain server and UI types. All four actual local process/ACP browser paths pass in 1.4 minutes. Fresh databases, no skips or retries, stable reviewed source hashes. The initial boundary failure is retained; its no-op service wrapper was removed without changing recovery context or weakening the check. An exploratory standalone test-directory typecheck fails because its new upstream transformation config is not a standalone typechecking project; standard CI/build does not invoke it, and no configuration was weakened to suppress those diagnostics. - The preceding head `e02a63d462ce5d47433b0aeb632bb6fd20aab1ba` passed [all 24 CI jobs](https://github.com/paperclipai/paperclip/actions/runs/34436462958) and exact-head Greptile review at 5/5. Required CODEOWNER review prevented its normal merge before master advanced again. - Final extracted-module composition: 307/307 recovery, batching, queue and Stop-control tests; 995/995 full chat integration; 49/49 module tests including eight PostgreSQL adapter cases; and 19/19 issue-update tests. Plain server types pass. All four actual local process/ACP browser paths pass in 1.3 minutes. Fresh databases, no skips or retries in these cohorts, frozen source hashes, and independent review clear. - The preceding head `3e4e1c1c` passes [all PR CI jobs](https://github.com/paperclipai/paperclip/actions/runs/34415826820), including Build and required `ci / verify` and `ci / e2e`. Both the original Rust failure and the previously load-sensitive lineage fixture pass with unchanged Linux concurrency. Master advanced afterward and required this reconciliation. - Final master composition: 448/448 focused UI tests, 186/186 adapter tests, 24/24 queue/control tests, and 11/11 packaging tests. Plain UI, server, shared, and adapter types pass. Token gates and diff checks pass. Independent server and UI reviews are clear. - Stop-registration regression: both real-service cases fail against exact `a95` source and pass with the fix. The full corrected recovery/control suite passes 265/265. Duplicate-owner and failed-Stop controls also pass. Plain server types pass. The readiness barrier prevents provider startup without adding an acknowledgment to an already terminal run. - Final qualification strengthens terminal-field equality and repeats both affected cases successfully on a fresh database. All four actual local process/ACP browser paths pass again in 1.3 minutes, without skips or retries. The final screenshot shows Cancelled, a paused subtree, retained input, and no error toast. - Two new actual-service regressions fail before the merge fix. They prove that queued-comment adoption could consume a dedicated chat answer or add unrelated input to that answer. The fixed four-case cohort passes, including ordinary upstream continuation and adapter Stop controls. Full recovery passes 257/257. All four actual local process/ACP Stop browser flows pass in 1.4 minutes, without skips or retries, on a fresh database. - The unchanged runner artifact was qualified with 171/171 transport tests, 870/870 API-authority tests, conformance 1/1, and replay 11/11. Six controlled reader tests prove the exit/drain repair. Its local serial Rust workspace passed 546 top-level cases plus two invoked helpers; the later passing Linux CI supplies default-concurrency evidence. - Prior exact-source full chat integration passes 995/995. Settings regressions cover concurrent stale pages, 501 destinations, pending state, rejected updates, and explicit retry. These deterministic tests do not prove live provider behavior. - Retained failed attempts and their causes are in the [qualification log](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-08-chat-queue-and-webhook-repair.md). The first merge adapter run timed out while macOS slept for 290 seconds. Its unchanged repeat passed with a temporary sleep guard. No assertion, deadline, or CI gate was weakened. Review commands include `pnpm --filter @paperclipai/server exec vitest run src/__tests__/heartbeat-process-recovery.test.ts src/__tests__/issue-queued-comments-routes.test.ts` and `pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/acp-stop-continuation.spec.ts`. Database suites require fresh disposable databases. See the [browser runbook](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-04-chat-adapters-browser-e2e-runbook.md) for provider setup and separate live acceptance steps. ## Risks - This remains experimental. Deterministic tests and bounded live evidence do not establish every provider feature, tenant, permission layout, or media shape. Teams work-tenant qualification is still open. - Failed and uncertain provider effects remain visible and can require operator action. A transport receipt does not prove recipient visibility. - Native controller and runner artifacts must remain compatible. Preserve lease ownership, terminal authority, source binding, and quarantine during future changes. - Access and audit rows commit together, but activity notifications remain best-effort. This is not a new durable event outbox. - The PR operation does not deploy a live server, replace its runner, or change provider permissions. Remaining live qualification is documented in the [temporary handoff](https://github.com/paperclipai/paperclip/blob/afe19299d06253cb628eb398e91d1200ea9f412a/doc/plans/chat-adapters/2026-09-08-open-qualification-followups.md). ## Model Used OpenAI Codex assisted with implementation, tool execution, testing, and review. The work records `gpt-6-astra` assistance. The environment does not report a context-window size. No private reasoning traces are included. ## 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> |
||
|
|
ee2a190626 |
Unify Paperclip Runner experimental controls (#12666)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner is an experimental execution adapter. > - The adapter and its required sandbox ingress had separate settings. > - A user could enable one setting and still have an unusable runner configuration. > - The runtime already makes one durable native or legacy decision for each run. > - This pull request uses that runtime decision for ingress authorization. > - The benefit is one clear opt-in with safe recovery for existing native runs. ## Linked Issues or Issue Description **What existing behavior does this improve?** This improves the experimental settings and transport authorization for Paperclip Runner. **Subsystem affected** Cross-cutting. This change affects the React settings UI, shared settings contracts, adapter utilities, and server runtime selection. **Current behavior** Settings shows separate Paperclip Runner and Runner Preview Ingress controls. A user can enable the runner but leave required sandbox ingress disabled. **Proposed behavior** Settings shows only Paperclip Runner. Its native runtime decision also authorizes provider WebSocket ingress when the execution target requires it. A persisted native run keeps its recovery transport after the setting is disabled. **Reason and benefit** Paperclip Runner is one experimental capability. One opt-in removes an invalid partial configuration and makes the rollout boundary easier to understand. **Breaking changes** The Runner Preview Ingress card is removed. The old `enableRunnerPreviewIngress` key remains accepted in stored settings and managed configuration, but it has no server runtime effect. The public adapter-utils input remains compatible through a deprecated alias. **Additional context** Refs: #12638, #12641, #12656. ## What Changed - Removed the separate Runner Preview Ingress card from Experimental Settings. - Made resolved native runtime selection authorize required provider ingress. - Preserved ingress recovery for persisted native runs after the rollout flag is disabled. - Kept the old settings key and adapter-utils input as deprecated compatibility contracts. - Added focused UI, runtime policy, transport, stored-settings, and managed-config regression tests. - Updated deployment documentation and feature descriptions. ## Verification - GitHub Actions will run typecheck, tests, build, policy, and browser shards. - Focused tests cover the single settings control, runtime authorization, fail-closed transport selection, the deprecated public input, and old managed configuration. - No local tests were run, per the maintainer request to use GitHub Actions for verification. - `git diff --check` passes. ## Risks Low to moderate risk. The effective ingress gate changes from a separate stored flag to the resolved native run decision. Fresh runs still require `enableNativeRunner`. Persisted native runs remain recoverable. Legacy adapters never receive ingress authorization. > 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, 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 - [ ] 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 |
||
|
|
0a422fda52 |
feat(runner): add remote execution substrate (#12638)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Paperclip Runner gives native runs a durable and governed execution path. > - The current native path runs on the control-plane host. > - Remote environments need an authenticated execution-target contract. > - The contract must not change direct adapters or enable new runtimes by default. > - This pull request adds the remote execution substrate and Daytona ingress. > - The benefit is a bounded base for later remote runner transport work. ## Linked Issues or Issue Description Refs #12616. Refs #12352. **Subsystem affected** Cross-cutting. This change touches runner transport, server orchestration, plugin contracts, and shared settings. **Problem or motivation** Native execution cannot resolve an authenticated runner ingress through a remote environment. The server also lacks one provider-neutral contract for remote execution targets. **Proposed solution** Add a default-off runner preview ingress capability. Add transport-neutral runner connectivity. Add remote execution target and lifecycle handling. Add a Daytona ingress implementation with redacted credentials. **Alternatives considered** A provider-specific server path would duplicate orchestration and authorization. A public endpoint without an environment contract would weaken the trust boundary. **Roadmap alignment** This work supports the Cloud and Sandbox agents milestone. It also supports self-healing runs and governed tool access. ## What Changed - Added execution-target traits for local, SSH, and sandbox environments. - Added plugin RPC contracts for runner ingress endpoints. - Added authenticated Daytona preview ingress. - Added transport-neutral PRP outbound connections. - Added remote runner artifact verification and fail-closed provider selection. - Added bounded native session resume, cancellation, and lifecycle recovery. - Preserved Codex-only selection for fresh experimental runner starts. - Preserved all direct adapter execution and finalization paths. - Removed stale Pi provider-pack requirements that security review rejected. - Kept the rollout controls off by default. - Did not change pnpm-lock.yaml, Cargo, database migrations, or GitHub workflows. ## Verification - GitHub Actions will run the repository test, typecheck, build, security, and policy gates. - Focused tests cover ingress validation, redaction, execution targets, remote lifecycle, cancellation, resume, and legacy adapter selection. - Local tests were not run. The requested verification policy uses GitHub Actions for this series. - `git diff --check origin/master...HEAD` passes. - The diff contains 52 files. ## Risks - Remote execution crosses a trust boundary. - The implementation validates target capabilities, artifact digests, provider-pack pins, and connection metadata. - The feature remains default-off. - Fresh native selection remains Codex-only. - Existing direct adapters remain on the legacy path. - This PR does not yet make remote Codex runnable. The next PR adds the Rust WSS and TLS transport. ## Model Used OpenAI Codex with GPT-5.6. The work used high-reasoning agent mode, repository tools, GitHub tools, and parallel code-audit agents. ## 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 or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal Paperclip ticket id - [ ] 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 - [ ] 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 |
||
|
|
7551b63ef2 |
Remove the instance Heartbeats settings page (#12282)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Instance settings collect deployment-wide controls; one of them was the Heartbeats page, an instance-wide list of scheduler heartbeat agents with enable/disable toggles > - The same controls live on each agent's own configuration surface, so the standalone list duplicates them, and its framing no longer matches how heartbeat agents are managed > - Keeping a settings view that no longer makes sense costs every deployment navigation noise and maintenance > - This pull request removes the page, its route, its navigation entries, and its hidden-settings key for all deployments > - The benefit is a smaller, coherent settings surface, with operator hidden-settings lists that still mention the retired key continuing to work unchanged ## Linked Issues or Issue Description No public issue exists; describing the issue inline per the enhancement template: **What existing behavior does this improve?** The instance settings surface — specifically the Settings → Heartbeats page, which listed scheduler heartbeat agents instance-wide with enable/disable toggles. The view no longer makes sense as a standalone settings page: the same controls are available on each agent's configuration surface, and the instance-wide list framing does not match how heartbeat agents are managed. **Subsystem affected** Cross-cutting: `ui/` (page, route, navigation), `packages/shared` (settings-visibility registry), docs. **Current behavior** The page renders at `/company/settings/instance/heartbeats`, appears in the settings sidebar and tab bar, and is hideable by hosting operators via the `instance.heartbeats` key of `PAPERCLIP_HIDDEN_SETTINGS`. **Proposed behavior** The page, route, and navigation entries are removed for every deployment. The `instance.heartbeats` registry key is retired; operator lists that still send it are logged and ignored, so mixed-version fleets keep working. Remembered settings paths pointing at the old page remap to the settings root. Heartbeat APIs are unchanged. **Reason and benefit** A smaller, coherent settings surface with no duplicated controls; less navigation noise and maintenance for every deployment. **Breaking changes** None functional. Bookmarks and remembered paths to the removed page land on the settings root; `PAPERCLIP_HIDDEN_SETTINGS` lists that still include `instance.heartbeats` log a warning and are otherwise honored unchanged. ## What Changed - Deleted `ui/src/pages/InstanceSettings.tsx` (the Heartbeats view) and its route in `ui/src/App.tsx`. - Removed the sidebar entry (`CompanySettingsSidebar`) and tab-bar item (`CompanySettingsNav`). - Removed `"/heartbeats"` from the remembered-settings-path allowlist; remembered heartbeats paths now remap to the settings root. - Retired the `instance.heartbeats` key from the shared settings-visibility registry and the environment-variables doc; documented that retired keys are ignored with a warning. - Dropped the now-unused UI client wrapper for the instance scheduler-agent list (`heartbeatsApi.listInstanceSchedulerAgents`); the server endpoint stays. - Removed the unused `schedulerHeartbeats` query key. ## Verification - `npx vitest run packages/shared/src/settings-visibility.test.ts ui/src/lib/instance-settings.test.ts ui/src/components/CompanySettingsSidebar.test.tsx ui/src/components/access/CompanySettingsNav.test.tsx` — 24 tests passing. - Full `ui` vitest suite: 4426 tests, 4 failures — all in files this PR does not touch; 3 were load-induced timeouts that pass on rerun, and `OnboardingWizard.test.tsx` "renders instead of throwing when the browser denies storage access" fails identically on a clean master checkout (pre-existing). - `pnpm --filter @paperclipai/ui typecheck` and `pnpm --filter @paperclipai/shared typecheck` — clean. - Merged `master` to clear a conflict (see below) and re-ran the four focused suites (24 passing), `ui/src/App.test.tsx` and `ui/src/plugins/bridge.test.ts` (22 passing), and both typechecks — all clean. Full CI is green on the merge commit. ## Merge With master `master` gained the `company` → `organization` copy pass (#12243), which reworded strings inside `ui/src/pages/InstanceSettings.tsx` — the page this branch deletes — producing a modify/delete conflict. Resolved by keeping the deletion: the page is going away, so the rewording of its copy has nothing to apply to. Every other file merged cleanly, and `master`'s rewording in `App.tsx`, `App.test.tsx`, and `CompanySettingsSidebar.tsx` sits away from this branch's structural removals, so both changes survive. The net diff against `master` is unchanged from the pre-merge review: the same 13 files, 23 insertions, 330 deletions. ## Risks - Low. Pure removal of a UI surface; heartbeat data and APIs are untouched. Operators still listing `instance.heartbeats` in `PAPERCLIP_HIDDEN_SETTINGS` get a warning log and otherwise unchanged behavior (covered by the registry's unknown-key handling). Bookmarks and remembered paths to the old page land on the settings root. ## Model Used Claude (Anthropic), model id `claude-fable-5`, extended thinking, agentic tool use via Claude Code. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] 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 |
||
|
|
8f195c2f49 |
Let operators supply defaults for selected instance settings (#12285)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - Hosting operators (a managed cloud, an internal shared server) tune
the settings surface with `PAPERCLIP_HIDDEN_SETTINGS`, but hiding a
control never changes its value
> - An instance whose stored feedback-sharing preference is still the
schema default ("prompt") keeps prompting users even when the operator
hid the control, leaving them no way to answer
> - More generally, operators have no supported way to change what a
setting defaults to without patching code
> - This pull request adds `PAPERCLIP_SETTING_DEFAULTS`, a generic
operator-supplied read-time default overlay for registry-listed general
settings
> - The benefit is that any hosting operator can pair "hide the control"
with "default the value", while explicit user choices and self-hosted
stock behavior stay untouched
## Linked Issues or Issue Description
No public issue exists; following the enhancement template:
**What existing behavior does this improve?**
Hosting operators need to supply the default value of selected instance
settings (first: `feedbackDataSharingPreference`) via configuration,
without patching code and without a hard-coded, opinionated constant in
the product.
**Subsystem affected**
Server (instance-settings service, feedback service, boot) and
`packages/shared` (settings schemas).
**Current behavior**
Setting defaults are fixed in the shared zod schemas.
`PAPERCLIP_HIDDEN_SETTINGS` can hide the feedback-sharing control and
floor writes, but the stored value stays "prompt", so issue-chat
surfaces keep prompting with no way to answer.
**Proposed behavior**
`PAPERCLIP_SETTING_DEFAULTS` takes a JSON object validated against a
shared registry of defaultable fields. The operator value substitutes
for the schema default at read time: a field whose effective value is
still the schema default resolves to the operator value; an explicit
non-default user choice always wins. Never persisted; unsetting the
variable restores stock behavior. Malformed JSON or an invalid value for
a known field refuses startup (fail closed); unknown field names warn
and are ignored (mixed-version fleet safe).
**Reason and benefit**
Any hosting operator can pair "hide the control" with "default the
value" without forking the product. Explicit user choices and
self-hosted stock behavior stay untouched.
**Breaking changes**
None. With the variable unset, every read path is byte-identical to
before.
## What Changed
- New `packages/shared/src/setting-defaults.ts`:
`SETTING_DEFAULTS_ENV_KEY`, `DEFAULTABLE_GENERAL_SETTINGS` registry
(currently `feedbackDataSharingPreference`), `parseSettingDefaults`
(fail-closed for policy content, warn-ignore unknown fields),
`applyOperatorGeneralDefaults` (pure read-time overlay),
`stripOperatorGeneralEchoes` (persist-time echo strip, see below),
re-exported from the package index.
- New `server/src/services/setting-defaults.ts`: parse-once accessor
mirroring `settings-visibility.ts`.
- `server/src/services/instance-settings.ts`: `toGeneralView` applies
the overlay in `get`/`getGeneral`/update responses; persisted writes
never carry operator values. Because general-settings writes materialize
every field, a stored schema-default value is treated as unchosen —
deliberate, documented, and covered by tests.
- `server/src/services/feedback.ts`: the preference-persistence branch
now checks the effective (overlaid) preference, so a stray prompt answer
cannot overwrite an operator default; its local normalize fallback now
returns full schema defaults.
- `server/src/index.ts`: boot-time fail-fast parse with a log line
naming the defaulted settings, mirroring the managed-config posture.
- The hidden-settings write floor (`assertNoHiddenSettingChanges`) keeps
comparing against effective values, so clients echoing a full GET
response keep working. To keep the overlay strictly read-time,
`updateGeneral` strips such echoes at persist time: a write of the
operator value over a field whose stored value is still the schema
default (unchosen) maps back to the schema default, so an echo cannot
promote the operator value into an explicit stored choice and later
changes to (or removal of) `PAPERCLIP_SETTING_DEFAULTS` still take
effect. A write of any other value, or over an explicit stored choice,
persists as given.
- Docs: `PAPERCLIP_SETTING_DEFAULTS` row + "Operator setting defaults"
section in `docs/deploy/environment-variables.md`.
- Tests: `packages/shared/src/setting-defaults.test.ts` (parse matrix,
overlay precedence, echo-strip matrix, immutability) and
`server/src/__tests__/instance-settings-operator-defaults.test.ts`
(accessor, substitution, explicit-choice wins, unset identity,
never-persisted, full-GET echo stays unchosen, explicit non-default
write persists).
## Verification
- `npx vitest run packages/shared/src/setting-defaults.test.ts
server/src/__tests__/instance-settings-operator-defaults.test.ts
server/src/__tests__/instance-settings-managed-overlay.test.ts` — 33
tests passing.
- `npx vitest run server/src/__tests__/instance-settings-routes.test.ts
server/src/__tests__/instance-settings-service.test.ts` — 57 passing;
`npx vitest run server/src/__tests__/feedback-service.test.ts
server/src/__tests__/issue-feedback-routes.test.ts` — 18 passing.
- `pnpm --filter @paperclipai/shared typecheck` and `pnpm --filter
@paperclipai/server typecheck` — clean.
## Risks
- Low. With the variable unset every read path is byte-identical to
before (identity overlay, covered by tests). The overlay is read-time
only and never persisted, so no migration and no data risk. Fail-closed
parsing means a bad policy value is a loud boot failure rather than
silent drift — consistent with the existing managed-config contract.
## Model Used
Claude (Anthropic), model id `claude-fable-5`, extended thinking,
agentic tool use via Claude Code.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] 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
|
||
|
|
e34ed9801b |
Let operators hide the Provider vaults and Proposals tabs (#12284)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Hosting operators (a managed cloud, an internal shared server) tune the settings surface with `PAPERCLIP_HIDDEN_SETTINGS`, which today hides whole pages > - The Secrets page bundles four tabs, and two of them — Provider vaults and Proposals — do not apply to deployments where the operator provisions provider credentials itself > - Hiding the whole Secrets page is too coarse: the Secrets and My secrets tabs stay essential everywhere > - This pull request adds per-tab visibility keys (`company.secrets.vaults`, `company.secrets.proposals`) as a new company-section registry group > - The benefit is that any hosting operator can trim the Secrets page to what fits their deployment, with self-hosted behavior unchanged by default ## Linked Issues or Issue Description No public issue exists; following the enhancement template: **What existing behavior does this improve?** `PAPERCLIP_HIDDEN_SETTINGS` can hide the whole Secrets page (`company.secrets`) but not individual tabs. Operators of managed deployments need to hide the Provider vaults and Proposals tabs while keeping the rest of the page. **Subsystem affected** Settings visibility (`packages/shared/src/settings-visibility.ts`) and the Secrets page UI (`ui/src/pages/Secrets.tsx`). **Current behavior** The Secrets page always renders all four tabs (Secrets, My secrets, Provider vaults, Proposals), polls pending proposals for the badge, and offers "manage vaults" affordances that jump to the vaults tab. **Proposed behavior** Two new registry keys, `company.secrets.vaults` and `company.secrets.proposals`, hide the corresponding tab: the tab-bar entry disappears, an active hidden tab snaps back to Secrets, the manage-vaults affordances are suppressed, and the pending-proposals poll stops. UI visibility only — the provider-config and proposal APIs stay live for agents and integrations, matching the existing `company.*` precedent. Nothing changes when the variable is unset. **Reason and benefit** Any hosting operator (a managed cloud, an internal shared server) can trim the Secrets page to what fits their deployment — for example when the operator provisions provider credentials itself, so the vault and proposal flows do not apply — without losing the Secrets and My secrets tabs, which stay essential everywhere. **Breaking changes** None. With `PAPERCLIP_HIDDEN_SETTINGS` unset (or set to existing keys only) nothing changes; older app versions receiving the new keys ignore them with a warning by design. ## What Changed - `packages/shared/src/settings-visibility.ts`: new `HIDEABLE_COMPANY_SECTIONS` group (`company.secrets.vaults`, `company.secrets.proposals`), `HideableCompanySection` type, `hidesCompanySection()` helper, wired into `HideableSettingKey` / `HIDEABLE_SETTING_KEYS`, re-exported from the package index. - `ui/src/pages/Secrets.tsx`: tab-bar filtering, hidden-tab snap-back effect, gated pending-proposals query, conditional `onManageVaults` on both the import button and dialog (the button's "AWS vault disabled — manage" affordance renders nothing when vaults are hidden), hidden `TabsContent` blocks. - Docs: new bullet in `docs/deploy/environment-variables.md` under "Hiding settings surfaces". - Tests: registry membership/parse cases in `settings-visibility.test.ts`; new render cases in `Secrets.render.test.tsx` (hidden tabs absent + proposals poll skipped; default render keeps both tabs and the poll). ## Verification - `npx vitest run packages/shared/src/settings-visibility.test.ts ui/src/pages/Secrets.render.test.tsx` — 43 tests passing. - `pnpm --filter @paperclipai/shared typecheck` and `pnpm --filter @paperclipai/ui typecheck` — clean. ## Risks - Low. Nothing changes with `PAPERCLIP_HIDDEN_SETTINGS` unset (covered by the default-render test). The keys are UI-visibility only, so agent/integration API access is unaffected. Older app versions receiving the new keys ignore them with a warning by design. ## Model Used Claude (Anthropic), model id `claude-fable-5`, extended thinking, agentic tool use via Claude Code. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] 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 |
||
|
|
9c03443c48 |
feat: hideable company settings pages, with import floored on cloud-managed instances (#12199)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The app can run self-hosted or as a cloud-managed instance, where a
hosting platform provisions the instance with its company already
materialized (the existing `isCloudManagedInstance()` predicate and
`cloud_managed` floors)
> - The company Import/Export surface lets an operator materialize whole
companies from an export bundle; on a cloud-managed instance this
bypasses the existing `cloud_managed` company-creation floor and
conflicts with platform-owned provisioning
> - Importing should be disabled on cloud-managed instances, while
export stays open as the data-portability escape hatch
> - This pull request floors every import route with 403
`code=cloud_managed` on cloud-managed instances and hides the Import UI
there, using the existing predicate and the established floor pattern
> - It also extends the operator-hidden settings registry with keys for
every top-level company settings page, so a hosting operator can hide
any of them with `PAPERCLIP_HIDDEN_SETTINGS` alone next time
> - The benefit is one consistent managed-instance policy: cloud-managed
instances cannot import companies, self-hosted installs keep the full
import surface unchanged
## Linked Issues or Issue Description
No public issue exists; the underlying problem follows the enhancement
template.
**What existing behavior does this improve?**
The company import surface (`/api/companies/import*`,
`/api/companies/:companyId/imports/*`) and its UI entry points on
cloud-managed instances.
**Subsystem affected**
Server routes (`server/src/routes/companies.ts`) and UI navigation/pages
(settings sidebar, settings tabs, org chart, `/company/import` route).
**Current behavior**
A cloud-managed instance floors direct company creation (`POST
/api/companies` answers 403 `cloud_managed`), but the import routes
still accept company bundles, so an import can materialize companies the
hosting platform did not provision. The UI offers Import entry points
that lead to a surface that is not available on cloud-managed instances.
**Proposed behavior**
On instances where `isCloudManagedInstance()` is true, every import
route answers 403 `code=cloud_managed` before auth and body work, and
the Import UI (sidebar entry, settings tab, org-chart button,
`/company/import` route) is hidden or redirected. Export remains fully
available. Self-hosted instances are unchanged.
**Reason and benefit**
Cloud-managed instances keep one consistent provisioning authority, and
users do not see an Import surface that dead-ends in a 403.
## What Changed
- `server/src/routes/companies.ts`: a router-level floor mounted at the
`/import` and `/:companyId/imports` prefixes. It covers the single-shot
upload, preview, job polling, chunked transfer
declare/part-upload/status/preview/apply, and the agent-safe per-company
import routes. It throws `forbidden(..., { code: "cloud_managed" })` on
cloud-managed instances, or `403 settings_operator_managed` when the
operator hides `company.import` — both before auth and body validation,
mirroring the company-creation floor.
- `packages/shared/src/settings-visibility.ts`: new
`HIDEABLE_COMPANY_PAGES` registry group — `company.members`,
`company.invites`, `company.secrets`, `company.export`, `company.import`
— with a `hidesCompanyPage` helper. The company General page stays
non-hideable (settings root). `company.import` floors its API; the other
keys are UI-visibility only, as documented in the registry, so
membership/invite/secret/export APIs stay live for agents.
- `ui/src/components/CloudManagedPageGate.tsx` (new): route gate that
redirects cloud-managed instances to `/company/settings`, modeled on
`HiddenSettingsPageGate`.
- `ui/src/App.tsx`: wraps the `company/import` route in
`CloudManagedPageGate`.
- `ui/src/components/CompanySettingsSidebar.tsx`,
`ui/src/components/access/CompanySettingsNav.tsx`,
`ui/src/pages/OrgChart.tsx`: hide the Import entry points when
`useCloudInstance()` reports a managed instance, and honor the new
`company.*` hidden-settings keys for every company page entry (sidebar
item, tab, org-chart buttons).
- `ui/src/App.tsx`: `HiddenSettingsPageGate` route gates for the members
(incl. the legacy access route), invites, secrets, export, and import
pages under their `company.*` keys.
- `docs/deploy/environment-variables.md`: documents the new keys and
their semantics; the CLI and board-operator guides note that import is
unavailable on cloud-managed instances.
- Tests: new `server/src/__tests__/company-import-cloud-floor.test.ts`
and `ui/src/components/CloudManagedPageGate.test.tsx`, registry cases in
`packages/shared/src/settings-visibility.test.ts`, plus cloud and
hidden-key cases in the sidebar, settings-nav, and org-chart suites.
## Verification
- TypeScript typechecks pass for every workspace package (`tsc` in
shared, server, ui; the runner's Rust leg needs a local cargo toolchain
and is covered by CI).
- `pnpm test` on this branch fails only in 9 files that also fail on a
clean `origin/master` checkout on the same machine
(environment-dependent suites: live-listener probes,
workspace/native-runtime spawns, skill materialization). Zero
branch-only failures against that baseline; every suite touched by this
change passes.
- `server/src/__tests__/company-import-cloud-floor.test.ts` asserts:
every import route answers 403 `cloud_managed` under the server-token
signal; the managed-config signal alone also floors; every import route
answers 403 `settings_operator_managed` when `company.import` is hidden;
hiding other company pages leaves import open; the floor applies before
auth and body validation; export stays open on cloud-managed instances;
self-hosted import preview and job polling still work.
- `packages/shared/src/settings-visibility.test.ts` covers the new
`company.*` keys and `hidesCompanyPage`.
- UI suites assert the Import tab, sidebar entry, and org-chart button
disappear on a cloud-managed instance while Export stays, that
`/company/import` redirects through the gate, and that the `company.*`
keys hide their sidebar entries and tabs.
## Risks
- Low risk for self-hosted installs: the floor is inert unless a cloud
signal (`PAPERCLIP_CLOUD_TENANT_SERVER_TOKEN` or
`PAPERCLIP_MANAGED_CONFIG`) is present, and the self-hosted paths are
regression-tested.
- On cloud-managed instances this is a deliberate behavioral removal:
import (including agent-driven safe imports and resumable transfers)
stops working the moment an instance runs this build. In-flight chunked
transfers on such instances cannot be applied afterward; they answer
403.
- CLI import commands against a cloud-managed instance now fail with the
`cloud_managed` error; the message names the reason.
- The new `company.*` keys change nothing unless an operator sets them:
`PAPERCLIP_HIDDEN_SETTINGS` unset keeps behavior identical, and older
images ignore unknown keys by design. The four non-import company keys
hide UI only; their APIs stay live, which the registry documents
explicitly.
## Model Used
Claude Fable 5 (`claude-fable-5`, Anthropic) via Claude Code — agentic
coding session with 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
- [ ] 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
|
||
|
|
db4defdfbf |
feat: operator-configurable settings visibility via PAPERCLIP_HIDDEN_SETTINGS (#11823)
## Thinking Path
> - Paperclip is the open source app people use to manage AI agents for
work
> - The instance settings surface (Access, Plugins, Adapters, General,
Experimental) assumes the person at the keyboard operates the whole
instance
> - Operators who host Paperclip for others — a managed cloud or an
internal shared server — expose settings pages and toggles that do not
apply to their deployment, and the related mutation APIs stay open
> - A hosted tenant can open Plugins or Adapters, try an action, and hit
a confusing failure, because only a few hardcoded platform floors exist
> - This pull request adds a generic, operator-configured visibility
mechanism: one env var hides declared settings surfaces in the UI and
floors their mutation routes with a stable 403 code
> - The benefit is a clean hosted-tenant settings surface for any
operator, with zero behavior change for normal self-hosted instances
## Linked Issues or Issue Description
**Subsystem affected**
Instance settings (server routes and UI), the shared settings registry
in `packages/shared`, and the `/api/health` bootstrap payload.
**Problem or motivation**
An operator who hosts Paperclip for other people cannot hide settings
surfaces that the platform manages. Tenants see Access, Plugins, and
Adapters pages, backup retention, and host-level experimental toggles
that do nothing useful for them. The mutation APIs behind these surfaces
also stay open, so a tenant admin can attempt actions the platform must
control. ROADMAP.md names a cleaner shared deployment story as a goal
("Teams should be able to run the same product in hosted or semi-hosted
environments without changing the mental model").
**Proposed solution**
Add a declarative registry of hideable settings surfaces and one env
var, `PAPERCLIP_HIDDEN_SETTINGS`. The server parses the list at boot,
reports it on `/api/health`, and rejects value-changing writes to hidden
surfaces with a stable `settings_operator_managed` 403 code. The UI
reads the list from the health payload and removes the hidden pages,
sections, and toggles from navigation, routes, and page content. Unknown
keys warn and are ignored, so one list can roll across a fleet with
mixed app versions. With the variable unset, behavior is byte-identical
to today.
**Alternatives considered**
- Hardcode the hidden set for cloud instances in this repo: rejected,
because each hosting operator needs a different policy, and policy does
not belong in shared code.
- Deliver the hidden set through the managed-config document: rejected,
because that channel is cloud-specific and fail-closed on unknown
fields; a plain env var works for any operator, including self-hosted
shared servers.
- Lock the controls with a badge instead of hiding them: rejected for
these surfaces, because they are meaningless to tenants, not merely
platform-controlled; the existing managed-overlay lock stays the right
tool for controlled flags.
**Roadmap alignment**
Supports the "shared deployment story" item in ROADMAP.md: hosted and
semi-hosted deployments keep the same product with a settings surface
that matches what the tenant can actually do.
## What Changed
- New `packages/shared/src/settings-visibility.ts`: registry of hideable
surfaces (every instance settings page — profile, environments, access,
heartbeats, experimental, plugins, adapters; every Instance → General
section; every experimental flag as `instance.experimental.<key>`), the
`PAPERCLIP_HIDDEN_SETTINGS` parser, and the `settings_operator_managed`
error code. The General page stays visible as the settings root and
redirect target.
- New `server/src/services/settings-visibility.ts`: parse-once accessor;
unknown keys log one warning and are ignored.
- `/api/health` reports `hiddenSettings` on every response shape; the
field is omitted when nothing is hidden.
- Server floors on hidden surfaces, with same-value echo tolerance (the
`executionMode` precedent): field-backed general sections and
experimental keys reject value-changing PATCHes, and hiding the whole
Experimental page floors every toggle; plugin lifecycle and config
writes, adapter management writes, and the Access admin routes (reads
included) return 403 `settings_operator_managed`. Reads the app itself
needs (plugin `ui-contributions`, adapter metadata, plugin job trigger)
stay open. Pages without instance-scoped mutation routes are hidden in
the UI only.
- UI: new `useHiddenSettings` hook and `HiddenSettingsPageGate` route
gate (hidden pages redirect to the settings root); the settings sidebar
and tab bar drop hidden entries; remembered settings paths remap to the
default page; `InstanceGeneralSettings` skips hidden sections; every
`ExperimentalToggleCard` now carries its flag key and renders nothing
when hidden.
- Removed the dead `InstanceSidebar` component (referenced only by its
own test).
- Docs: `docs/deploy/environment-variables.md` documents the variable
and the key registry.
## Verification
- `pnpm vitest run` over the new and extended suites: shared registry
and parser, representative floor tests per route class (changed-value
403, same-value echo 200, unset env 200, page-level Experimental
hiding), the health field, the route gate, nav filtering, and
section/card hiding with one hidden example per surface kind — 168 tests
pass.
- Full root `pnpm typecheck` passes.
- Manual: booted a server with the variable set. `/api/health` lists the
keys; an unknown key logs one warning and the server boots; hidden pages
redirect; hidden sections and cards do not render; hidden-field PATCH
returns 403 with `details.code = "settings_operator_managed"`; a
same-value echo returns 200. Unset the variable: the full settings
surface returns and responses are byte-identical to master.
## Risks
- Low risk for self-hosted instances: with the variable unset, the
hidden set is empty, the health field is omitted, and no floor
activates.
- Flooring plugin config writes assumes hosted deployments configure
plugins through the platform. If a future bundled plugin needs
tenant-entered config, the floor needs a narrow carve-out.
- Hidden-key floors tolerate same-value echoes, so API clients that
round-trip full GET responses keep working.
- Hiding a toggle does not change its value; operators pair hiding with
the desired default where the value matters.
## Model Used
Claude Fable 5 (Anthropic, `claude-fable-5`) with extended thinking and
agentic tool use, driven through the Claude Code CLI (file edits, test
execution, and live-server verification loops).
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] 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
|
||
|
|
bf982c8c83 |
Normalize adapter display labels (#8913)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Adapter names are part of the board-facing agent setup and management experience. > - The product now treats adapters as harnesses, while execution environments are modeled separately. > - Several built-in adapter labels still carried legacy local wording from the older harness-by-environment model. > - That wording makes the UI noisier and implies a distinction users no longer need to reason about. > - This pull request normalizes adapter display labels while keeping persisted adapter type identifiers unchanged. > - The benefit is clearer adapter selection and management copy without a database migration. ## Linked Issues or Issue Description No public GitHub issue was found for this exact cleanup. Related public PRs: - Supersedes #8910, an earlier branch for the same cleanup that did not include the later docs/gateway/Cursor alignment. - Refs #8819, which is related display-registry work for external multi-segment adapter labels, but not a duplicate of this built-in label cleanup. Feature request details: - Subsystem affected: Cross-cutting (`ui/`, `packages/adapters`, and docs). - Problem or motivation: user-facing adapter names include legacy local qualifiers even though adapters map to harnesses and environments are first-class elsewhere. - Proposed solution: remove the legacy local wording from built-in display labels, keep machine-readable adapter type ids unchanged, and keep gateway disambiguation where it is useful. - Alternatives considered: changing persisted adapter type ids was ruled out because it would create migration and compatibility risk; one-off UI replacements were ruled out because the display registry is already the correct central label boundary. - Roadmap alignment: this is small adapter UX polish, not a new roadmap-level core feature. ## What Changed - Updated the adapter display registry so known adapter labels are final and no built-in local adapter renders a legacy local suffix. - Preserved clean derived labels for unknown plugin local types while keeping gateway disambiguation for unknown gateway types. - Updated `AdapterManager` to prefer registry labels when the server reports raw adapter type ids for built-ins. - Removed legacy local wording from built-in adapter metadata labels in UI and adapter packages. - Aligned Cursor adapter metadata with the central display registry label. - Updated adapter docs and Storybook fixtures to match the new display names. - Added focused registry coverage for built-in labels and unknown plugin suffix behavior. ## Verification - `pnpm check:tokens` - `git diff --check origin/master...fix/adapter-display-labels` - Patch-addition scan for added secrets, private paths, and internal links: no matches. - GitHub duplicate search for open adapter-label/local-suffix issues and PRs; #8910 was identified as the older superseded public PR. - `pnpm exec vitest run ui/src/adapters/adapter-display-registry.test.ts` - `pnpm --filter @paperclipai/ui typecheck` - Stale-label scan found no remaining user-facing display-label suffixes; remaining local wording is operational/test terminology such as adapter ids, docs about running locally, and test descriptions. ## Risks Low risk. The change is display-label and documentation focused, and adapter type ids remain unchanged. The main risk is ambiguous gateway naming, mitigated by keeping explicit gateway labels where variants need disambiguation. ## Model Used OpenAI GPT-5 via Codex, tool-enabled coding agent in a local repository workspace. Context window size is not exposed by this environment. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
b816809a1e |
fix(server): respect externally set PAPERCLIP_API_URL env var (#3472)
## Thinking Path > - Paperclip server starts up and sets internal `PAPERCLIP_API_URL` for downstream services and adapters > - The server startup code was unconditionally overwriting `PAPERCLIP_API_URL` with `http://localhost:3100` (or equivalent based on `config.host`) > - In Kubernetes deployments, `PAPERCLIP_API_URL` is set via a ConfigMap to the externally accessible load balancer URL (e.g. `https://paperclip.example.com`) > - Because the env var was unconditionally set after loading the ConfigMap value, the ConfigMap-provided URL was ignored and replaced with the internal localhost address > - This caused downstream services (adapter env building) to use the wrong URL, breaking external access > - This pull request makes the assignment conditional — only set if not already provided by the environment > - External deployments can now supply `PAPERCLIP_API_URL` and it will be respected; local development continues to work without setting it ## What Changed - `server/src/index.ts`: Wrapped `PAPERCLIP_API_URL` assignment in `if (!process.env.PAPERCLIP_API_URL)` guard so externally provided values are preserved - `server/src/__tests__/server-startup-feedback-export.test.ts`: Added tests verifying external `PAPERCLIP_API_URL` is respected and fallback behavior is correct - `docs/deploy/environment-variables.md`: Updated `PAPERCLIP_API_URL` description to clarify it can be externally provided and the load balancer/reverse proxy use case ## Verification - Run the existing test suite: `pnpm test:run server/src/__tests__/server-startup-feedback-export.test.ts` — all 3 tests pass - Manual verification: Set `PAPERCLIP_API_URL` to a custom value before starting the server and confirm it is not overwritten ## Risks - Low risk — purely additive conditional check; existing behavior for unset env var is unchanged ## Model Used MiniMax M2.7 — reasoning-assisted for tracing the root cause through the startup chain (`buildPaperclipEnv` → `startServer` → `config.host` → `HOST` env var) ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Pawla Abdul (Bot) <pawla@groombook.dev> Co-authored-by: Paperclip <noreply@paperclip.ing> |
||
|
|
2a84e53c1b |
Introduce bind presets for deployment setup
Co-Authored-By: Paperclip <noreply@paperclip.ing> |
||
|
|
09d2ef1a37 |
fix: restore docs deleted in v0.2.3 release, add Paperclip branding
- Restored docs/ directory that was accidentally deleted by `git add -A` in the v0.2.3 release script - Replaced generic "P" favicon with actual paperclip icon using brand primary color (#2563EB) - Added light/dark logo SVGs for Mintlify navbar (paperclip icon + wordmark) - Updated docs.json with logo configuration for dark/light mode - Fixed release.sh to stage only release-related files instead of `git add -A` to prevent sweeping unrelated changes into release commits Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
28bf5e9e9b | chore: release v0.2.3 | ||
|
|
cabd16bc70 | docs: sync docs and skills updates from backup branch | ||
|
|
02dc46e782 |
docs: add external documentation site content
Add structured documentation covering quickstart, architecture, core concepts, API reference, adapter guides, CLI commands, deployment options, and operator/developer guides. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |