paperclip/server/src/services
Devin Foley 90631b09b3
Let adapters declare runtime command spec for remote provisioning (#5141)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies, running
adapter
> commands like `claude`, `codex`, `pi` either locally or on remote
runtimes
>   (SSH hosts, sandboxes, etc.)
> - On a fresh remote runtime — particularly an ephemeral sandbox — the
> adapter's CLI may not be installed yet. Today operators handle this
via
> external configuration (e.g. a project-level `provisionCommand` shell
> script) that has to know about every adapter the operator might want
to use
> - This means every adapter has its own well-known npm package, but
operators
>   end up writing duplicate provision shell scripts that paste together
> `npm install -g @anthropic-ai/claude-code`, `npm install -g
@openai/codex`,
>   etc. — knowledge the adapter itself already has
> - This PR moves that knowledge into the adapter modules: each adapter
declares
> how its runtime command should be detected and (if applicable)
installed
> via `getRuntimeCommandSpec(config)`. The execution path runs the
adapter's
> own install command on remote sandbox targets before launching, so a
fresh
> sandbox bootstraps itself instead of requiring a hand-written
provision script
> - The benefit is fewer footguns for operators provisioning remote
runtimes,
>   and a clean place for new adapters to plug in their install recipe

## What Changed

- New types in `packages/adapter-utils/src/types.ts`:
    - `AdapterRuntimeCommandSpec` describing `command`, optional
      `detectCommand`, and optional `installCommand`
    - Optional `getRuntimeCommandSpec(config)` on `ServerAdapterModule`
- Optional `runtimeCommandSpec` on `AdapterExecutionContext` so adapters
      receive the resolved spec at execute time
- New helper `ensureAdapterExecutionTargetRuntimeCommandInstalled(...)`
in
`packages/adapter-utils/src/execution-target.ts` that runs the install
command
on remote targets when `transport === "sandbox"`. SSH and local targets
are
  no-ops. Throws on timeout or non-zero exit so failures surface early.
- Each of `claude-local`, `codex-local`, `cursor-local`, `gemini-local`,
  `opencode-local`, `pi-local`'s `execute.ts` now reads
`ctx.runtimeCommandSpec?.installCommand` and calls the helper before
launching
  the adapter command.
- `server/src/adapters/registry.ts` declares `getRuntimeCommandSpec` for
each
  adapter:
- claude/codex/gemini/opencode/pi-local: `npm install -g <package>`
recipe via
a shared `buildNpmRuntimeCommandSpec` helper, with a defensive guard
that
only auto-installs when the configured `command` matches the well-known
      fallback (custom binaries are left alone).
- cursor-local: declares `command` only; no auto-install (no public npm
      package), preserving the existing manual setup.
- `server/src/services/heartbeat.ts` resolves the spec via
`adapter.getRuntimeCommandSpec?.(runtimeConfig)` and passes it through
to
  `AdapterExecutionContext`.
- Tests added in `execution-target.test.ts` (~75 lines), e2b
`plugin.test.ts` (~32 lines), and `environment-run-orchestrator.test.ts`
  (~76 lines).

## Verification

- `pnpm --filter @paperclipai/adapter-utils test`
- `pnpm --filter @paperclipai/server test --
environment-run-orchestrator`
- `pnpm --filter @paperclipai/sandbox-providers-e2b test`
- Manual QA: run an adapter (claude/codex/etc.) against a fresh
sandbox-backed
environment that does NOT have the adapter CLI pre-installed. Confirm
the
install runs once at the start of the agent run and the adapter then
launches
successfully. Re-run on the same sandbox; confirm the install command is
  idempotent and the second run starts faster.
- Confirm SSH and local execution paths are unaffected (gated by
  `transport === "sandbox"`).

## Risks

- Behavioural shift on sandbox runs: a new install step now runs at the
start
  of every sandbox agent run for adapters with `installCommand` set. The
install commands are idempotent (`if ! command -v X >/dev/null 2>&1;
then
npm install -g <pkg>; fi`), so this is fast on warm sandboxes. On a cold
  sandbox, the first run takes longer.
- Operators who used the legacy project-level `provisionCommand` to
install
adapter CLIs can drop that part of their script; the adapter handles it
now.
  Existing scripts continue to work — installs are idempotent.
- The cursor-local adapter has no auto-install (no public npm package).
  Behaviour for cursor-local on sandboxes is unchanged.
- New optional surface on `ServerAdapterModule`. Plugins that don't
implement
  `getRuntimeCommandSpec` retain previous behaviour (no auto-install).

## Model Used

- OpenAI GPT-5.4 (reasoning effort: high) via Codex CLI
- Provider: OpenAI
- Used to author the code changes in this PR

## 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
- [ ] I have updated relevant documentation to reflect my changes — N/A
- [x] I have considered and documented any risks above
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-05-03 18:35:36 -07:00
..
recovery [codex] Add issue monitor liveness controls (#4988) 2026-05-03 08:58:53 -05:00
access.ts [codex] Add access cleanup and user profile page (#4088) 2026-04-20 06:10:20 -05:00
activity-log.ts [codex] Add plugin orchestration host APIs (#4114) 2026-04-20 08:52:51 -05:00
activity.ts Add sandbox environment support (#4415) 2026-04-24 12:15:53 -07:00
adapter-plugin-store.ts [codex] Add runtime lifecycle recovery and live issue visibility (#4419) 2026-04-24 15:50:32 -05:00
agent-instructions.ts chore: mark bootstrapPromptTemplate as deprecated 2026-03-26 11:12:25 -05:00
agent-permissions.ts Implement agent hiring, approval workflows, config revisions, LLM reflection, and sidebar badges 2026-02-19 13:02:41 -06:00
agent-start-lock.ts [codex] Add runtime lifecycle recovery and live issue visibility (#4419) 2026-04-24 15:50:32 -05:00
agents.ts Add SSH environment support (#4358) 2026-04-23 19:15:22 -07:00
approvals.ts Add username log censor setting 2026-03-20 08:50:00 -05:00
assets.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
board-auth.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
budgets.ts Sync/master post pap1497 followups 2026 04 15 (#3779) 2026-04-15 21:13:56 -05:00
companies.ts [codex] Split backend control-plane QoL slice (#4700) 2026-04-28 16:46:45 -05:00
company-export-readme.ts fix: link Agent Company to agentcompanies.io in export README 2026-03-20 08:06:04 -05:00
company-member-roles.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
company-portability.ts Switch OpenCode to explicit static/local-aware model selection (#5117) 2026-05-03 13:01:34 -07:00
company-skills.ts [codex] Reject stale company skill refreshes (#4601) 2026-04-27 13:19:38 -05:00
costs.ts Add workflow interaction cancellation and issue cost summaries (#4862) 2026-04-30 13:57:25 -05:00
cron.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
dashboard.ts [codex] Harden heartbeat scheduling and runtime controls (#4223) 2026-04-21 12:24:11 -05:00
default-agent-instructions.ts Add default agent instructions bundle 2026-03-20 07:42:36 -05:00
documents.ts [codex] Add run liveness continuations (#4083) 2026-04-20 06:01:49 -05:00
environment-config.ts Generalize sandbox provider core for plugin-only providers (#4449) 2026-04-24 18:03:41 -07:00
environment-execution-target.ts Migrate SSH environment callback to bridge (#5116) 2026-05-03 12:43:52 -07:00
environment-probe.ts Add sandbox environment support (#4415) 2026-04-24 12:15:53 -07:00
environment-run-orchestrator.ts Add sandbox callback bridge for remote environment API access (#4801) 2026-04-29 16:37:34 -07:00
environment-runtime.ts Migrate SSH environment callback to bridge (#5116) 2026-05-03 12:43:52 -07:00
environments.ts Add sandbox environment support (#4415) 2026-04-24 12:15:53 -07:00
execution-workspace-policy.ts Add SSH environment support (#4358) 2026-04-23 19:15:22 -07:00
execution-workspaces.ts Add SSH environment support (#4358) 2026-04-23 19:15:22 -07:00
feedback-redaction.ts Add feedback voting and thumbs capture flow 2026-04-02 09:11:49 -05:00
feedback-share-client.ts Restore feedback trace export fixes 2026-04-03 15:59:42 -05:00
feedback.ts Restore feedback trace export fixes 2026-04-03 15:59:42 -05:00
finance.ts Sync/master post pap1497 followups 2026 04 15 (#3779) 2026-04-15 21:13:56 -05:00
github-fetch.ts fix: harden GHE URL detection and extract shared GitHub helpers 2026-04-01 21:05:48 +00:00
goals.ts Improve onboarding defaults and issue goal fallback 2026-03-12 08:50:31 -05:00
heartbeat-run-summary.ts [codex] Add run liveness continuations (#4083) 2026-04-20 06:01:49 -05:00
heartbeat-stop-metadata.test.ts [codex] Retry max-turn exhausted heartbeats (#5096) 2026-05-03 11:30:48 -05:00
heartbeat-stop-metadata.ts [codex] Retry max-turn exhausted heartbeats (#5096) 2026-05-03 11:30:48 -05:00
heartbeat.ts Let adapters declare runtime command spec for remote provisioning (#5141) 2026-05-03 18:35:36 -07:00
hire-hook.ts fix(adapters): honor paused overrides and isolate UI parser state 2026-04-04 14:04:33 -05:00
inbox-dismissals.ts Persist non-issue inbox dismissals 2026-04-09 06:16:05 -05:00
index.ts [codex] Split backend control-plane QoL slice (#4700) 2026-04-28 16:46:45 -05:00
instance-settings.ts [codex] Add configurable liveness auto-recovery controls (#4587) 2026-04-27 08:46:44 -05:00
invite-grants.ts feat: implement multi-user access and invite flows (#3784) 2026-04-17 09:44:19 -05:00
issue-approvals.ts refactor: rename packages to @paperclipai and CLI binary to paperclipai 2026-03-03 08:45:26 -06:00
issue-assignment-wakeup.ts fix: close remaining routine merge blockers 2026-03-20 16:40:27 -05:00
issue-continuation-summary.ts [codex] Add run liveness continuations (#4083) 2026-04-20 06:01:49 -05:00
issue-execution-policy.ts [codex] Add issue monitor liveness controls (#4988) 2026-05-03 08:58:53 -05:00
issue-goal-fallback.ts Seed onboarding project and issue goal context 2026-03-24 11:48:59 -05:00
issue-liveness.ts [codex] Add runtime lifecycle recovery and live issue visibility (#4419) 2026-04-24 15:50:32 -05:00
issue-references.ts Add first-class issue references (#4214) 2026-04-21 10:02:52 -05:00
issue-thread-interactions.test.ts [codex] Add structured issue-thread interactions (#4244) 2026-04-21 20:15:11 -05:00
issue-thread-interactions.ts Add workflow interaction cancellation and issue cost summaries (#4862) 2026-04-30 13:57:25 -05:00
issue-tree-control.ts [codex] Split backend control-plane QoL slice (#4700) 2026-04-28 16:46:45 -05:00
issues.ts Honor reuse-existing preference and assignee default environment in issue runs (#5139) 2026-05-03 18:33:55 -07:00
json-schema-secret-refs.ts Generalize sandbox provider core for plugin-only providers (#4449) 2026-04-24 18:03:41 -07:00
live-events.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
local-service-supervisor.ts fix: harden heartbeat and adapter runtime workflows 2026-04-10 22:26:21 -05:00
plugin-capability-validator.ts Add sandbox environment support (#4415) 2026-04-24 12:15:53 -07:00
plugin-config-validator.ts Refactor secret-ref format registration to use a UI hint for Paperclip secret UUIDs 2026-03-14 15:43:56 -07:00
plugin-database.ts [codex] Add plugin orchestration host APIs (#4114) 2026-04-20 08:52:51 -05:00
plugin-dev-watcher.ts Tighten plugin dev file watching 2026-03-14 12:07:04 -05:00
plugin-environment-driver.ts Improve E2B plugin configuration UX and fix execution timeouts (#4802) 2026-04-29 17:12:30 -07:00
plugin-event-bus.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-host-service-cleanup.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-host-services.ts Add sandbox environment support (#4415) 2026-04-24 12:15:53 -07:00
plugin-job-coordinator.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-job-scheduler.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-job-store.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-lifecycle.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-loader.ts [codex] Add plugin orchestration host APIs (#4114) 2026-04-20 08:52:51 -05:00
plugin-log-retention.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-manifest-validator.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-registry.ts Simplify plugin runtime and cleanup lifecycle 2026-03-13 16:58:29 -05:00
plugin-runtime-sandbox.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-secrets-handler.ts Generalize sandbox provider core for plugin-only providers (#4449) 2026-04-24 18:03:41 -07:00
plugin-state-store.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-stream-bus.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-tool-dispatcher.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-tool-registry.ts Add plugin framework and settings UI 2026-03-13 16:22:34 -05:00
plugin-worker-manager.ts [codex] Add plugin orchestration host APIs (#4114) 2026-04-20 08:52:51 -05:00
productivity-review.ts [codex] Bound productivity review recovery loops (#4948) 2026-05-01 08:32:04 -05:00
project-workspace-runtime-config.ts [codex] Respect manual workspace runtime controls (#4125) 2026-04-20 10:39:37 -05:00
projects.ts Add SSH environment support (#4358) 2026-04-23 19:15:22 -07:00
quota-windows.ts feat(costs): add billing, quota, and budget control plane 2026-03-16 15:11:01 -05:00
routines.ts [codex] Add workspace routine run tab (#4958) 2026-05-01 11:58:15 -05:00
run-continuations.ts [codex] Add runtime lifecycle recovery and live issue visibility (#4419) 2026-04-24 15:50:32 -05:00
run-liveness.ts [codex] Add runtime lifecycle recovery and live issue visibility (#4419) 2026-04-24 15:50:32 -05:00
run-log-store.ts [codex] Add runtime lifecycle recovery and live issue visibility (#4419) 2026-04-24 15:50:32 -05:00
sandbox-provider-runtime.ts Generalize sandbox provider core for plugin-only providers (#4449) 2026-04-24 18:03:41 -07:00
secrets.ts Add project-level environment variables 2026-04-06 21:23:30 -05:00
sidebar-badges.ts Persist non-issue inbox dismissals 2026-04-09 06:16:05 -05:00
sidebar-preferences.ts [codex] Improve workspace runtime and navigation ergonomics (#3680) 2026-04-14 12:57:11 -05:00
work-products.ts Address remaining Greptile workspace review 2026-03-17 10:12:44 -05:00
workspace-operation-log-store.ts Add workspace operation tracking and fix project properties JSX 2026-03-17 09:36:35 -05:00
workspace-operations.ts [codex] Improve agent runtime recovery and governance (#4086) 2026-04-20 06:19:48 -05:00
workspace-realization.ts Add sandbox environment support (#4415) 2026-04-24 12:15:53 -07:00
workspace-runtime-read-model.ts Fix workspace runtime state reconciliation 2026-04-04 17:48:54 -05:00
workspace-runtime.ts [codex] Respect manual workspace runtime controls (#4125) 2026-04-20 10:39:37 -05:00