Files
PaperClipAI/server/package.json
T
DottaandPaperclip 6080daf262 fix(runner): start native OpenCode without postinstall (#15702)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip Runner starts a qualified OpenCode runtime for native
tasks.
> - The default launch path uses a file populated by OpenCode's
postinstall script.
> - Package managers can skip that script and leave a text placeholder.
Native task startup then fails with `spawn ENOEXEC` before the model
request.
> - This pull request resolves the declared platform package directly
and includes the pinned runtime in the published server dependency
graph.
> - Users can run native OpenCode tasks after a normal install without
global commands or manual dependency repair.

## Linked Issues or Issue Description

**What happened?**

Native OpenCode tasks fail at session startup when dependency
postinstall is skipped. The Runner selects
`opencode-ai/bin/opencode.exe`, which contains a text placeholder. The
published server also lacks the OpenCode runtime dependency used by its
vendored Runner.

**Expected behavior**

Paperclip starts the qualified platform binary installed by the package
manager. macOS uses a Mac binary. No manual postinstall command is
needed.

**Steps to reproduce**

1. Install dependencies with lifecycle scripts disabled.
2. Configure a native OpenCode agent with an OpenRouter model and valid
credentials.
3. Assign a task. The previous default fails before any model request.

Related work: #15682 fixes HTTP transport registration. #15422 includes
compatible OpenCode resolution in a broader agent setup change. This PR
isolates the runtime repair for current users.

## What Changed

- Resolve pinned OpenCode platform packages through the module
dependency graph in source, standalone, and vendored server layouts.
- Check package identity, version, platform, executable containment, and
execute permission. Preserve verified executable launch profiles.
- Use the resolver for new and resumed native sessions. Reject missing
remote pack executables before controller dependency lookup.
- Declare `opencode-ai@1.18.34` as a published server dependency. Leave
platform selection to the consumer's package manager.
- Check remote paths for the selected provider only. An unused OpenCode
path must not reject a Pi run on macOS.
- Add skipped-postinstall and invalid artifact regressions. Document
automatic runtime selection.

## Verification

- Regression tests fail with the previous default path and pass with
platform resolution.
- Source, standalone, and vendored layout fixtures cover Apple Silicon,
Intel Mac, and Linux x64 baseline packages.
- A fresh npm install with `--ignore-scripts` resolves the macOS
executable and reports `1.18.34`. The placeholder remains unchanged.
- Live browser test on Apple Silicon: a native
OpenCode/OpenRouter/DeepSeek task ran shell arithmetic, created and
uploaded a verified 23-byte file, and completed. A follow-up ran shell
arithmetic and completed using the same session. Both runs committed
successfully while the wrapper remained broken.
- `pnpm -r typecheck` and `pnpm build` passed. All 269 affected Runner
tests and 8 server packaging tests passed. `pnpm test:run` encountered
15 initial database-heavy failures; all 15 passed on an isolated group
rerun. The redundant local run was then stopped after the matching
server and workspace CI suites passed. All final-head checks passed (56
passed, 2 skipped); its unrelated chat-retry browser assertion passed on
one rerun. An additional local repeat could not start its temporary
server within the startup timeout. Greptile reviewed the final head at
5/5 with no open findings.

## Risks

- Native runtime resolution requires the pinned optional platform
package. Installations that omit optional dependencies fail with an
explicit runtime error.
- Supported native targets remain Apple Silicon, Intel Mac, and Linux
x64. This change does not qualify another platform.
- Published server installations now install the OpenCode dependency.
Remote provider packs retain their verified executable paths and
digests.
- No schema changes or agent configuration migration.
- Repository policy assigns `pnpm-lock.yaml` to CI. PR CI refreshes
dependency resolution before frozen installs, and the master workflow
updates the tracked lockfile. This PR leaves the tracked lockfile
unchanged.

## Model Used

- OpenAI GPT-6 through Codex, with reasoning, tool use, and code
execution. The session does not expose the exact GPT-6 variant or
context window.
- Live verification used OpenRouter `deepseek/deepseek-v4-flash-0731`;
it did not author this patch.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-09 11:46:15 -05:00

184 lines
5.9 KiB
JSON

{
"name": "@paperclipai/server",
"version": "0.3.1",
"license": "MIT",
"homepage": "https://github.com/paperclipai/paperclip",
"bugs": {
"url": "https://github.com/paperclipai/paperclip/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/paperclipai/paperclip",
"directory": "server"
},
"type": "module",
"exports": {
".": "./src/index.ts"
},
"publishConfig": {
"access": "public",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"files": [
"dist",
"ui-dist",
"skills"
],
"scripts": {
"dev": "tsx src/index.ts",
"dev:watch": "cross-env PAPERCLIP_MIGRATION_PROMPT=never PAPERCLIP_MIGRATION_AUTO_APPLY=true tsx ./scripts/dev-watch.ts",
"prepare:ui-dist": "bash ../scripts/prepare-server-ui-dist.sh",
"build": "pnpm run prepare:runner-vendor && node scripts/verify-runner-vendor-dependencies.mjs && tsc && mkdir -p dist/onboarding-assets dist/built-ins dist/services/scripts dist/vendor/paperclip-runner && cp -R src/onboarding-assets/. dist/onboarding-assets/ && cp -R src/built-ins/. dist/built-ins/ && cp -R src/services/scripts/. dist/services/scripts/ && cp -Rf ../packages/paperclip-runner/dist/. dist/vendor/paperclip-runner/ && node scripts/write-build-stamp.mjs",
"prepack": "pnpm run prepare:ui-dist && pnpm run build",
"postpack": "rm -rf ui-dist",
"clean": "rm -rf dist",
"start": "node dist/index.js",
"prepare:runner-vendor": "pnpm --filter @paperclipai/paperclip-runner build",
"typecheck": "pnpm run prepare:runner-vendor && pnpm --filter @paperclipai/plugin-sdk ensure-build-deps && tsc --noEmit"
},
"dependencies": {
"@agentclientprotocol/codex-acp": "1.6.2",
"ai": "7.0.130",
"@ai-sdk/openai": "4.0.86",
"@openrouter/ai-sdk-provider": "3.1.0",
"@aws-sdk/client-s3": "^3.1141.0",
"@chat-adapter/discord": "4.39.0",
"@chat-adapter/github": "4.39.0",
"@chat-adapter/slack": "4.39.0",
"@chat-adapter/teams": "4.39.0",
"@chat-adapter/telegram": "4.39.0",
"@discordjs/ws": "1.2.3",
"@grpc/grpc-js": "1.14.5",
"@modelcontextprotocol/sdk": "^1.31.0",
"@opentelemetry/api": "^1.9.0",
"@paperclipai/adapter-claude-local": "workspace:*",
"@paperclipai/adapter-codex-local": "workspace:*",
"@paperclipai/adapter-cursor-cloud": "workspace:*",
"@paperclipai/adapter-cursor-local": "workspace:*",
"@paperclipai/adapter-gemini-local": "workspace:*",
"@paperclipai/adapter-grok-local": "workspace:*",
"@paperclipai/adapter-kimi-local": "workspace:*",
"@paperclipai/adapter-openclaw-gateway": "workspace:*",
"@paperclipai/adapter-opencode-local": "workspace:*",
"@paperclipai/adapter-pi-local": "workspace:*",
"@paperclipai/adapter-utils": "workspace:*",
"@paperclipai/db": "workspace:*",
"@paperclipai/hermes-paperclip-adapter": "workspace:*",
"@paperclipai/plugin-sdk": "workspace:*",
"@paperclipai/shared": "workspace:*",
"@paperclipai/skills-catalog": "workspace:*",
"@photon-ai/advanced-imessage": "2.1.0",
"@vercel/connect": "2.3.3",
"acorn": "8.18.0",
"acpx": "0.13.1",
"ajv": "^8.20.0",
"ajv-formats": "^3.0.1",
"better-auth": "1.7.2",
"chat": "4.39.0",
"chokidar": "^5.0.0",
"compression": "^1.8.2",
"detect-port": "^2.1.0",
"dompurify": "^3.4.16",
"dotenv": "^17.4.2",
"drizzle-orm": "^0.45.2",
"embedded-postgres": "^18.1.0-beta.16",
"express": "^5.1.0",
"heif2jpeg": "0.1.6",
"jsdom": "^30.0.1",
"light-my-request": "^6.6.0",
"multer": "^2.4.0",
"nice-grpc": "2.1.17",
"nice-grpc-common": "2.0.4",
"open": "^11.0.4",
"opencode-ai": "1.18.34",
"pino": "^10.0.0",
"pino-http": "^11.0.0",
"pino-pretty": "^13.1.3",
"sharp": "^0.35.4",
"smol-toml": "^1.4.2",
"ssh2": "^1.17.0",
"svix": "1.76.1",
"ws": "^8.22.0",
"zod": "^4.4.3"
},
"bundleDependencies": [
"@agentclientprotocol/codex-acp",
"@chat-adapter/discord",
"@chat-adapter/github",
"@chat-adapter/slack",
"@chat-adapter/teams",
"@chat-adapter/telegram",
"@discordjs/ws",
"acpx"
],
"devDependencies": {
"@paperclipai/paperclip-runner": "workspace:*",
"@types/compression": "^1.8.1",
"@types/express": "^5.0.0",
"@types/express-serve-static-core": "^5.1.3",
"@types/jsdom": "^30.0.0",
"@types/multer": "^2.2.0",
"@types/node": "^24.0.0",
"@types/sharp": "^0.32.0",
"@types/supertest": "^7.2.1",
"@types/ws": "^8.18.2",
"cross-env": "^10.1.0",
"supertest": "^7.0.0",
"tsx": "^4.23.15",
"typescript": "^7.0.2",
"vite": "^8.2.2",
"vitest": "^5.0.3"
},
"peerDependencies": {
"@opentelemetry/auto-instrumentations-node": "0.79.0",
"@opentelemetry/exporter-trace-otlp-grpc": "0.221.0",
"@opentelemetry/exporter-trace-otlp-http": "0.221.0",
"@opentelemetry/exporter-trace-otlp-proto": "0.221.0",
"@opentelemetry/resources": "2.10.0",
"@opentelemetry/sdk-node": "0.221.0",
"@opentelemetry/semantic-conventions": "1.43.0",
"@sentry/node": "10.71.0"
},
"peerDependenciesMeta": {
"@opentelemetry/auto-instrumentations-node": {
"optional": true
},
"@opentelemetry/exporter-trace-otlp-grpc": {
"optional": true
},
"@opentelemetry/exporter-trace-otlp-http": {
"optional": true
},
"@opentelemetry/exporter-trace-otlp-proto": {
"optional": true
},
"@opentelemetry/resources": {
"optional": true
},
"@opentelemetry/sdk-node": {
"optional": true
},
"@opentelemetry/semantic-conventions": {
"optional": true
},
"@sentry/node": {
"optional": true
}
},
"engines": {
"node": ">=24.11.0"
},
"optionalDependencies": {
"@github/copilot-darwin-arm64": "1.0.88",
"@github/copilot-darwin-x64": "1.0.88",
"@github/copilot-linux-x64": "1.0.88"
}
}