chore: sync 11 upstream commits from paperclipai/paperclip#174
Merged
Conversation
…lipai#6804) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - The repository README closes with a license/copyright line that downstream readers use to identify the legal entity behind the project > - The line currently reads "MIT © 2026 Paperclip", which omits the formal corporate name > - The legal entity is "Paperclip Labs, Inc"; the README should reflect that for accuracy > - This pull request updates the README footer to "MIT © 2026 Paperclip Labs, Inc" > - The benefit is correct attribution of the MIT license to the actual legal entity ## What Changed - Updated `README.md` license line from "MIT © 2026 Paperclip" to "MIT © 2026 Paperclip Labs, Inc" ## Verification - Open `README.md` and confirm the final line reads `MIT © 2026 Paperclip Labs, Inc` - No code paths affected; no tests required ## Risks - Low risk — single-line documentation change, no runtime impact ## Model Used - Provider: Anthropic Claude - Model ID: claude-opus-4-7 - Capabilities: tool use, code execution via Claude Code CLI ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass (N/A — docs-only change) - [x] I have added or updated tests where applicable (N/A) - [x] If this change affects the UI, I have included before/after screenshots (N/A — no UI change) - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
…pai#6810) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - The README is the first impression for developers and operators landing on the repo, so it has to reflect the current brand voice and visual identity > - The existing README leads with an outdated hero ("Open-source orchestration for zero-human companies"), keeps a board-centric tagline that no longer matches the positioning, advertises a removed COMING SOON teaser, and still uses an old header image and an unnecessary footer image > - Out-of-date positioning at the top of the README undercuts the rest of the doc and the brand guidelines refresh at https://paperclip.ing/brand > - This pull request swaps the README header image for the new brand banner, updates the hero copy and tagline, and trims stale callouts so the README matches the new brand guidelines > - The benefit is a README that leads with the current positioning ("Paperclip is the app people use to manage AI agents for work.") and current visual identity, with no stale teasers or extraneous footer image ## What Changed - Added new brand banner at \`doc/assets/banner.jpg\` and pointed the README header \`<img>\` at it (alt text updated to the new tagline) - Replaced the \`## What is Paperclip?\` + \`# Open-source orchestration for zero-human companies\` heading pair with a single H1: \`# Paperclip is the app people use to manage AI agents for work.\` - Tightened the opening paragraphs ("Open-source orchestration for teams of AI agents.", trimmed dashboard sentence, "Under the hood:" line, period on the OpenClaw/Paperclip tagline) - Removed the \`COMING SOON: Clipmart\` callout - Softened the Governance copy by dropping "You're the board." in both the Features grid and the Systems table - Fixed typo: "solo-entreprenuer" → "solo entrepreneur" - Removed the README footer image block entirely - Updated the closing subline: "Built for people who want to run companies, not babysit agents." → "Built for people who want to get work done, not babysit agents." - Left existing assets untouched on disk: \`doc/assets/header.png\` and \`doc/assets/footer.jpg\` are unchanged from master (only the README references changed) ## Verification - \`git diff master..HEAD --stat\` → only \`README.md\` (10+/18-) and the new \`doc/assets/banner.jpg\` - Rendered the README locally and confirmed: - The header banner shows the new brand image - The H1 reads "Paperclip is the app people use to manage AI agents for work." - No COMING SOON Clipmart callout - No footer image; closing subline reads "Built for people who want to get work done, not babysit agents." - No code paths changed; no test suite applies ## Risks - Low risk. Docs-only change. \`cli/README.md\` still references the on-master URL for \`doc/assets/header.png\`, which is intentionally left in place so that link does not break. ## Model Used - Claude (Anthropic), model id \`claude-opus-4-7\` ("Opus 4.7"), running under Claude Code via the Paperclip claude_local adapter. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass (n/a — docs-only) - [x] I have added or updated tests where applicable (n/a — docs-only) - [x] If this change affects the UI, I have included before/after screenshots (n/a — README-only; rendered review described in Verification) - [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 Closes PAPA-439
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - Fresh self-hosted deployments need an operator path before any invite exists. > - Umbrel installs are private LAN deployments, so a one-time browser claim is appropriate only when the deployment is private and unclaimed. > - Public deployments and installs with active invites must keep the existing invite-only model so admin creation is not exposed broadly. > - GitHub PR paperclipai#2927 established the useful direction, but it needed to be adapted onto current `master` rather than merged as-is. > - This pull request adds that adapted private-only claim flow across server, UI, docs, and regression coverage. > - The benefit is that a fresh private Umbrel-style install can be claimed from the browser without weakening public deployment access. ## What Changed - Added a first-admin claim service and access route support for one-time admin claim eligibility on private unclaimed deployments. - Updated the bootstrap/access UI so eligible private installs show a setup claim path, while public and invited deployments keep invite-first behavior. - Added a bootstrap-pending setup UX lab covering claim, invite, public, and signed-in access states. - Updated deployment and local development docs for authenticated private/public behavior and the Umbrel-style claim path. - Added server and UI regression tests for private claim, public no-claim, active invite fallback, existing board/no-access flows, and health exposure reporting. - Stabilized PR handoff verification by serializing the aggregate server Vitest workspace run, forcing `NODE_ENV=test`, and relaxing the heartbeat batching test around legitimate recovery follow-up runs. ## Verification - `pnpm -r typecheck` - `pnpm build` - `pnpm vitest --run server/src/__tests__/heartbeat-comment-wake-batching.test.ts` - `pnpm vitest --run server/src/__tests__/health-dev-server-token.test.ts` - `pnpm test:run` - QA validation: PAP-10115 passed browser validation with screenshots for private fresh install claim, active invite versus claim conflict, public invite-only/claim-absent behavior, existing invite fallback, and normal board/no-access flows. - GitHub closeout: issue paperclipai#2579 and PR paperclipai#2927 were updated with the accepted direction: adapt the implementation, do not direct-merge paperclipai#2927 as-is. ## Risks - The claim endpoint must remain private-only and one-time; a regression here could expose admin creation on public deployments. - Existing invite behavior must remain intact for public deployments and installs that already have an active invite. - The stable Vitest harness now serializes the aggregate server workspace group; this is slower, but it avoids DB-backed suite collisions under root workspace mode. > 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`. > > ROADMAP.md checked: this is a scoped deployment bootstrap/access fix and does not duplicate a listed roadmap project. ## Model Used - OpenAI GPT-5 Codex via Paperclip `codex_local` for product engineering, implementation, and verification, with tool-enabled local code execution. Paperclip QA browser validation was performed in PAP-10115 by the assigned QA agent; exact adapter model metadata for that QA run is not exposed in this PR context. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies through company-scoped control-plane workflows. > - Agents need reusable, inspectable skills that can be installed, reset, audited, exported, and assigned without bespoke local setup. > - The existing skill truth model needed cleanup so bundled skills, optional catalog skills, runtime skills, and adapter-provided skills have clear provenance. > - Operators also need a practical CLI and board UI for discovering and managing company skills. > - This pull request adds the skills CLI, packaged skills catalog, company skills APIs, and catalog-aware board UI. > - The benefit is a more reusable Paperclip company setup where skills are portable, auditable, and easier for operators and agents to manage. ## What Changed - Added `paperclipai skills` CLI commands and coverage for catalog listing, installing, resetting, and inspecting company skills. - Added a packaged `@paperclipai/skills-catalog` workspace with bundled and optional skill content plus validation/build tests. - Added shared company-skill types and validators used across CLI, server, and UI contracts. - Added server catalog APIs/services for company skill catalog operations, reset semantics, audit behavior, and portability provenance. - Updated adapter skill handling so runtime/catalog provenance remains explicit across local adapters. - Added board UI support for browsing and managing catalog-backed company skills. - Updated docs for the skills CLI/catalog flow and the company skills Paperclip skill reference. - Rebased the branch onto current `paperclipai/paperclip:master`; no `pnpm-lock.yaml`, `.github/workflows`, or migration files are included in the final PR diff. ## Verification - Passed: `pnpm run preflight:workspace-links && pnpm exec vitest run cli/src/__tests__/skills.test.ts packages/skills-catalog/src/catalog-builder.test.ts packages/skills-catalog/src/shipped-catalog.test.ts packages/shared/src/validators/company-skill.test.ts packages/adapter-utils/src/server-utils.test.ts packages/plugins/create-paperclip-plugin/src/entrypoints.test.ts server/src/__tests__/company-skills-catalog-service.test.ts server/src/__tests__/company-skills-routes.test.ts server/src/__tests__/company-portability.test.ts`. - Passed: `pnpm exec vitest run server/src/__tests__/workspace-runtime.test.ts -t "default branch|origin/master|symbolic-ref"`. - Attempted: full `server/src/__tests__/workspace-runtime.test.ts`. Four provisioning tests failed while seeding an isolated worktree database from the local Paperclip instance because the local plugin schema dump contains a duplicate-column foreign key (`plugin_content_machine_18a7bc327b.content_case_signals`). The default-branch tests touched by the rebase conflict passed in the focused run above. - Checked final diff: no `pnpm-lock.yaml`, no `.github/workflows`, and no migration-file changes relative to `master`. ## Risks - Medium: this is a broad skills/catalog change touching CLI, server APIs, shared contracts, adapter skill sync, and UI. - Catalog validation and reset semantics need careful reviewer attention because they affect reusable company setup and portability. - No database migrations are included in this PR, so there is no migration ordering/idempotency risk in the final diff. - No lockfile is included by design; dependency resolution will be handled by the repository lockfile workflow. ## Model Used - OpenAI Codex coding agent based on GPT-5, running in Paperclip via the `codex_local` adapter with shell, git, GitHub CLI, and code-editing tool access. Exact hosted model build/context-window metadata is not exposed in this runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run targeted tests locally and documented the local workspace-runtime seed failure above - [x] I have added or updated tests where applicable - [x] If this change affects the UI, screenshots were intentionally omitted per PAP-10124 instructions; UI behavior is covered by tests and reviewer inspection - [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: Paperclip <noreply@paperclip.ing>
…clipai#6831) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies, so planning approvals and child-issue fan-out are part of the core control-plane loop. > - Accepted plans are supposed to be a safe bridge from planning into execution, especially when agents wake from review decisions and reuse isolated workspaces. > - The duplicate-subtask incident showed that an accepted plan revision could be interpreted more than once across overlapping runs, which broke the single-source-of-truth model for issue decomposition. > - Fixing that required tightening the backend contract first: accepted-plan decomposition needs an exact-once fingerprint, durable claim state, and retry-safe child creation. > - Once that backend behavior existed, the board still needed visibility into what happened, so the issue detail view needed a dedicated decomposition section instead of forcing operators to reconstruct child creation from raw activity. > - This pull request adds the exact-once decomposition primitive, hardens wake routing and regressions around the incident, and surfaces decomposition state in the UI so future incidents are both prevented and easier to inspect. ## What Changed - Added accepted-plan decomposition semantics to `doc/execution-semantics.md`, including the exact-once fingerprint, durable claim/result expectations, and retry/resume behavior. - Added persistent accepted-plan decomposition claims in the backend, including schema, shared types/validators, service logic, and issue routes for creating and listing decomposition state. - Hardened heartbeat routing so an accepted-plan continuation stays scoped to the relevant planning issue instead of opportunistically re-decomposing another accepted issue on the same assignee. - Added regression coverage for the original failure modes: concurrent same-parent retries, cross-issue accepted-plan isolation, and partial child recreation under the same fingerprint. - Added the `Plan decomposition` issue-detail section plus supporting API/query-key/activity formatting updates so operators can see revision status, owner, child counts, and the linked child issues directly in the UI. - Included the small follow-up UI fix so the decomposition section still renders when the issue work mode is no longer `planning`. ## Verification - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - `pnpm --filter @paperclipai/db typecheck` - `pnpm exec vitest run server/src/__tests__/issues-service.test.ts` - `pnpm exec vitest run server/src/__tests__/issues-service.test.ts -t "lists persisted decompositions with child issue summaries"` - `pnpm exec vitest run server/src/__tests__/issues-service.test.ts -t "accepted plan decomposition" server/src/__tests__/heartbeat-accepted-plan-workspace-refresh.test.ts server/src/__tests__/heartbeat-context-summary.test.ts` - Manual UI path: create a planning issue without an isolated execution workspace, add a `plan` document, accept the `request_confirmation`, let Paperclip create child issues, then reopen the parent issue detail page and confirm the `Plan decomposition` section shows the accepted revision, status, idempotent-claim badge, and child links. - Separate follow-up bug noted during manual UI validation: accepting a plan on an issue whose run never records `workspace_finalize` is tracked in `PAPA-445` and is not part of this PR’s fix scope. ## Risks - This adds a new migration and a large Drizzle snapshot update; reviewers should confirm the schema shape and generated metadata match the intended decomposition table. - The exact-once claim changes sit on the accepted-plan fan-out path, so regressions there could block legitimate child creation or mis-handle retries if the claim state machine is wrong. - The new UI only appears when decomposition records exist; reviewers should use the manual verification path above rather than expecting existing issues on a stale local instance to show the section automatically. - `PAPA-445` remains an open follow-up for the `workspace_finalize` accept gate when a planning handoff never records finalize; that bug can interfere with reproducing the UI flow on isolated workspaces but does not change the correctness of the exact-once decomposition feature itself. > Checked `ROADMAP.md`: this PR is a bug fix / control-plane hardening change for accepted-plan decomposition, not a new uncoordinated roadmap feature. ## Model Used - OpenAI Codex via Paperclip `codex_local` (GPT-5-based coding agent; exact backend model ID/context window not exposed in the run context), with repository tool use, shell execution, and code-editing capabilities. <img width="806" height="1069" alt="Screenshot 2026-05-27 at 11 05 48 PM" src="https://github.com/user-attachments/assets/5b00b670-96cd-4470-b0a3-581743bcae28" /> ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [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: Paperclip <noreply@paperclip.ing>
## Thinking Path > - Paperclip relies on CI browser suites to protect control-plane workflows, so a stalled browser bootstrap is a release blocker even when app code is unchanged. > - The failing signal on [PAPA-457](/PAP/issues/PAPA-457) was specific to the PR e2e lane timing out before tests started, which pointed at environment setup rather than assertions. > - The first shell-only Chromium attempt reduced download size, but the GitHub Actions log showed Playwright still hanging inside its install step after the headless shell download finished. > - That means the real problem is the Playwright browser-install path itself on the hosted Ubuntu runner, not just the size of the downloaded artifact. > - GitHub's Ubuntu runners already ship Google Chrome, and Playwright can target that binary through the `chrome` channel without downloading its own Chromium bundle. > - The safer workflow fix is therefore to remove the Playwright install step from the affected headless jobs and make the Playwright configs optionally use runner Chrome only when CI opts into it. > - This keeps local defaults unchanged, removes the failing browser-download dependency from CI, and preserves headless coverage for PR, standalone e2e, and release-smoke workflows. ## What Changed - Updated `.github/workflows/pr.yml`, `.github/workflows/e2e.yml`, and `.github/workflows/release-smoke.yml` to stop downloading Playwright browsers and instead verify the runner's preinstalled `google-chrome`. - Passed `PAPERCLIP_PLAYWRIGHT_CHANNEL=chrome` into the headless PR, standalone e2e, and release-smoke test steps so those jobs explicitly use runner Chrome. - Updated `tests/e2e/playwright.config.ts` and `tests/release-smoke/playwright.config.ts` to honor `PAPERCLIP_PLAYWRIGHT_CHANNEL` while keeping the default local/browser-bundle behavior unchanged when the env var is absent. ## Verification - Investigated the failed PR run log and confirmed the prior `Install Playwright` step stalled after `chromium-headless-shell` reached 100% download. - `PLAYWRIGHT_BROWSERS_PATH="$(mktemp -d)" PAPERCLIP_PLAYWRIGHT_CHANNEL=chrome PAPERCLIP_E2E_SKIP_LLM=true pnpm run test:e2e` Result: `7 passed (21.1s)` with an empty temporary Playwright browser cache, proving the e2e suite runs without any Playwright browser download when the `chrome` channel is selected. - `git diff --check` ## Risks - This assumes GitHub's Ubuntu runner continues to ship `google-chrome`; if that image contract changes, these workflows would need a dedicated Chrome install step. - The `chrome` channel can differ slightly from Playwright-managed Chromium, so the config gate is intentionally env-scoped to CI workflows that need the hosted-runner path. ## Model Used - OpenAI Codex, GPT-5-based coding agent running through Paperclip's `codex_local` adapter with tool use, shell execution, and repository editing enabled. The exact internal snapshot/version string is not exposed in-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 run tests locally and they pass - [ ] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
…clipai#6969) ## Thinking Path > - Paperclip orchestrates AI agents across isolated execution workspaces; the local cwd is the only persistence boundary between runs. > - Workspace lifecycle (worktree_prepare → execute → workspace_finalize) and the wake/accept flow are what guarantee that dependent issues see a consistent worktree. > - PAPA-380 / PAPA-431 / PAPA-432 / PAPA-440 surfaced three holes in that contract: silent env reuse across assignees, dependent wakes firing before finalize, and `issue.interaction.accept` advancing before finalize landed. > - PAPA-441 / PAPA-442 then needed to document the "no remote git" contract and prevent future adapter/runtime code from quietly reintroducing `git push` as a backdoor sync. > - This pull request lands those server fixes, the static `check-no-git-push` enforcement, the AUTHORING.md cross-link, and the Cody-review follow-ups on the PAPA-430 thread. > - The benefit is that finalize is a real barrier — board accepts, dependent wakes, and operator-set env all respect it — and adapter code can't bypass it via raw `git push`. ## What Changed - **server (PAPA-380, PAPA-431):** `execution-workspace-policy` refuses silent env reuse when the assignee's resolved env disagrees with the workspace it would inherit. The inheritance protection is now scoped to the actual inheritance signal — explicit issue-level `environmentId` is honored even when the agent's default env is `null`. - **server (PAPA-432):** `heartbeat.ts` gates dependent wakes on `listUnfinalizedExecutionWorkspaceIds`, and writes a `workspace_finalize` row on the succeeded path. Write failures now surface instead of being swallowed so dependents aren't silently stranded behind a missing row. - **server (PAPA-440):** `issue-thread-interactions.acceptInteraction` adds a workspace_finalize precondition for `request_confirmation` (not `suggest_tasks`). Accept returns 409 if finalize hasn't succeeded for the latest workspace operation. - **ci (PAPA-442):** new `scripts/check-no-git-push.mjs` static check scans `packages/adapters/`, `packages/adapter-utils/`, `server/src/`, and `cli/src/` for any `git push` invocation (string or args-array). Wired into the `policy` PR job and `test:release-registry`. Operators can opt in per-call with `// paperclip:allow-git-push: <reason>`. Release scripts are out of scope by design. - **docs (PAPA-441):** `AUTHORING.md` documents the no-remote-git contract and cross-links the static check so adapter authors learn the rule and the enforcement together. - **review follow-up (PAPA-430, Cody):** three fixes — env resolver bug, accept-gate scope (request_confirmation only), and finalize record write on the succeeded path. ## Verification - `pnpm exec vitest run server/src/__tests__/execution-workspace-policy.test.ts server/src/__tests__/issue-thread-interactions-service.test.ts` → 33/33 pass - `node scripts/check-no-git-push.test.mjs` → check covers string form, args-array form, comment exclusions, and per-line allow-comment. - Manual: server compiles; the policy job runs the check in <1s before heavier jobs. ## Risks - **Behavioral shift in accept:** boards accepting `request_confirmation` while finalize is in-flight now get 409s. This is intentional — they can retry — but it changes timing on a hot path. `suggest_tasks` is unaffected. - **Workspace policy:** the env-reuse refusal is a new error path. Issues that previously silently reused an env from a different-assignee workspace will now fail-loud; the resolver still honors explicit issue-level `executionWorkspaceSettings.environmentId`. - **CI rule:** any future legitimate `git push` in scoped dirs must be marked with the allow-comment, which is the intended ergonomic. ## Model Used - Claude Opus 4.7 (`claude-opus-4-7`, extended thinking), via Claude Code in the Paperclip executor adapter. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots (N/A — server/CI/docs only) - [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 Closes related issues: PAPA-430, PAPA-380, PAPA-431, PAPA-432, PAPA-440, PAPA-441, PAPA-442 --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
## Thinking Path > - Paperclip orchestrates AI-agent companies through adapter-backed local and external runtimes. > - The agent configuration UI lets operators choose adapter models and refresh model lists when adapters support live discovery. > - Codex already had a live refresh path, but Claude Local only exposed static fallback models and the UI hid the refresh action for Claude. > - A newly available Claude Opus model should not require a code release every time the model catalog changes. > - This pull request adds Anthropic model discovery for Claude Local, keeps the static fallback current with Claude Opus 4.8, and exposes the existing refresh button in the Claude Local dropdown. > - The benefit is that operators can refresh Claude models from the same model selector flow they already use for Codex. ## What Changed - Added `claude-opus-4-8` to the Claude Local fallback model list. - Added Claude model discovery through Anthropic-compatible `GET /v1/models` when `ANTHROPIC_API_KEY` is available. - Added normal cache reuse, forced refresh support, a SHA-256-based API-key fingerprint for cache keys, and warning logging for discovery errors before fallback. - Wired `claude_local.refreshModels` into the server adapter registry. - Enabled the existing `Refresh models` dropdown action for `claude_local` in `AgentConfigForm`. - Added tests for Claude fallback, live discovery, API-failure fallback, forced refresh, and the UI refresh-button gate. ## Verification - `pnpm exec vitest run server/src/__tests__/adapter-models.test.ts` - `pnpm exec vitest run ui/src/components/AgentConfigForm.test.ts` - `pnpm --filter @paperclipai/adapter-claude-local typecheck` - `pnpm --filter @paperclipai/server typecheck` - `pnpm --filter @paperclipai/ui typecheck` - Greptile review reached Confidence Score: 5/5 on commit `b796cf4f1` with addressed threads resolved. UI note: the visible change is a conditional action row inside the existing model dropdown; the regression test covers that `claude_local` now receives the refresh action. ## Risks - Low risk. Without `ANTHROPIC_API_KEY`, Claude Local still uses the static fallback list. - If Anthropic model discovery fails or times out, Paperclip falls back to the existing cached or static list. - Bedrock environments remain on Bedrock-native model IDs. ## Model Used OpenAI GPT-5 via Codex local coding agent, with repository file access, shell command execution, git operations, and targeted test/typecheck verification. Exact context window is not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] If this change affects the UI, I have included before/after screenshots - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge
## Release changelog: v2026.529.0 Stable changelog for the **v2026.529.0** release (released 2026-05-29), generated with the `release-changelog` skill. - Range: `v2026.525.0..origin/master` — 11 squash-merged PRs - Adds `releases/v2026.529.0.md` - **No breaking changes** — migrations are additive (`CREATE TABLE IF NOT EXISTS`); the only `DROP CONSTRAINT` lines are FK adjustments, not data loss - **No external contributors** this cycle — all PR authors are Paperclip founders, who are excluded from the Contributors section per the skill, so that section is omitted ### Highlights - Inline document annotations and comments (paperclipai#6733) - Company skills CLI and catalog management (paperclipai#6782) - Hide projects and agents from your sidebar (paperclipai#6677) - First-admin claim flow for fresh self-hosted deployments (paperclipai#6755) - Live Claude model discovery (paperclipai#6953) ### Improvements - Bundled plugins now appear in the plugin manager (paperclipai#6734) - Tighter workspace lifecycle guarantees (paperclipai#6969) ### Fixes - Accepted plans decompose exactly once (paperclipai#6831) Docs-only (README brand/license paperclipai#6810, paperclipai#6804) and CI-only (paperclipai#6967) changes were excluded as not materially user-facing. Issue: PAP-10155 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Paperclip <noreply@paperclip.ing>
… key handling (PAPA-407) (paperclipai#7025) ## Thinking Path > - Paperclip orchestrates AI agents and provisions sandboxed execution environments for them; one of those provisioners is the exe.dev plugin, which runs each agent inside a long-lived VM reached over SSH. > - The instance-config form for that plugin is rendered generically by `JsonSchemaForm` from the plugin's `instanceConfigSchema`, so any UX problem with the form is split between the shared form component and the plugin's schema/runtime code. > - Users coming in cold hit a 12-field flat config they couldn't reason about (PAPA-407), a form that silently submitted `cpu: 0` for untouched optional fields (PAPA-407 root cause), a `sshPrivateKey` textarea that truncated RSA-4096 keys at 4096 chars (PAPA-449), a save flow that accepted clearly-malformed keys and only blew up at lease time with raw SSH stderr (PAPA-450, PAPA-451), and a manifest that didn't distinguish "essential" from "advanced" knobs (PAPA-410 / PAPA-411 — duplicate sub-issues with identical scope; PAPA-418 reconciliation kept PAPA-410 canonical). > - These problems all point at the same surface (exe.dev sandbox config) and are tightly coupled in code — PAPA-449/450/451 patch fields that PAPA-410/411 introduce — so they get reviewed together. > - This pull request lands the shared-form changes (advanced-options disclosure, optional-scalar defaults) and the exe.dev-specific changes (manifest restructure, longer `maxLength`, stderr translation, save-time key validation) as five focused commits stacked on `master`. > - The benefit is a config form that defaults to the two fields a new user actually needs (API key + SSH private key) with a collapsible disclosure for the rest, no silent truncation or zero-default submissions, and SSH key problems surfaced at save time with actionable messages instead of cryptic post-provision failures. ## What Changed - **JsonSchemaForm advanced-options disclosure** (PAPA-410, PAPA-411 — same scope, see note above): adds `x-paperclip-advanced` / `x-paperclip-group` schema annotations and renders flagged fields behind a collapsible "Advanced options" disclosure that auto-opens when a hidden field has a validation error. Exe.dev manifest is restructured to use the new annotations, so essentials (`apiKey`, `sshPrivateKey`) show by default while the long tail of optional knobs is grouped under "SSH access" / "VM resources" / "More options" headings. - **Omit optional scalar defaults** (PAPA-407): `getDefaultForSchema` no longer materialises `0` / `""` for optional `number`/`integer`/`string`/`secret-ref` fields without an explicit `default`. Object recursion drops properties whose default is `undefined`. Fields that declare a `default` (e.g. `sshPort: 22`) still round-trip. Adds a regression test against `getDefaultValues`. - **Raise `sshPrivateKey` `maxLength`** (PAPA-449): bumps the exe.dev manifest cap from 4096 to 8192 so RSA-4096 OpenSSH private keys (which can exceed 4 KB with comments/metadata) aren't silently truncated at submit. - **Translate `invalid format` SSH stderr** (PAPA-450): `formatSshFailure` now recognises `Load key … invalid format` in combined stderr/stdout and returns a specific message naming the key-format problem ("isn't an OpenSSH/PEM private key — confirm the secret starts with `-----BEGIN … PRIVATE KEY-----` and isn't the `.pub` or a PuTTY `.ppk` export") instead of dumping the raw stderr. - **Save-time SSH key validation** (PAPA-451): `onEnvironmentValidateConfig` inline-parses `sshPrivateKey` and rejects common failure modes — pasted public keys, PuTTY `.ppk` format, missing `-----END-----` footer, non-base64 body — so the form surfaces an inline error before any VM is provisioned. Secret-ref bindings (UUIDs) are still passed through unchanged. ## Verification CI gates (`pnpm typecheck`, `pnpm test`, the targeted vitest suites below) all pass. Run locally: ```bash # Shared form pnpm --filter @paperclipai/ui exec vitest run src/components/JsonSchemaForm # 9 tests pass — includes the new "omits optional scalar fields" regression # and the three advanced-options-disclosure tests. # exe.dev plugin cd packages/plugins/sandbox-providers/exe-dev && pnpm test # 32 tests pass — includes the new sshPrivateKey-validation cases # and the new "invalid format" stderr-translation case. ``` Manual smoke (after reinstalling the plugin so the DB manifest refreshes): 1. Open the exe.dev environment config page. **Default view shows API Key + SSH Private Key only**, with an "Advanced options" disclosure for everything else (PAPA-410 / PAPA-411). 2. Paste a `.pub` file's contents into SSH Private Key, click Save. **Inline error** rejecting the wrong-format key (PAPA-451). 3. Re-paste a valid OpenSSH/PEM private key longer than 4096 bytes — saves cleanly (PAPA-449). 4. Save the form with everything optional left blank — server no longer rejects with `"cpu must be greater than 0 when provided"` (PAPA-407). 5. Force a bad key through via a stored secret-ref binding and lease a VM — failure message names the key-format problem instead of dumping raw SSH stderr (PAPA-450). ## Risks - **PAPA-410 / PAPA-411 manifest restructure** is the largest surface here. Schemas using `x-paperclip-*` extensions are forward-compatible with stricter JSON Schema validators (extensions are ignored by default), and the form gracefully renders a flat layout when no field opts in. - **PAPA-407** changes form-default behaviour: optional scalar fields that previously round-tripped as `""` / `0` will now be `undefined` and absent from the submitted payload. Downstream consumers that expected the empty-string/zero shape need to treat the field as optional. Spot-checked the existing exe.dev driver — it already uses `parseOptionalString` / `parseOptionalInteger`, which treat missing fields as `null` rather than `0`/`""`. - **PAPA-451** adds a save-time check, so a previously-saved-but-malformed `sshPrivateKey` raw value will now fail to re-save. Bound secret-refs are unaffected, matching how the user reaches the bad-key state today (via the secrets picker). - **PAPA-449** simply raises a cap; no semantic risk. - **PAPA-450** only kicks in on the "invalid format" code path; existing onboarding-marker branch is untouched. ## Model Used - Provider: Anthropic - Model: Claude Opus 4.7 (`claude-opus-4-7`) - Capabilities used: code reading, code editing, test execution, git/PR mechanics, Paperclip API for issue coordination ## Checklist - [x] PR body sections present (Thinking Path, What Changed, Verification, Risks, Model Used, Checklist) - [x] Unit tests added for the new behaviours (JsonSchemaForm default-value omission + advanced disclosure; exe.dev plugin validation + stderr translation) - [x] Existing tests still pass locally (`vitest run` on both packages) - [x] No raw secrets, IP addresses, or machine-local config in commits or PR body - [x] Commits are atomic per linked issue (PAPA-410 / PAPA-411, PAPA-407, PAPA-449, PAPA-450, PAPA-451) - [x] Branch is up-to-date with `origin/master` --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Paperclip <noreply@paperclip.ing>
…#7031) ## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies. > - The recovery subsystem is responsible for keeping assigned work moving when a live heartbeat run disappears or fails. > - `continuation_recovery` is the path that re-enqueues stranded `in_progress` issues after an interrupted continuation attempt. > - That path recently gained cause-aware retry classes and transient retry caps, but the streak counter was still aggregating mixed failure causes into one retry history. > - That meant a sequence like `timeout -> timeout -> adapter_failed -> adapter_failed` could escalate as a false `3x adapter_failed` streak even though the latest cause had only happened twice. > - This pull request makes continuation retry streaks count only consecutive failures whose `errorCode` matches the latest run and adds a regression test for the mixed-cause case. > - The benefit is that transient retry backoff and escalation now match the actual current failure cause instead of inheriting stale budget from unrelated failures. ## What Changed - Updated `summarizeRecentContinuationRetries(...)` to stop counting as soon as the continuation failure cause no longer matches the latest run's `errorCode`. - Wired the continuation recovery escalation/backoff path to pass the latest classified `errorCode` into the retry streak summarizer. - Added a regression test proving mixed-cause continuation failures do not consume the transient retry cap for a new failure cause. ## Verification - `pnpm exec vitest run server/src/__tests__/heartbeat-process-recovery.test.ts` ## Risks - Low risk. The behavioral change is intentionally narrow, but any future continuation retry modes that rely on `errorCode = null` will now be counted as a separate streak bucket and should be kept in mind when adding new retry classifications. ## Model Used - OpenAI Codex via Paperclip `codex_local` (GPT-5-based Codex coding agent; exact backend revision is not surfaced in the runtime), with tool use, shell execution, and patch application in the local repository. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] 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: Paperclip <noreply@paperclip.ing>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merge 11 upstream commits that landed in
paperclipai/paperclipsince our last sync. Clean merge — 0 conflicts. Levi retains all 22 fork-specific commits (kimi-local adapter, OPEA-18 review, etc.).What lands
Bug fixes / security (recommended priority)
scripts/check-no-git-push.mjsFeatures
packages/skills-catalogDocs / chore
Conflict status
0 conflicts. Upstream Claude-model-refresh (paperclipai#6953) and Leviʼs kimi-fallback patches both touch
claude-localbut at non-overlapping regions.Files
165 files changed, +55,570 / −859 (most of this is the new
packages/skills-catalog+ storybook fixtures from paperclipai#6782).Test plan
pnpm install && pnpm -r buildpnpm paperclipai runboots, UI loads🤖 Generated with Claude Code