Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement โ†’
Sign In

@opencode-cloud/core

Package Overview
Dependencies
Maintainers
1
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@opencode-cloud/core - npm Package Compare versions

Comparing version
4.0.0
to
4.0.1
+1
-1
Cargo.toml
[package]
name = "opencode-cloud-core"
version = "4.0.0"
version = "4.0.1"
edition = "2024"

@@ -5,0 +5,0 @@ rust-version = "1.88"

{
"name": "@opencode-cloud/core",
"version": "4.0.0",
"version": "4.0.1",
"description": "Core NAPI bindings for opencode-cloud (internal package)",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -11,4 +11,9 @@ # opencode-cloud

> [!WARNING]
> This project is a work in progress and evolving rapidly. Use with caution.
A production-ready toolkit for deploying and managing [opencode](https://github.com/anomalyco/opencode) as a persistent cloud service, **sandboxed inside a Docker container** for isolation and security.
This project uses the opencode fork at https://github.com/pRizz/opencode, which adds additional authentication and security features.
## Quick install (cargo)

@@ -23,8 +28,10 @@

[![Deploy to AWS](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?templateURL=https://raw.githubusercontent.com/pRizz/opencode-cloud/main/infra/aws/cloudformation/opencode-cloud-quick.yaml)
[![Deploy to AWS](https://s3.amazonaws.com/cloudformation-examples/cloudformation-launch-stack.png)](https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?templateURL=https://opencode-cloud-templates.s3.us-east-2.amazonaws.com/cloudformation/opencode-cloud-quick.yaml)
Quick deploy provisions a private EC2 instance behind a public ALB with HTTPS.
**A domain name is required** for ACM certificate validation.
**A Route53 hosted zone ID is required** for automated DNS validation.
Docs: `docs/deploy/aws.md` (includes teardown steps)
Docs: `docs/deploy/aws.md` (includes teardown steps and S3 hosting setup for forks)
Credentials: `docs/deploy/aws.md#retrieving-credentials`

@@ -31,0 +38,0 @@ ## Features

@@ -107,4 +107,2 @@ # =============================================================================

dnsutils=1:9.18.* \
# Reverse proxy for opencode UI + API
nginx=1.24.* \
# Compression

@@ -509,3 +507,3 @@ zip=3.0-* \

# - opencode-broker build
# - nginx config for single-endpoint UI + API proxy
# - opencode web build + runtime
# - PAM configuration + systemd services

@@ -522,3 +520,3 @@ # - opencode config file

# Build opencode from source (BuildKit cache mounts disabled for now)
RUN OPENCODE_COMMIT="3a4eccc7e883575e0d5a508f46036a9f243c06e8" \
RUN OPENCODE_COMMIT="9b91eb17f5ca1b0ee99cfaa0b4c87da6dbe9e784" \
&& rm -rf /tmp/opencode-repo \

@@ -532,9 +530,11 @@ && git clone --depth 1 https://github.com/pRizz/opencode.git /tmp/opencode-repo \

&& bun install --frozen-lockfile \
&& bun run packages/opencode/script/build.ts --single \
&& cd packages/app \
&& bun run build \
&& cd packages/opencode \
&& export VITE_OPENCODE_SERVER_URL="http://localhost:3000" \
&& bun run build-single-ui \
&& rm -rf /home/opencode/.bun/install/cache /home/opencode/.bun/cache /home/opencode/.cache/bun \
&& cd /tmp/opencode-repo \
&& mkdir -p /home/opencode/.local/share/opencode/bin \
&& mkdir -p /home/opencode/.local/share/opencode/ui \
&& cp /tmp/opencode-repo/packages/opencode/dist/opencode-*/bin/opencode /home/opencode/.local/share/opencode/bin/opencode \
&& cp -R /tmp/opencode-repo/packages/opencode/dist/opencode-*/ui/. /home/opencode/.local/share/opencode/ui/ \
&& chown -R opencode:opencode /home/opencode/.local/share/opencode \

@@ -547,10 +547,2 @@ && chmod +x /home/opencode/.local/share/opencode/bin/opencode \

# Copy UI assets to standard web root (requires root)
USER root
RUN mkdir -p /var/www/opencode \
&& cp -R /tmp/opencode-repo/packages/app/dist/. /var/www/opencode/ \
&& chown -R root:root /var/www/opencode \
&& chmod 755 /var/www /var/www/opencode \
&& chmod -R a+rX /var/www/opencode
# -----------------------------------------------------------------------------

@@ -577,45 +569,2 @@ # opencode-broker Installation

# -----------------------------------------------------------------------------
# Nginx Reverse Proxy for UI + API
# -----------------------------------------------------------------------------
# Serve the built UI from /var/www/opencode and proxy all 3000 traffic to backend.
RUN rm -f /etc/nginx/sites-enabled/default /etc/nginx/conf.d/default.conf 2>/dev/null || true \
&& printf '%s\n' \
'server {' \
' listen 3000;' \
' server_name _;' \
'' \
' location / {' \
' proxy_pass http://127.0.0.1:3001;' \
' proxy_http_version 1.1;' \
' proxy_set_header Upgrade $http_upgrade;' \
' proxy_set_header Connection "upgrade";' \
' proxy_set_header Host $host;' \
' proxy_set_header X-Real-IP $remote_addr;' \
' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;' \
' proxy_set_header X-Forwarded-Proto $scheme;' \
' }' \
'}' \
'' \
'server {' \
' listen 3002;' \
' server_name _;' \
'' \
' root /var/www/opencode;' \
' index index.html;' \
'' \
' location /assets/ {' \
' try_files $uri =404;' \
' }' \
'' \
' location ~* \.(?:js|css|png|jpg|jpeg|gif|svg|ico|webp|woff2?|ttf|map)$ {' \
' try_files $uri =404;' \
' }' \
'' \
' location / {' \
' try_files $uri $uri/ /index.html;' \
' }' \
'}' \
> /etc/nginx/conf.d/opencode.conf
# -----------------------------------------------------------------------------
# PAM Configuration

@@ -699,3 +648,3 @@ # -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Create opencode as a systemd service for Cockpit integration (backend only)
# Create opencode as a systemd service for Cockpit integration
# NOTE: Requires root privileges to write to /etc/systemd/system/

@@ -712,3 +661,3 @@ USER root

'WorkingDirectory=/home/opencode/workspace' \
'ExecStart=/home/opencode/.local/share/opencode/bin/opencode --port 3001 --hostname 0.0.0.0' \
'ExecStart=/home/opencode/.local/share/opencode/bin/opencode web --port 3000 --hostname 0.0.0.0' \
'Restart=always' \

@@ -726,40 +675,11 @@ 'RestartSec=5' \

# Nginx service for serving UI + proxying API
RUN printf '%s\n' \
'[Unit]' \
'Description=Nginx reverse proxy for opencode UI' \
'After=network.target opencode.service' \
'' \
'[Service]' \
'Type=simple' \
'ExecStart=/usr/sbin/nginx -g "daemon off;"' \
'ExecReload=/usr/sbin/nginx -s reload' \
'Restart=always' \
'RestartSec=5' \
'' \
'[Install]' \
'WantedBy=multi-user.target' \
> /etc/systemd/system/opencode-nginx.service
# Enable nginx service
RUN mkdir -p /etc/systemd/system/multi-user.target.wants \
&& ln -sf /etc/systemd/system/opencode-nginx.service /etc/systemd/system/multi-user.target.wants/opencode-nginx.service
# Prevent the distro nginx service from also starting (port 3000 conflict)
RUN rm -f /etc/systemd/system/multi-user.target.wants/nginx.service \
&& ln -sf /dev/null /etc/systemd/system/nginx.service
# -----------------------------------------------------------------------------
# opencode Configuration
# -----------------------------------------------------------------------------
# Create opencode.jsonc config file with PAM authentication enabled and UI URL
# Create opencode.jsonc config file with PAM authentication enabled
RUN mkdir -p /home/opencode/.config/opencode \
&& printf '%s\n' \
'{' \
' // Container UI served via nginx on 3002' \
' "auth": {' \
' "enabled": true' \
' },' \
' "server": {' \
' "uiUrl": "http://localhost:3002"' \
' }' \

@@ -788,5 +708,7 @@ '}' \

'else' \
' # Ensure broker socket directory exists' \
' install -d -m 0755 /run/opencode' \
' /usr/local/bin/opencode-broker &' \
' # Use runuser to switch to opencode user without password prompt' \
' runuser -u opencode -- /home/opencode/.local/share/opencode/bin/opencode --port 3001 --hostname 0.0.0.0 &' \
' exec /usr/sbin/nginx -g "daemon off;"' \
' exec runuser -u opencode -- sh -lc "cd /home/opencode/workspace && /home/opencode/.local/share/opencode/bin/opencode web --port 3000 --hostname 0.0.0.0"' \
'fi' \

@@ -825,6 +747,6 @@ > /usr/local/bin/entrypoint.sh && chmod +x /usr/local/bin/entrypoint.sh

# Expose opencode ports (3000/3001/3002) and Cockpit (9090)
EXPOSE 3000 3001 3002 9090
# Expose opencode web (3000) and Cockpit (9090)
EXPOSE 3000 9090
# Hybrid init: entrypoint script chooses tini or systemd based on USE_SYSTEMD env
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

@@ -56,2 +56,10 @@ //! Health check module for OpenCode service

fn format_host(bind_addr: &str) -> String {
if bind_addr.contains(':') && !bind_addr.starts_with('[') {
format!("[{bind_addr}]")
} else {
bind_addr.to_string()
}
}
/// Check health by querying OpenCode's /global/health endpoint

@@ -61,4 +69,5 @@ ///

/// Returns an error for connection issues, timeouts, or non-200 responses.
pub async fn check_health(port: u16) -> Result<HealthResponse, HealthError> {
let url = format!("http://127.0.0.1:{port}/global/health");
pub async fn check_health(bind_addr: &str, port: u16) -> Result<HealthResponse, HealthError> {
let host = format_host(bind_addr);
let url = format!("http://{host}:{port}/global/health");

@@ -100,6 +109,7 @@ let client = reqwest::Client::builder()

client: &DockerClient,
bind_addr: &str,
port: u16,
) -> Result<ExtendedHealthResponse, HealthError> {
// Get basic health info
let health = check_health(port).await?;
let health = check_health(bind_addr, port).await?;

@@ -161,3 +171,3 @@ // Get container stats

// Port 1 should always refuse connection
let result = check_health(1).await;
let result = check_health("127.0.0.1", 1).await;
assert!(result.is_err());

@@ -169,2 +179,12 @@ match result.unwrap_err() {

}
#[test]
fn format_host_wraps_ipv6() {
assert_eq!(format_host("::1"), "[::1]");
}
#[test]
fn format_host_preserves_ipv4() {
assert_eq!(format_host("127.0.0.1"), "127.0.0.1");
}
}

@@ -180,2 +180,4 @@ //! Docker image build and pull operations

last_buildkit_vertex_id: Option<String>,
export_vertex_id: Option<String>,
export_vertex_name: Option<String>,
buildkit_logs_by_vertex_id: HashMap<String, String>,

@@ -203,2 +205,4 @@ vertex_name_by_vertex_id: HashMap<String, String>,

last_buildkit_vertex_id: None,
export_vertex_id: None,
export_vertex_name: None,
buildkit_logs_by_vertex_id: HashMap::new(),

@@ -260,20 +264,30 @@ vertex_name_by_vertex_id: HashMap::new(),

update_buildkit_vertex_names(&mut state.vertex_name_by_vertex_id, status);
let (vertex_id, vertex_name) =
match select_latest_buildkit_vertex(status, &state.vertex_name_by_vertex_id) {
Some((vertex_id, vertex_name)) => (vertex_id, vertex_name),
None => {
let Some(log_entry) = latest_logs.last() else {
return;
};
let name = state
.vertex_name_by_vertex_id
.get(&log_entry.vertex_id)
.cloned()
.or_else(|| state.last_buildkit_vertex.clone())
.unwrap_or_else(|| format_vertex_fallback_label(&log_entry.vertex_id));
(log_entry.vertex_id.clone(), name)
}
};
update_export_vertex_from_logs(
&latest_logs,
&state.vertex_name_by_vertex_id,
&mut state.export_vertex_id,
&mut state.export_vertex_name,
);
let (vertex_id, vertex_name) = match select_latest_buildkit_vertex(
status,
&state.vertex_name_by_vertex_id,
state.export_vertex_id.as_deref(),
state.export_vertex_name.as_deref(),
) {
Some((vertex_id, vertex_name)) => (vertex_id, vertex_name),
None => {
let Some(log_entry) = latest_logs.last() else {
return;
};
let name = state
.vertex_name_by_vertex_id
.get(&log_entry.vertex_id)
.cloned()
.or_else(|| state.last_buildkit_vertex.clone())
.unwrap_or_else(|| format_vertex_fallback_label(&log_entry.vertex_id));
(log_entry.vertex_id.clone(), name)
}
};
record_buildkit_logs(state, &latest_logs, &vertex_id, &vertex_name);
state.last_buildkit_vertex_id = Some(vertex_id);
state.last_buildkit_vertex_id = Some(vertex_id.clone());
if state.last_buildkit_vertex.as_deref() != Some(&vertex_name) {

@@ -285,3 +299,7 @@ state.last_buildkit_vertex = Some(vertex_name.clone());

vertex_name
} else if let Some(log_entry) = latest_logs.last() {
} else if let Some(log_entry) = latest_logs
.iter()
.rev()
.find(|entry| entry.vertex_id == vertex_id)
{
format!("{vertex_name} ยท {}", log_entry.message)

@@ -367,3 +385,13 @@ } else {

vertex_name_by_vertex_id: &HashMap<String, String>,
export_vertex_id: Option<&str>,
export_vertex_name: Option<&str>,
) -> Option<(String, String)> {
if let Some(export_vertex_id) = export_vertex_id {
let name = export_vertex_name
.map(str::to_string)
.or_else(|| vertex_name_by_vertex_id.get(export_vertex_id).cloned())
.unwrap_or_else(|| format_vertex_fallback_label(export_vertex_id));
return Some((export_vertex_id.to_string(), name));
}
let mut best_runtime: Option<(u32, String, String)> = None;

@@ -431,2 +459,20 @@ let mut fallback: Option<(String, String)> = None;

fn update_export_vertex_from_logs(
latest_logs: &[BuildkitLogEntry],
vertex_name_by_vertex_id: &HashMap<String, String>,
export_vertex_id: &mut Option<String>,
export_vertex_name: &mut Option<String>,
) {
if let Some(entry) = latest_logs
.iter()
.rev()
.find(|log| log.message.trim_start().starts_with("exporting to image"))
{
*export_vertex_id = Some(entry.vertex_id.clone());
if let Some(name) = vertex_name_by_vertex_id.get(&entry.vertex_id) {
*export_vertex_name = Some(name.clone());
}
}
}
fn record_buildkit_logs(

@@ -433,0 +479,0 @@ state: &mut BuildLogState,

@@ -31,7 +31,15 @@ # opencode-cloud-sandbox

```
docker run --rm -it -p 3000:3000 -p 3001:3001 -p 3002:3002 -p 9090:9090 ghcr.io/prizz/opencode-cloud-sandbox:latest
docker run --rm -it -p 3000:3000 -p 9090:9090 ghcr.io/prizz/opencode-cloud-sandbox:latest
```
The opencode web UI is available at `http://localhost:3000`. The backend is reachable at `http://localhost:3001`, and the static UI is served at `http://localhost:3002`. Cockpit runs on `http://localhost:9090`.
The opencode web UI is available at `http://localhost:3000`. Cockpit runs on `http://localhost:9090`.
## opencode build and serve flow
The Docker image builds opencode directly from the fork and runs the web server without nginx:
1. `cd packages/opencode`
2. `bun run build` to generate `packages/opencode/dist`
3. Run the server with `./bin/opencode web`
## Source

@@ -38,0 +46,0 @@