Commit Graph

17 Commits

Author SHA1 Message Date
Devin Foley 4518f272b2 fix(release): publish all remaining @paperclipai workspace packages from CI + guard unpublishable edges (#8365)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work, distributed primarily via the `paperclipai` npm package and its
`@paperclipai/*` workspace packages.
> - The release subsystem (`scripts/release-package-*`) decides which
workspace packages CI republishes at the unified calver version each
release, and `replaceWorkspaceDeps()` rewrites every internal
`workspace:` dependency to that calver version at publish time.
> - The gap: a package that publishes from CI can declare a `workspace:`
dependency on a package that is NOT enrolled for CI publish. The
dependency spec gets rewritten to a calver version that is never
actually published, so the dependent becomes uninstallable.
> - This shipped for real: a recent change made `@paperclipai/server`
depend on `@paperclipai/skills-catalog`, but skills-catalog was not on
the calver release train — so canary builds after that merge failed to
resolve `@paperclipai/skills-catalog@<calver>` and `npx
paperclipai@canary run` broke.
> - This PR addresses it durably by (a) putting every remaining internal
package on the CI release train so no internal dependency can dangle,
and (b) adding a fail-fast guard so this class of break can never ship
again.
> - The benefit is that canary and stable installs resolve all internal
dependencies, and any future unpublishable workspace edge fails the
release build with a clear, named error instead of producing a broken
package.

## Linked Issues or Issue Description

Refs #8327 (introduced the `server -> skills-catalog` runtime dependency
that surfaced the gap).

No public issue tracks this; describing it in-PR:

- **Problem:** After #8327, `npx paperclipai@canary run` failed for
builds past the merge because `@paperclipai/skills-catalog` was
rewritten to a calver version that was never published (the package was
not enrolled for CI publish). Versions before the merge still ran.
- **Root cause:** A `publishFromCi:true` package can declare a
`workspace:` dependency on a package that is not `publishFromCi:true`;
the release-time version rewrite then points at a non-existent published
version.

## What Changed

- Enrolled every remaining internal package on the calver release train
by setting `publishFromCi: true` in
`scripts/release-package-manifest.json`: `skills-catalog`,
`teams-catalog`, `plugin-workspace-diff`, `plugin-kubernetes`,
`plugin-novita-sandbox`. There are now zero `publishFromCi:false`
entries.
- `skills-catalog`, `teams-catalog`, `plugin-workspace-diff` already
existed on npm — CI simply republishes them at calver.
- `plugin-kubernetes` and `plugin-novita-sandbox` were not on npm; their
one-time first publish was bootstrapped so the
`check-release-package-bootstrap` gate passes.
- Added `findUnpublishableWorkspaceEdges()` to
`scripts/release-package-map.mjs`, wired into
`buildReleasePackagePlan()`. The release map build now fails fast
(surfaced by the `check` CI already runs) whenever a
`publishFromCi:true` package declares a runtime `workspace:` dependency
(`dependencies`/`optionalDependencies`/`peerDependencies`) on a
non-`publishFromCi:true` `@paperclipai/*` package, naming the offending
edge.
- Added tests covering positive/negative detection, all three dependency
sections, unknown-package edges, off-train edges, and the live manifest.

## Verification

- `node --test scripts/release-package-map.test.mjs` → 9/9 pass
(includes a test asserting the live manifest has no unpublishable
edges).
- `node scripts/check-release-package-bootstrap.mjs
scripts/release-package-manifest.json` → passes, naming all five
newly-enabled packages (all confirmed present on npm).
- Confirmed via `npm view` that all five packages resolve on the public
registry.

## Risks

- Low risk. The change only enrolls already-existing (or
freshly-bootstrapped) packages onto the existing release train and adds
a build-time validation. No runtime code paths change. The new guard can
only *fail* a release that was already going to ship a broken package.

## Model Used

Claude Opus 4.7 (claude-opus-4-7), extended thinking, with tool use /
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 and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] If this change affects the UI, I have included before/after
screenshots (N/A — no UI changes)
- [x] I have updated relevant documentation to reflect my changes (N/A —
no doc-facing behavior change)
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge
2026-06-19 19:11:20 -07:00
Alex b18669452f Add Novita sandbox provider plugin (#7595)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip already separates agent adapters from execution
environments, so agents can run locally, over SSH, or through sandbox
providers.
> - Sandbox provider plugins let Paperclip add new cloud runtimes
without changing each agent adapter.
> - Novita Agent Sandbox is a cloud runtime for AI agent workloads with
isolated filesystems, command execution, templates, timeout controls,
and pause/resume behavior.
> - Paperclip currently has sandbox provider examples for Daytona and
Cloudflare, but not Novita.
> - This pull request adds a Novita sandbox provider plugin using the
existing provider-plugin lifecycle.
> - The benefit is that Paperclip users can run existing adapters such
as Codex, Claude, Gemini, OpenCode, Cursor, or ACPX inside Novita Agent
Sandbox environments.

## Linked Issues or Issue Description

Fixes #7596

## What Changed

- Added `packages/plugins/sandbox-providers/novita` as a standalone
sandbox provider plugin package.
- Registered provider key `novita` with `kind: "sandbox_provider"` and
`environment.drivers.register` capability.
- Implemented Novita environment lifecycle hooks: validate config,
probe, acquire lease, resume lease, release lease, destroy lease,
realize workspace, and execute commands.
- Added config support for `apiKey`, `domain`, `template`,
`requestedCwd`, `timeoutMs`, `requestTimeoutMs`, `secure`, `autoPause`,
and `reuseLease`.
- Added README documentation for setup, configuration, and lifecycle
behavior.
- Added tests for manifest shape, config parsing, safe shell command
wrapping, stdin delimiter safety, and env-key validation.

## Verification

From `packages/plugins/sandbox-providers/novita`:

- `pnpm typecheck`
- `pnpm test`

The tests avoid live Novita API calls and cover the provider's static
contract and command-wrapping behavior. Live end-to-end verification
requires a Paperclip instance with the plugin installed and a Novita API
key configured as either a Paperclip secret or `NOVITA_API_KEY` in the
worker environment.

## Risks

- This adds a new direct dependency on the Novita Sandbox JS SDK
(`novita-sandbox`). Socket/Snyk should review the package as part of
normal dependency checks.
- The implementation relies on Novita SDK command execution semantics;
live provider behavior should be verified with a real Novita sandbox
before marking the plugin production-ready.
- `reuseLease` maps Paperclip release behavior to Novita `betaPause()`.
If pause is unavailable for a selected template, the plugin falls back
to best-effort kill during release.
- Low migration risk for existing users because this is a new standalone
provider plugin and does not change existing adapters or built-in
providers.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI GPT-5 Codex via Codex CLI, with repository file access, shell
command execution, GitHub CLI/API usage, and local TypeScript/Vitest
verification. Web and local documentation context were used for Novita
Sandbox SDK/API behavior.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Devin Foley <devin@paperclip.ing>
2026-06-17 18:34:12 -07:00
Jannes Stubbemann 05ab45225a feat(plugin-kubernetes): self-hostable Kubernetes sandbox provider (stage 1/3: plugin package) (#5790)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Sandbox providers are the seam that lets agent runs execute in
isolated environments; today the only first-party remote provider is
Daytona, a hosted third-party service
> - Self-hosters running Paperclip on their own infrastructure (often
Kubernetes already) have no first-party way to run agent sandboxes on a
cluster they control
> - That gap matters for teams with data-residency, sovereignty, or cost
constraints who cannot or will not send workloads to a hosted sandbox
service
> - This pull request adds a Kubernetes sandbox-provider plugin as a
standalone, workspace-excluded package: it implements every
SandboxProvider hook the Daytona provider does, on infrastructure the
operator owns
> - The benefit is that any Paperclip deployment with a Kubernetes
cluster gets multi-tenant, network-isolated, quota-bounded agent
sandboxes with zero new external dependencies

## Linked Issues or Issue Description

No existing issue. Following the feature template:

- **Problem:** Paperclip's remote sandbox execution requires a hosted
third-party provider. Self-hosters cannot run agent sandboxes on their
own Kubernetes clusters with a first-party provider.
- **Proposed solution:** A `@paperclipai/plugin-kubernetes`
sandbox-provider plugin with two backends: long-lived sandboxes via the
[kubernetes-sigs/agent-sandbox](https://github.com/kubernetes-sigs/agent-sandbox)
CRD (multi-command exec, adapter-install pattern) and one-shot
`batch/v1` Jobs (stable APIs only, no extra controllers).
- **Alternatives considered:** Driving kubectl from a generic shell
provider (no lifecycle/lease semantics), or requiring a hosted provider
(exactly the constraint this removes).

## What Changed

This is **stage 1 of 3** of a staged contribution (direction agreed with
maintainers): the plugin package alone. Stage 2 (server integration:
lease params, provider registration) and stage 3 (agent runtime images +
CI) are companion PRs that will be cross-linked from a comment here.

- New package `packages/plugins/sandbox-providers/kubernetes`
(workspace-excluded, like the path already carved out in
`pnpm-workspace.yaml`): src, unit + kind integration tests, operator
prerequisite manifests, README, smoke-test guide
- Implements the full SandboxProvider hook surface the Daytona provider
implements: `validateConfig`, `probe`, `acquireLease`, `resumeLease`,
`releaseLease`, `destroyLease`, `realizeWorkspace`, `execute`
- Two backends: `sandbox-cr` (default; long-lived pod via the
agent-sandbox `Sandbox` CR, supports multi-command exec) and `job`
(one-shot `batch/v1` Job; nothing beyond k8s 1.27+ required)
- Per-run adapter resolution: one environment serves mixed harnesses;
the per-run `adapterType` hint is read through a local optional type
extension, so the plugin typechecks and builds against the current
plugin SDK and simply falls back to the environment's configured default
adapter until stage 2 lands
- Exec-env wrapping: the Kubernetes exec API carries no environment, so
commands are wrapped to receive the run's env
- Fast-upload interception for workspace realization, scoped per lease
- Per-tenant isolation: derived namespace per company, RBAC,
ResourceQuota, restricted-PSS pod security (runAsNonRoot, drop ALL,
seccomp RuntimeDefault, no SA token automount)
- Network egress policy in two flavors: native `NetworkPolicy` and
`CiliumNetworkPolicy` (FQDN allowlists)
- Image allowlist with glob matching, registry override, and per-run
image override validation
- Per-run Kubernetes Secrets carrying agent credentials, ownerRef'd to
the Job or Sandbox CR for cascade GC

## Verification

- Standalone build, exactly as the README documents:
  ```bash
  cd packages/plugins/sandbox-providers/kubernetes
  pnpm install --ignore-workspace
  pnpm test        # 147 unit tests, 17 files, all green
  pnpm typecheck   # clean against the in-repo plugin SDK on master
pnpm build # dist/ emitted, manifest + worker entrypoints present
  ```
- A kind-cluster end-to-end integration test is included
(`RUN_K8S_INTEGRATION_TESTS=1 pnpm test
test/integration/end-to-end-run.test.ts`)
- Beyond CI: this provider has been verified in a production
multi-tenant deployment against five harnesses (opencode, pi, codex,
gemini, claude code) with real billed runs

## Risks

- **Zero behavior change for any existing deployment.** The package is
workspace-excluded; nothing in the server imports or loads it until
stage 2's integration lands. No existing code paths are touched.
- The default `sandbox-cr` backend depends on an alpha CRD
(`agents.x-k8s.io/v1alpha1`); the README flags this and the `job`
backend uses only stable APIs as a fallback.
- Risk surface is confined to deployments that explicitly install and
configure the plugin.
- The default runtime images (`ghcr.io/paperclipai/agent-runtime-*`) are
published by the stage 3 companion PR (#7934); until that lands,
deployments must point `runtimeImage` at their own images.

## Model Used

Claude Opus 4.8 (1M context), extended thinking, with tool use (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 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 (no UI changes)
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green (pending this push)
- [ ] 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: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 21:07:00 -07:00
Dotta fff3832a01 [codex] Add teams catalog extraction (#7550)
Fixes #7551

## Thinking Path

> - Paperclip is the control plane for AI-agent companies, and reusable
company/team setup is part of making those companies faster to launch.
> - The teams catalog work introduces app-shipped team templates that
can be browsed, previewed, and installed into a company.
> - Catalog installation crosses several contracts: bundled package
contents, shared API types, server import/install behavior, CLI
workflows, and the board UI.
> - Agents also need a safe path through catalog installs: scoped
company selection, explicit source policy, approval fallback for agent
creation, and preserved catalog provenance.
> - This pull request extracts the completed teams catalog branch into
one reviewable PR on top of `public-gh/master`.
> - The benefit is a reusable teams catalog foundation with server, CLI,
package, docs, and hidden UI surfaces kept in sync.

## What Changed

- Added the `@paperclipai/teams-catalog` package with bundled/optional
team definitions, generated manifest, validators, catalog builder tests,
and migration notes.
- Added shared teams catalog types/validators plus server routes and
services for listing, previewing, and installing catalog teams.
- Integrated catalog install with company portability, skill/source
policy checks, provenance metadata, origin hashes, target-manager
reparenting, and installed/out-of-date detection.
- Added CLI `teams` commands and agent-safe company selection behavior,
including `company current` and approval fallback for forbidden
agent-run installs.
- Added hidden Team Catalog UI/API/query surfaces, Storybook fixtures,
and targeted UI tests while keeping the UI route out of primary
navigation.
- Added docs for CLI/company/teams catalog behavior and removed
generated screenshot artifacts from the PR diff.

## Verification

- `pnpm exec vitest run cli/src/__tests__/company.test.ts
cli/src/__tests__/teams.test.ts
packages/teams-catalog/src/catalog-builder.test.ts
packages/teams-catalog/src/shipped-catalog.test.ts
server/src/__tests__/agent-permissions-service.test.ts
server/src/__tests__/company-portability.test.ts
server/src/__tests__/company-skills-service.test.ts
server/src/__tests__/teams-catalog-routes.test.ts
server/src/__tests__/teams-catalog-service.test.ts
server/src/__tests__/teams-catalog-install-no-overrides.test.ts
ui/src/lib/company-routes.test.ts ui/src/pages/TeamCard.test.tsx
ui/src/pages/TeamCatalog.test.tsx
ui/src/pages/useInstallTeamCatalogEntry.test.tsx`
- `pnpm --filter @paperclipai/shared typecheck && pnpm --filter
@paperclipai/teams-catalog typecheck && pnpm --filter paperclipai
typecheck && pnpm --filter @paperclipai/server typecheck && pnpm
--filter @paperclipai/ui typecheck`
- Confirmed branch is rebased onto `public-gh/master` (`78dc3625a`) and
`public-gh/master` is an ancestor of `HEAD`.
- Confirmed PR diff excludes `pnpm-lock.yaml`, `.github/workflows/*`,
generated screenshot images, and screenshot helper scripts.

## Risks

- Medium review surface: this crosses package generation, shared
contracts, server install behavior, CLI, docs, and hidden UI code.
- Catalog install behavior creates agents/projects/tasks/skills and must
keep company scoping, permissions, source policy, and provenance checks
strict.
- `pnpm-lock.yaml` is intentionally excluded per repo policy;
CI/default-branch automation owns lockfile refresh.
- The Team Catalog UI is included but hidden from primary navigation, so
future enablement should re-check visual QA before exposure.

> 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 checked: this aligns with reusable companies/templates and
plugin-adjacent onboarding work. This PR packages work already developed
on the Paperclip task branch for review.

## Model Used

- OpenAI Codex, GPT-5 series coding agent in this Paperclip session;
exact runtime context window was not exposed. Used shell, git, `gh`, and
local test/typecheck tooling.

## 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, or documented why screenshots are intentionally omitted
- [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>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 12:55:49 -05:00
Dotta 9eac727cf1 [codex] Add skills CLI and catalog management (#6782)
## 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>
2026-05-28 07:33:51 -10:00
Devin Foley 988689947a fix(release): publish modal plugin from ci (#6290)
## Thinking Path

> - Paperclip keeps its core release process declarative through
`scripts/release-package-manifest.json`, which decides which packages CI
is allowed to publish.
> - The Modal sandbox provider now exists as a first-party plugin
package under `packages/plugins/sandbox-providers/modal`.
> - The original Modal PR intentionally left `publishFromCi` disabled
until the package had been published and the registry bootstrap concern
was cleared.
> - The latest reviewer comment confirms that bootstrap step is
complete, so the remaining gap is only release automation configuration.
> - This pull request flips the Modal manifest entry to `publishFromCi:
true` so future CI-driven releases can publish
`@paperclipai/plugin-modal` the same way the other releasable packages
do.
> - The benefit is that Modal releases no longer require a manual
exception in the release pipeline.

## What Changed

- Updated the `@paperclipai/plugin-modal` entry in
`scripts/release-package-manifest.json` to set `publishFromCi` to
`true`.

## Verification

- Ran `node -e 'const
m=require("./scripts/release-package-manifest.json"); const
e=m.find(x=>x.name==="@paperclipai/plugin-modal");
if(!e||e.publishFromCi!==true){throw new Error("modal publishFromCi not
true")}; console.log(JSON.stringify(e))'`

## Risks

- Low risk. This only changes release-manifest metadata; the main
failure mode is CI attempting to publish the Modal package before
registry credentials or release conditions are ready.

## Model Used

- OpenAI Codex local agent, GPT-5-based coding model in the Codex
runtime (exact deployment model ID not exposed in this workspace), with
tool use and shell 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 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
2026-05-18 09:42:01 -07:00
Devin Foley 4b1e92a588 feat(plugins): add Modal sandbox provider plugin (#6245)
## Thinking Path

> - Paperclip orchestrates AI agents through company-scoped
control-plane workflows and extensible runtime integrations.
> - Sandbox providers are part of that extension surface because they
let agents execute isolated work without baking each provider into the
core server.
> - Modal already offers managed sandboxes with filesystem, process,
timeout, and networking controls that map onto Paperclip's sandbox
provider contract.
> - The repo did not have a Modal provider plugin, so teams wanting
Modal-backed sandboxes had no first-party integration path.
> - This pull request adds a standalone
`packages/plugins/sandbox-providers/modal` plugin that implements the
provider contract, worker entrypoint, docs, and tests.
> - The benefit is that Modal can now be installed as a provider plugin
without expanding the core control-plane surface area.

## What Changed

- Added a new `packages/plugins/sandbox-providers/modal` package with
the plugin manifest, worker entrypoint, and exported plugin surface.
- Implemented Modal-backed sandbox lifecycle support for creation,
command execution, file operations, networking options, termination, and
metadata translation.
- Added focused Vitest coverage for config validation, env handling,
lifecycle flows, networking behavior, and error mapping.
- Documented installation, configuration, and usage requirements in the
plugin README.
- Removed misleading `MODAL_TOKEN_*` fallback behavior so authentication
relies on supported Modal credentials only.

## Verification

- `pnpm -r typecheck`
- `pnpm test:run`
- `pnpm build`
- `cd packages/plugins/sandbox-providers/modal && pnpm test`

## Risks

- Low to medium risk: this is isolated to a new plugin package, but
runtime behavior still depends on live Modal account credentials and
service-side sandbox semantics.
- Modal's current docs target a newer Node baseline than the repo
default, so the first live install should confirm credential loading and
sandbox startup behavior in a real Modal workspace.
- No UI or schema changes are included in this PR.

> 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 via Paperclip `codex_local` agent (GPT-5-class Codex
coding model; exact backend model ID is not exposed by the runtime),
with tool use, shell execution, and code-editing capabilities enabled.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have 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>
2026-05-18 08:36:34 -07:00
Dotta 5071c4c776 [codex] Add workspace diff viewer plugin (#6071)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies.
> - Operators need to inspect what agents changed inside execution and
project workspaces.
> - The existing workspace detail views did not provide a first-party
rich diff surface for staged, unstaged, head, renamed, binary,
oversized, and untracked changes.
> - The plugin system is the intended extension point for optional rich
UI surfaces.
> - This pull request adds a workspace diff plugin plus host services
and shared contracts so Changes tabs can render workspace diffs through
plugin slots.
> - The diff-renderer dependency should stay owned by the plugin package
rather than the core UI app.
> - The dependency surface must stay aligned with repository PR policy,
including intentionally omitting `pnpm-lock.yaml` from the PR.
> - The benefit is a more reviewable workspace surface without
hard-coding the renderer into every page.

## What Changed

- Added `@paperclipai/plugin-workspace-diff`, including diff
normalization, plugin manifest/worker/UI entrypoints, and focused plugin
tests.
- Kept `@pierre/diffs` scoped to `@paperclipai/plugin-workspace-diff`;
removed the core UI lab diff-renderer surface and direct UI package
dependency.
- Added shared workspace diff types and validators, plus plugin SDK
surface for workspace diff host services.
- Added server workspace diff service support and route coverage for
execution/project workspace diff flows.
- Wired Execution Workspace and Project Workspace Changes tabs to load
the diff plugin, including loading/error fallback behavior.
- Added UI tests and fixtures for the Changes tabs and plugin bridge
behavior.
- Added the new plugin package manifest to the Docker deps stage so PR
policy can validate dependency coverage.
- Addressed review hardening around empty untracked patches, workspace
path exposure, project workspace read capability checks, and default
base refs.

## Verification

- `pnpm --filter @paperclipai/plugin-workspace-diff test`
- `pnpm exec vitest run
packages/shared/src/validators/workspace-diff.test.ts
server/src/__tests__/workspace-diff-service.test.ts
ui/src/pages/ProjectWorkspaceDetail.test.tsx
ui/src/pages/ExecutionWorkspaceDetail.test.tsx`
- `pnpm exec vitest run ui/src/plugins/bridge.test.ts
server/src/__tests__/workspace-runtime-routes-authz.test.ts`
- `pnpm --filter @paperclipai/shared typecheck`
- `pnpm --filter @paperclipai/plugin-workspace-diff typecheck`
- `pnpm --filter @paperclipai/server typecheck`
- `pnpm --filter @paperclipai/ui typecheck`
- `node ./scripts/check-docker-deps-stage.mjs`
- Browser screenshot captured from the local worktree dev server:
https://files.catbox.moe/ofdpsp.png
- Confirmed branch is rebased onto `public-gh/master`,
`.github/workflows/pr.yml` is not included in the PR diff,
`ui/package.json` is not included in the PR diff, and `pnpm-lock.yaml`
is not included in the PR diff.

## Risks

- Medium UI integration risk: the Changes tab depends on the plugin slot
and host diff service path.
- Medium dependency risk: this adds `@pierre/diffs` in the plugin
package, but `pnpm-lock.yaml` is intentionally omitted per packaging
instructions because repository automation manages lockfile updates.
- Current CI blocker: downstream frozen installs fail until the
repository policy path for new plugin package dependencies is chosen.
- Diff rendering edge cases are covered for common working-tree and head
diff states, but very large repositories may still expose performance
limits.
- No migrations are included.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5 class coding model, tool-enabled local execution
environment. Exact context window was not exposed by the runtime.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have 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>
2026-05-18 08:50:06 -05:00
Dotta 7bbdfb69df [codex] Enable Grok adapter canary publishing (#6154)
## Thinking Path

> - Paperclip publishes its CLI, server, UI, and adapter packages
through the shared release workflow.
> - Canary releases are driven by the GitHub release workflow on pushes
to `master`.
> - The release workflow does not publish every public package
automatically; it uses `scripts/release-package-manifest.json` as the CI
enrollment source of truth.
> - The Grok adapter is public and already present in the manifest, but
its `publishFromCi` flag was still disabled.
> - Because of that flag, normal canary publishes skipped
`@paperclipai/adapter-grok-local` even when the main package received a
canary.
> - This pull request enables Grok in the release manifest so future
canary runs include it.
> - The benefit is that Grok adapter canaries stay aligned with the rest
of the package release set.

## What Changed

- Set `packages/adapters/grok-local` / `@paperclipai/adapter-grok-local`
to `publishFromCi: true` in `scripts/release-package-manifest.json`.

## Verification

- `node ./scripts/release-package-map.mjs check`
- `node ./scripts/release-package-map.mjs list | grep
'@paperclipai/adapter-grok-local'`
- `pnpm test:release-registry`

## Risks

- Low risk: this is a release manifest-only change.
- Future canary releases will attempt to publish
`@paperclipai/adapter-grok-local`; this assumes the package remains
publishable and trusted publishing/package access are correctly
configured for the existing npm package.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

- OpenAI Codex, GPT-5-based coding agent with shell, git, and GitHub
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 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>
2026-05-16 20:34:28 -05:00
Devin Foley ab8b471685 Add built-in grok_local adapter (#6087)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies, so
adapter quality directly affects what runtimes the control plane can
supervise.
> - Local CLI adapters are one of the core execution surfaces because
they turn real coding tools into Paperclip-managed employees with
heartbeats, transcripts, and reviewability.
> - Grok Build was installed on the Paperclip host, but Paperclip had no
built-in `grok_local` adapter, so the runtime could not be configured
through the normal server/UI/CLI adapter path.
> - That gap needed to be closed with the same built-in registry,
environment diagnostics, transcript parsing, and skill/instructions
behavior that the other local adapters already rely on.
> - After the initial adapter landed, a real follow-up run showed that
Grok streaming text was being rendered one fragment per line, which made
transcripts harder to read even though the runtime itself was working.
> - This pull request adds the built-in `grok_local` adapter end-to-end
and then fixes the transcript parser so streamed Grok output is
coalesced into readable assistant/thinking blocks.
> - The benefit is that Grok Build becomes a first-class Paperclip
runtime with a usable operator experience instead of a partially wired
runtime with noisy transcript output.

## What Changed

- Added a new built-in `@paperclipai/adapter-grok-local` package with
server, UI, and CLI entrypoints.
- Implemented Grok execution, session handling, environment diagnostics,
config building, skill syncing, and parser coverage inside the new
adapter package.
- Registered `grok_local` across the built-in adapter inventories and
capability/display metadata in server, UI, CLI, and shared constants.
- Added adapter route coverage for the new built-in type.
- Fixed Grok transcript readability by emitting streamed `text` and
`thought` fragments as deltas so the shared transcript builder coalesces
them into readable message blocks.
- Added regression tests for the Grok parser and transcript coalescing
behavior.

## Verification

- `pnpm vitest run
packages/adapters/grok-local/src/ui/parse-stdout.test.ts
ui/src/adapters/transcript.test.ts`
- `pnpm --filter @paperclipai/adapter-grok-local build`
- Manual runtime verification on the Paperclip host during
implementation and follow-up review:
  - confirmed the Grok CLI was installed and authenticated
- confirmed the worktree dev server could be restarted cleanly and
health-checked after the parser follow-up
- No screenshots attached. This change is primarily adapter plumbing
plus transcript formatting behavior; reviewers can verify via the
Grok-backed run surfaces directly.

## Risks

- This adds a new built-in adapter, so any missed registration surface
could create inconsistencies between server, UI, and CLI behavior.
- The adapter depends on Grok Build's current event/output shape; if
upstream Grok streaming JSON changes, transcript parsing or session
extraction may need follow-up updates.
- The transcript readability fix intentionally changes how Grok
fragments are grouped, so any downstream code that implicitly expected
one entry per fragment would behave differently.

> 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 via Paperclip `codex_local` agent runtime.
- GPT-5-class coding model with tool use, shell execution, file editing,
and repo inspection enabled.
- Exact backend model ID/context window were not surfaced to the agent
in this Paperclip 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
- [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
2026-05-16 09:51:09 -07:00
Devin Foley eaa80cf88b Enable CI publishing for cursor-cloud, cloudflare, and exe.dev release packages (#5728)
## Thinking Path

> - Paperclip orchestrates AI agents, and its release flow depends on
explicit package enrollment for automated publishing.
> - The release registry tooling uses
`scripts/release-package-manifest.json` as the source of truth for which
public packages CI is allowed to publish.
> - The cursor cloud adapter plus the Cloudflare and exe.dev sandbox
plugins are public packages that now need to ship through the normal CI
release path.
> - Leaving those entries at `publishFromCi: false` keeps release
automation and registry validation out of sync with the intended package
set.
> - This pull request updates only those three manifest entries and
leaves the release tooling itself unchanged.
> - The benefit is that CI release enrollment now matches the packages
we intend to publish, with the existing manifest checks continuing to
guard correctness.

## What Changed

- Enabled CI publishing for `@paperclipai/adapter-cursor-cloud` in
`scripts/release-package-manifest.json`.
- Enabled CI publishing for `@paperclipai/plugin-cloudflare-sandbox` in
`scripts/release-package-manifest.json`.
- Enabled CI publishing for `@paperclipai/plugin-exe-dev` in
`scripts/release-package-manifest.json`.

## Verification

- `node ./scripts/release-package-map.mjs check`
- `pnpm test:release-registry`

## Risks

- Low risk. This is a manifest-only change, but a wrong enrollment flag
would affect release automation, so the release-registry checks are the
main guardrail.

## Model Used

- OpenAI GPT-5.4 via Paperclip `codex_local` (`adapterConfig.model:
gpt-5.4`), high reasoning effort, with tool use and shell/code
execution. The adapter does not expose a separate context-window value
in 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 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
2026-05-11 11:47:07 -07:00
Devin Foley 5a64cf52a1 Add exe.dev sandbox provider plugin (#5688)
> _Stacked on top of #5685#5686#5687. Diff against master includes
commits from earlier PRs in the stack — review focuses on the two new
commits (`Add long-secret textarea variant to JsonSchemaForm
SecretField` + `Add exe.dev sandbox provider plugin`)._

## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Each agent runs in a sandbox environment, and operators choose the
provider — today E2B, Daytona, and (in this stack) Cloudflare
> - exe.dev offers per-VM sandboxes via a small CLI / HTTP API — useful
for operators who want full Linux VMs (vs container/runtime-only
sandboxes)
> - The plugin shape mirrors the e2b plugin: lifecycle hooks (`new`,
`ls`, `rm`) drive exe.dev's CLI; SSH plumbing handles direct VM access
for adapters that need it
> - exe.dev VMs come up bare — `node` is not preinstalled, so the
Paperclip sandbox callback bridge (a Node script) needs Node 20
installed at VM init via `--setup-script`. The plugin defaults the setup
script to a Nodesource install
> - The auth field accepts long SSH private keys, which need a textarea
variant of the existing `SecretField` in `JsonSchemaForm` — added behind
a `maxLength > THRESHOLD` opt-in so other secret fields are unaffected
> - The benefit is that operators get exe.dev as a fully working sandbox
provider out of the box, with no manual VM provisioning required

## What Changed

**Shared UI support (`Add long-secret textarea variant to JsonSchemaForm
SecretField`):**

- `ui/src/components/JsonSchemaForm.tsx` + new
`JsonSchemaForm.test.tsx`: when a secret-formatted field declares
`maxLength` larger than the existing single-line threshold, render a
monospace textarea instead of the masked input. Short secrets (API keys,
tokens) keep the existing masked-input + show/hide toggle behavior.

**The exe.dev plugin (`Add exe.dev sandbox provider plugin`):**

- `packages/plugins/sandbox-providers/exe-dev/`: plugin entry, manifest,
plugin runtime, README, and 19-test Vitest suite.
- Manifest fields: API token (with `secret-ref` + `/exec` permission
notes — needs `new`, `ls`, `rm`), API URL override, optional SSH
username, optional SSH private key (uses the new `JsonSchemaForm`
textarea variant via `maxLength: 4096`), optional SSH identity-file
path, optional setup script.
- Default `--setup-script` is a Nodesource Node 20 install. exe.dev VMs
come up bare and the Paperclip sandbox callback bridge is a Node script,
so without Node preinstalled the bridge can't start. Operators can
override by supplying their own setup script.
- `runLifecycleCommand` redacts env values from the executed command
before surfacing it in error messages, so secrets passed via
`--env=KEY=VALUE` don't leak into operator-visible failures.
- The plugin distinguishes exe.dev's SSH onboarding failures (`Please
complete registration by running: ssh exe.dev`) from general SSH
failures and surfaces a clear remediation message.
- `scripts/release-package-manifest.json`: register the new plugin for
CI publish alongside the existing daytona / e2b providers.

## Verification

- `pnpm typecheck`
- `pnpm exec vitest run --no-coverage
ui/src/components/JsonSchemaForm.test.tsx`
- `(cd packages/plugins/sandbox-providers/exe-dev && pnpm test)` — 19
passing

For an operator-side smoke test:

1. Get an exe.dev API token with `/exec` permission for `new`, `ls`,
`rm`.
2. Register the plugin in your Paperclip instance, configure an
environment with the token.
3. Create a sandbox env whose provider is `exe-dev`, then run a Codex or
Claude job against it. The default Node 20 setup script should bring the
VM up automatically.

## Risks

- Adds a new sandbox provider plugin that follows the existing daytona /
e2b shape; behavior on existing providers is unchanged.
- The `JsonSchemaForm` textarea variant only engages for fields that opt
in via `maxLength` larger than the existing threshold. All existing
secret fields (which don't declare a `maxLength`) keep their current
rendering. Test coverage pins both paths.
- The redaction in `runLifecycleCommand` is a defense-in-depth measure;
the test suite exercises the redaction path. If the redaction misses a
future env-arg shape, the worst case is restored behavior (secrets in
error messages), which is what the existing daytona / e2b plugins also
do today.
- Default setup script downloads from `deb.nodesource.com` over HTTPS at
VM init. Operators on air-gapped networks or with a different package
strategy can override the setup script.

## Model Used

- Provider: Anthropic
- Model: Claude Opus 4.7 (1M context)
- Capabilities used: extended reasoning, tool use (Read/Edit/Bash/Grep)

## 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 — UI change is a textarea variant of an existing secret
field; will attach screenshots before requesting merge
- [x] I have updated relevant documentation to reflect my changes
(plugin README, manifest descriptions)
- [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>
2026-05-11 07:42:18 -07:00
Devin Foley 486fb88a15 Add Cloudflare sandbox provider plugin (#5687)
> _Stacked on top of #5685#5686. Diff against master includes commits
from earlier PRs in the stack — review focuses on the two new commits
(`Extend sandbox callback bridge for Worker-hosted plugins` + `Add
Cloudflare sandbox provider plugin`)._

## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Each agent runs in a sandbox environment, and operators choose which
provider backs that sandbox — today E2B and Daytona are bundled with the
platform
> - Cloudflare Workers + Durable Objects + the Sandbox SDK offer a
credible new option: globally distributed, cheap idle, and
operator-deployable as a single Worker
> - To plug it in, Paperclip needs (a) a provider plugin that speaks the
`PaperclipPluginManifestV1` lifecycle and (b) a small operator-deployed
Worker — the **bridge** — that adapts Paperclip's runtime RPCs to the
Cloudflare Sandbox SDK
> - The plugin extends the existing sandbox-callback-bridge with a
`bridge.transport: "worker"` discriminator so the platform routes
runtime RPCs through the Worker bridge instead of the in-process runner
> - This pull request adds the plugin, the bridge Worker template, and
the supporting adapter-utils + server hooks the new transport needs
> - The benefit is that operators can run sandboxes on Cloudflare's edge
with no new platform code beyond installing the plugin and deploying the
Worker

## What Changed

**Shared support (`Extend sandbox callback bridge for Worker-hosted
plugins`):**

- `packages/adapter-utils/src/sandbox-callback-bridge.{ts,test.ts}`:
expose `expectedHostHeader` so plugin-side bridge clients can verify the
canonical request envelope before forwarding.
- `packages/adapter-utils/src/command-managed-runtime.{ts,test.ts}`:
relax the always-fresh runner construction so callers can re-use a
runner across exec calls (Worker-hosted bridges hold the runner inside a
Durable Object).
- `server/src/services/environment-runtime.ts` +
`environment-runtime.test.ts`: route Worker-hosted bridges through the
same env-shaping path as E2B and pin the `requestEnv` contract.
- `server/src/services/plugin-environment-driver.ts`: thread an optional
`issueId` through the runtime descriptor so bridges can scope leases to
the originating issue (used by Cloudflare to map a sandbox to the
issue/workflow for billing and audit).
- `packages/plugins/sdk/src/protocol.ts`: add `issueId?` to
`PluginEnvironmentDriverBaseParams` and the new `bridge.transport:
"worker"` discriminator that the new plugin declares.
- `server/__tests__/heartbeat-plugin-environment.test.ts`: pin the
heartbeat path against the new runtime descriptor.

**The Cloudflare plugin itself (`Add Cloudflare sandbox provider
plugin`):**

- `packages/plugins/sandbox-providers/cloudflare/`: plugin entry,
manifest, plugin runtime (lifecycle + bridge client), config parsing,
and Vitest coverage. Manifest declares `bridge.transport: "worker"` so
the platform routes runtime RPCs through the bridge client.
- `bridge-template/`: a Worker template the operator deploys with
`wrangler`. Owns Durable Object-backed sessions (`sessions.ts`),
exec/stream routes (`exec.ts`, `routes.ts`), and an HMAC auth layer
(`auth.ts`) that pins the `Host` header surface. Includes the
SDK-contract-correct exec implementation, lease recovery, and chunked
stdout/stderr streaming.
- Tests cover lease/session handoff (`bridge-template/src/exec.test.ts`,
`routes.test.ts`), bridge client request shaping
(`src/bridge-client.test.ts`), and end-to-end plugin behavior
(`src/plugin.test.ts`) including streamed exec output. 27 tests in
total.
- `README.md` walks the operator through deploying the bridge Worker,
registering the plugin, and configuring the runtime.

## Verification

- `pnpm typecheck`
- `pnpm exec vitest run --no-coverage
packages/adapter-utils/src/sandbox-callback-bridge.test.ts
packages/adapter-utils/src/command-managed-runtime.test.ts
server/src/__tests__/environment-runtime.test.ts
server/src/__tests__/heartbeat-plugin-environment.test.ts`
- `(cd packages/plugins/sandbox-providers/cloudflare && pnpm test)` — 27
passing

For an operator-side smoke test:

1. Deploy the bridge: `cd
packages/plugins/sandbox-providers/cloudflare/bridge-template &&
wrangler deploy`
2. Register the plugin in your Paperclip instance, point its bridge URL
at the deployed Worker, set the HMAC shared secret.
3. Create a sandbox environment whose provider is `cloudflare`, then run
a Codex or Claude job against it.

## Risks

- Adds a new `bridge.transport: "worker"` code path, but the existing
E2B / Daytona transports go through the same shaped helpers and have
explicit test coverage that pins their behavior unchanged.
- The Worker bridge stores session state in a Durable Object; operator
instances must be aware of the corresponding Cloudflare costs (DO
requests, storage). Documented in the README.
- The `issueId` plumbing is optional throughout — existing plugins that
don't supply it continue to work.

## Model Used

- Provider: Anthropic
- Model: Claude Opus 4.7 (1M context)
- Capabilities used: extended reasoning, tool use (Read/Edit/Bash/Grep)

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [ ] If this change affects the UI, I have included before/after
screenshots — N/A, no UI change
- [x] I have updated relevant documentation to reflect my changes
(plugin README, bridge-template README)
- [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>
2026-05-11 07:33:13 -07:00
Devin Foley 534aee66ae Add cursor_cloud adapter for Cursor SDK + Cloud Agents API v1 (#5664)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - There are many adapter types, one per agent-runtime product (Claude,
Codex, OpenCode, Cursor local CLI, etc.)
> - Cursor shipped a public TypeScript SDK on 2026-04-29 that exposes
Cursor's full hosted-agent platform (cloud VMs, harness, MCP, skills,
hooks)
> - Paperclip had no first-class adapter for this — agents that wanted
to use Cursor's managed cloud runtime had to fall back to the local CLI
adapter, which loses the cloud session, streaming, and durable run model
> - This PR adds a new `cursor_cloud` adapter built directly on
`@cursor/sdk`, with Paperclip's heartbeat mapped to Cursor's
durable-agent + per-run model
> - The benefit is that any Paperclip agent can now drive a Cursor cloud
agent across heartbeats with native session reuse, streaming, and
cancellation, while Paperclip remains the source of truth for issue/task
state

## What Changed

- New built-in adapter package `packages/adapters/cursor-cloud` (15
files, ~1.7k LOC) backed by `@cursor/sdk` ^1.0.12
- `src/server/execute.ts` — SDK-first lifecycle: `Agent.create` /
`Agent.resume` / `Agent.getRun` / `agent.send` / `run.stream` /
`run.wait`, with session reuse keyed on the (runtime env type, env name,
repo set) tuple
- `src/server/session.ts` — codec for `cursorAgentId` + `latestRunId` +
repo metadata, persisted in `runtime.sessionParams`
- `src/server/test.ts` — environment probe via `Cursor.me()` and
optional model validation via `Cursor.models.list()`
- `src/ui/parse-stdout.ts` + `src/cli/format-event.ts` — normalize
Cursor SDK message types (`status`, `thinking`, `assistant`, `user`,
`tool_call`, `tool_result`, `result`) into Paperclip transcript events
for the UI and CLI
- Registrations: `packages/shared/src/constants.ts`,
`packages/adapter-utils/src/session-compaction.ts`,
`server/src/adapters/{registry,builtin-adapter-types}.ts`,
`ui/src/adapters/{registry,adapter-display-registry}.ts` +
`ui/src/adapters/cursor-cloud/index.ts`, `cli/src/adapters/registry.ts`,
plus workspace deps in `cli`/`server`/`ui` `package.json`
- `ui/src/components/AgentConfigForm.tsx` — hide local-Cursor
`mode`/thinking-effort field for `cursor_cloud` (different config
surface)
- 11 vitest tests covering execute paths (fresh create, matching-resume,
active-run reattach, non-finished result), session codec round-trip,
transcript parsing, and config building

## Verification

Reviewer steps:

```bash
pnpm install
pnpm --filter @paperclipai/adapter-cursor-cloud typecheck   # → clean
pnpm vitest run packages/adapters/cursor-cloud              # → 11/11 passing
```

End-to-end check against a real Cursor cloud agent (requires
`CURSOR_API_KEY` and Cursor GitHub-app install on the target repo):

1. Create a `cursor_cloud` agent in Paperclip with `repoUrl` set to the
test repo, `repoStartingRef: main`, and `env.CURSOR_API_KEY` set
2. Trigger a heartbeat → adapter calls `Agent.create({ cloud: { env: {
type: "cloud" }, repos: [...] } })`, streams events, terminates on
`finished`
3. Trigger a second heartbeat → adapter calls `Agent.resume` or
`agent.send` follow-up depending on prior-run state, reusing
`cursorAgentId`
4. The Paperclip UI/CLI transcript reflects Cursor `status` / `thinking`
/ `assistant` events as they stream
5. Cancellation from Paperclip maps to `run.cancel()` or Cloud API v1
`cancelRun` for cross-heartbeat cancellation

A direct-SDK smoke run against a real repo (devinfoley/my_test_project @
main) confirmed: `Cursor.me()` ok → `Agent.create` → `agent.send` →
`run.stream()` (30 events) → terminal status `finished` in ~11s.

## Risks

- **New adapter, additive only.** No existing adapter or registry is
replaced; current `cursor` local-CLI adapter is untouched. Default
behavior of any existing agent is unchanged.
- **External dependency on `@cursor/sdk`.** Cursor's SDK is v1.0.x and
may evolve. Mocked unit tests cover the public surface used here; if the
SDK breaks compatibility we update the adapter independently.
- **Cost/budget.** `cursor_cloud` runs on Cursor's billed cloud VMs;
operators must understand they are spending money outside Paperclip's
budget controls when they enable this adapter. Same shape as other
API-billed adapters.
- **No webhook support in V1.** The SDK already provides
stream/wait/cancel/reattach, so V1 does not require a public callback
URL. If a future use case needs out-of-band wakes, we add a Cloud API v1
webhook bridge as a separate change. This is called out in the issue
plan document.
- **Lockfile.** Per repo policy, `pnpm-lock.yaml` is intentionally not
in this PR — CI's lockfile workflow will update it on merge given the
manifest changes.

## Model Used

- Provider: Anthropic Claude (via Claude Code / Paperclip `claude_local`
adapter)
- Model: `claude-opus-4-7` (Claude Opus 4.7), knowledge cutoff January
2026
- Mode: standard tool-use with extended reasoning
- Context: ~200k token window
- Capabilities used: code generation, multi-file edits, shell/test
execution, GitHub PR workflow

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass (11/11 in
`packages/adapters/cursor-cloud`)
- [x] I have added or updated tests where applicable (4 new test files,
11 cases)
- [ ] If this change affects the UI, I have included before/after
screenshots (the only UI change is hiding the local-Cursor mode field on
the `cursor_cloud` adapter — happy to attach a screenshot if the
reviewer wants one)
- [x] I have updated relevant documentation to reflect my changes (issue
plan document supersedes the pre-SDK design; tracked in PAPA-203)
- [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>
2026-05-10 17:21:04 -07:00
Devin Foley 433dfed33d Enable CI publish for plugin-daytona (#5586)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - The release pipeline gates new public packages behind a bootstrap
policy: `scripts/check-release-package-bootstrap.mjs` requires every
package marked `publishFromCi: true` in
`scripts/release-package-manifest.json` to already exist on npm
> - PR #5580 added the new Daytona sandbox provider plugin but had to
land with `publishFromCi: false` because the package had never been
published, so CI's release plan would have failed bootstrap validation
otherwise
> - Now that `@paperclipai/plugin-daytona` has been bootstrap-published
to npm by hand, the temporary `false` flag is the only thing keeping it
out of the standard CI publish flow
> - This pull request flips the Daytona entry to `publishFromCi: true`,
matching every other release-enabled package in the manifest
> - The benefit is that future tagged releases will publish the Daytona
plugin automatically alongside the rest of the monorepo's public
packages

## What Changed

- Single-line flip in `scripts/release-package-manifest.json`:
`@paperclipai/plugin-daytona` is now `publishFromCi: true`

## Verification

- `node ./scripts/release-package-map.mjs check` → `Release package
manifest OK: 19 enabled for CI publish, 0 disabled pending bootstrap`
(was 18 + 1)
- `node ./scripts/check-release-package-bootstrap.mjs
scripts/release-package-manifest.json` against `origin/master` →
`Release bootstrap OK for changed manifests:
@paperclipai/plugin-daytona`, confirming npm sees the
bootstrap-published package
- No code changes; no tests required beyond the existing manifest
validators

## Risks

- Low risk. Only effect is that the next release run will include
`@paperclipai/plugin-daytona` in its publish set
- If the npm bootstrap was incomplete, CI's bootstrap check will fail
loudly before any release tag goes out — same safety net the policy is
designed to provide

## Model Used

- Claude Opus 4.7 (`claude-opus-4-7`), extended thinking, tool use
enabled

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have run tests locally and they pass
- [ ] I have added or updated tests where applicable (N/A —
manifest-only flag flip, covered by existing validators)
- [ ] If this change affects the UI, I have included before/after
screenshots (N/A — release config)
- [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>
2026-05-09 16:58:35 -07:00
Devin Foley 06e6ee25cd Add Daytona sandbox provider plugin (#5580)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Agents need isolated sandbox environments to execute work safely;
Paperclip already supports E2B as a sandbox provider plugin
> - Users want to use Daytona (https://www.daytona.io/) as an
alternative sandbox backend, but no plugin existed for it
> - Without a Daytona plugin, teams that prefer Daytona's
pricing/regions/runtime can't run Paperclip agents on it
> - This pull request adds a `@paperclip/sandbox-provider-daytona`
plugin that mirrors the existing E2B plugin shape and wires up Daytona's
`@daytonaio/sdk` for sandbox lifecycle, command execution, and shell
detection
> - The benefit is that operators can pick Daytona as a first-class
sandbox provider without touching core code, broadening Paperclip's
runtime options

## What Changed

- New plugin package `packages/plugins/sandbox-providers/daytona` with
manifest, worker entry, and provider implementation backed by
`@daytonaio/sdk`
- Implements sandbox create/destroy/exec/upload/download lifecycle,
shell command detection, and config/env wiring consistent with the E2B
plugin
- Adds unit tests under `src/plugin.test.ts` and a README documenting
setup and the `DAYTONA_API_KEY` requirement
- Minor adjustments in `scripts/paperclip-issue-update.sh`,
`packages/shared/src/issue-thread-interactions.test.ts`, and
`packages/shared/src/validators/issue.ts` to support the integration

## Verification

- Re-ran the full sandbox provider matrix on the QA Paperclip instance
using Daytona as the runtime — all 6 adapters executed inside the
Daytona sandbox with zero `environmentExecute` timeouts
- 5/6 adapters pass cleanly (or with informational warns); the only
failure is `codex_local`, which is an OpenAI quota/billing issue
unrelated to Daytona
- `pnpm --filter @paperclip/sandbox-provider-daytona test` runs the
plugin unit tests

## Risks

- New optional plugin; no behavior change for users who don't enable it
- Requires `DAYTONA_API_KEY` for runtime use — documented in the plugin
README
- Daytona SDK is a new external dependency; tracked in the plugin's own
package.json so it doesn't affect the core install footprint

## Model Used

- Claude Opus 4.7 (`claude-opus-4-7`), extended thinking, tool use
enabled

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have 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 — backend plugin)
- [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>
2026-05-09 11:50:12 -07:00
Devin Foley 29401b231b fix(ci): gate new release packages on npm bootstrap (#5146)
## Thinking Path

> - Paperclip is a control plane for autonomous agent companies, so its
release automation is part of the core operator trust boundary.
> - The affected subsystem is npm/GitHub Actions release publishing for
the public monorepo packages.
> - The concrete failure was that a newly added package reached
`master`, the canary workflow attempted its first publish, and npm
trusted publishing was not yet bootstrapped for that package.
> - That means the problem is not just one broken run; it is a missing
pre-merge guard that lets release-ineligible packages land and only fail
once `publish_canary` runs.
> - This pull request makes release enrollment explicit, validates that
enrollment in CI, and adds a PR-time bootstrap check against npm for
changed release-enabled package manifests.
> - The result is that we keep trusted publishing, avoid teaching CI to
`npm adduser`, and move this class of failure from post-merge canary
time to pre-merge review time.

## What Changed

- Added `scripts/release-package-manifest.json` so release-managed
public packages are explicitly enrolled instead of being inferred from
every non-private workspace package.
- Hardened `scripts/release-package-map.mjs` to validate the manifest
before release workflows rewrite versions or assemble publish payloads.
- Added `scripts/check-release-package-bootstrap.mjs` and wired it into
`.github/workflows/pr.yml` so PRs that change a release-enabled package
manifest fail if that package does not already exist on npm.
- Added release-package manifest coverage tests to
`scripts/release-package-map.test.mjs` and included them in `pnpm run
test:release-registry`.
- Wired manifest validation into `.github/workflows/release.yml` and
documented the first-publish bootstrap policy in `doc/PUBLISHING.md` and
`doc/RELEASE-AUTOMATION-SETUP.md`.

## Verification

- `pnpm run test:release-registry`
- `./scripts/release.sh canary --skip-verify --dry-run`
- Confirmed the committed diff contains no obvious PII/secrets via
targeted pattern scan before pushing.

## Risks

- Low risk overall: this is CI/release-policy code, not product runtime
logic.
- The new PR bootstrap check depends on npm metadata availability, so a
transient npm outage could block a PR that changes a release-enabled
package manifest.
- The manifest introduces a new source of truth that must stay aligned
with public package additions, but that is intentional and now enforced.

## Model Used

- OpenAI Codex via the `codex_local` Paperclip adapter; GPT-5-based
coding agent with tool use, terminal execution, git, and GitHub CLI.
Exact served model ID/context window are not exposed by the local
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
2026-05-03 19:31:28 -07:00