mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-07 07:23:08 +02:00
## 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
5.3 KiB
5.3 KiB
title, summary
| title | summary |
|---|---|
| Environment Variables | Full environment variable reference |
All environment variables that Paperclip uses for server configuration.
Server Configuration
| Variable | Default | Description |
|---|---|---|
PORT |
3100 |
Server port |
PAPERCLIP_BIND |
loopback |
Reachability preset: loopback, lan, tailnet, or custom |
PAPERCLIP_BIND_HOST |
(unset) | Required when PAPERCLIP_BIND=custom |
HOST |
127.0.0.1 |
Legacy host override; prefer PAPERCLIP_BIND for new setups |
DATABASE_URL |
(embedded) | PostgreSQL connection string |
PAPERCLIP_HOME |
~/.paperclip |
Base directory for all Paperclip data |
PAPERCLIP_INSTANCE_ID |
default |
Instance identifier (for multiple local instances) |
PAPERCLIP_DEPLOYMENT_MODE |
local_trusted |
Runtime mode override |
PAPERCLIP_DEPLOYMENT_EXPOSURE |
private |
Exposure policy when deployment mode is authenticated |
PAPERCLIP_API_URL |
(auto-derived) | Paperclip API base URL. When set externally (e.g., via Kubernetes ConfigMap, load balancer, or reverse proxy), the server preserves the value instead of deriving it from the listen host and port. Useful for deployments where the public-facing URL differs from the local bind address. |
PAPERCLIP_HIDDEN_SETTINGS |
(unset) | Comma-separated settings surfaces to hide from the UI and floor at the API, for operators hosting Paperclip for others (managed cloud, internal shared server). See Hiding settings surfaces. |
Hiding settings surfaces
PAPERCLIP_HIDDEN_SETTINGS takes keys from the registry in
packages/shared/src/settings-visibility.ts:
- Any instance settings page:
instance.profile,instance.environments,instance.access,instance.heartbeats,instance.experimental,instance.plugins,instance.adapters— removed from navigation and routing (the General page is the settings root and stays visible). Hidinginstance.access,instance.plugins, orinstance.adaptersalso floors their management endpoints with403 settings_operator_managed; hidinginstance.experimentalfloors every experimental toggle write. - Any Instance → General section:
instance.general.censorUsernameInLogs,instance.general.keyboardShortcuts,instance.general.backupRetention,instance.general.feedbackDataSharingPreference(each also rejects value-changing writes viaPATCH /api/instance/settings/general), plus the UI-onlyinstance.general.deploymentStatusandinstance.general.signOut. - Any experimental toggle:
instance.experimental.<flagKey>(e.g.instance.experimental.enableSmokeLab) — the card disappears and value-changing writes are rejected. - Any top-level company settings page:
company.members,company.invites,company.secrets,company.export,company.import— removed from the settings sidebar, tab bar, and routing (the company General page is the settings root and stays visible). These are UI-visibility keys: the membership, invite, secret, and export APIs stay live for agents and integrations.company.importis the exception — hiding it also floors every company-import route with403 settings_operator_managed. On cloud-managed instances import is floored unconditionally with403 cloud_managed, independent of this variable. - A single tab of the Secrets page:
company.secrets.vaults(Provider vaults) andcompany.secrets.proposals(Proposals) — the tab disappears while the rest of the page stays up. UI-visibility only; the secret provider-config and proposal APIs stay live for agents and integrations.
Unknown keys are logged and ignored, so one list can be rolled across a fleet of mixed app versions. With the variable unset nothing is hidden and behavior is identical to earlier releases. Hiding a toggle does not change its value; pair hiding with the desired default where it matters.
Secrets
| Variable | Default | Description |
|---|---|---|
PAPERCLIP_SECRETS_MASTER_KEY |
(from file) | 32-byte encryption key (base64/hex/raw) |
PAPERCLIP_SECRETS_MASTER_KEY_FILE |
~/.paperclip/.../secrets/master.key |
Path to key file |
PAPERCLIP_SECRETS_STRICT_MODE |
false |
Require secret refs for sensitive env vars |
Agent Runtime (Injected into agent processes)
These are set automatically by the server when invoking agents:
| Variable | Description |
|---|---|
PAPERCLIP_AGENT_ID |
Agent's unique ID |
PAPERCLIP_COMPANY_ID |
Company ID |
PAPERCLIP_API_URL |
Paperclip API base URL (inherits the server-level value; see Server Configuration above) |
PAPERCLIP_API_KEY |
Short-lived JWT for API auth |
PAPERCLIP_RUN_ID |
Current heartbeat run ID |
PAPERCLIP_TASK_ID |
Issue that triggered this wake |
PAPERCLIP_WAKE_REASON |
Wake trigger reason |
PAPERCLIP_WAKE_COMMENT_ID |
Comment that triggered this wake |
PAPERCLIP_APPROVAL_ID |
Resolved approval ID |
PAPERCLIP_APPROVAL_STATUS |
Approval decision |
PAPERCLIP_LINKED_ISSUE_IDS |
Comma-separated linked issue IDs |
LLM Provider Keys (for adapters)
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY |
Anthropic API key (for Claude Code adapter) |
OPENAI_API_KEY |
OpenAI API key (for Codex adapter) |