@opencode-cloud/core 1.0.8 → 3.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +9 -2
- package/README.md +56 -30
- package/package.json +1 -1
- package/src/config/mod.rs +8 -3
- package/src/config/paths.rs +14 -0
- package/src/config/schema.rs +561 -0
- package/src/config/validation.rs +271 -0
- package/src/docker/Dockerfile +353 -207
- package/src/docker/README.dockerhub.md +39 -0
- package/src/docker/client.rs +132 -3
- package/src/docker/container.rs +204 -36
- package/src/docker/dockerfile.rs +15 -12
- package/src/docker/exec.rs +278 -0
- package/src/docker/health.rs +165 -0
- package/src/docker/image.rs +2 -4
- package/src/docker/mod.rs +72 -8
- package/src/docker/mount.rs +330 -0
- package/src/docker/progress.rs +4 -4
- package/src/docker/state.rs +120 -0
- package/src/docker/update.rs +156 -0
- package/src/docker/users.rs +357 -0
- package/src/docker/version.rs +95 -0
- package/src/host/error.rs +61 -0
- package/src/host/mod.rs +29 -0
- package/src/host/provision.rs +394 -0
- package/src/host/schema.rs +308 -0
- package/src/host/ssh_config.rs +282 -0
- package/src/host/storage.rs +118 -0
- package/src/host/tunnel.rs +268 -0
- package/src/lib.rs +10 -1
- package/src/platform/launchd.rs +1 -1
- package/src/platform/systemd.rs +6 -6
- package/src/singleton/mod.rs +1 -1
- package/src/version.rs +1 -6
package/Cargo.toml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "opencode-cloud-core"
|
|
3
|
-
version = "
|
|
3
|
+
version = "3.0.15"
|
|
4
4
|
edition = "2024"
|
|
5
|
-
rust-version = "1.
|
|
5
|
+
rust-version = "1.88"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/pRizz/opencode-cloud"
|
|
8
8
|
homepage = "https://github.com/pRizz/opencode-cloud"
|
|
@@ -32,6 +32,7 @@ thiserror = "2"
|
|
|
32
32
|
anyhow = "1"
|
|
33
33
|
tracing = "0.1"
|
|
34
34
|
console = "0.16"
|
|
35
|
+
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
|
|
35
36
|
|
|
36
37
|
# NAPI dependencies (optional - only for Node bindings)
|
|
37
38
|
napi = { version = "2", features = ["tokio_rt", "napi9"], optional = true }
|
|
@@ -46,10 +47,16 @@ tokio-retry = "0.3"
|
|
|
46
47
|
indicatif = { version = "0.17", features = ["tokio", "futures"] }
|
|
47
48
|
http-body-util = "0.1"
|
|
48
49
|
bytes = "1.9"
|
|
50
|
+
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json"] }
|
|
49
51
|
|
|
50
52
|
# Platform service management (macOS)
|
|
51
53
|
plist = "1.8"
|
|
52
54
|
|
|
55
|
+
# Host management
|
|
56
|
+
whoami = "1.5"
|
|
57
|
+
ssh2-config-rs = "0.7.1"
|
|
58
|
+
dirs = "6"
|
|
59
|
+
|
|
53
60
|
[build-dependencies]
|
|
54
61
|
napi-build = "2"
|
|
55
62
|
|
package/README.md
CHANGED
|
@@ -2,54 +2,82 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/pRizz/opencode-cloud/actions/workflows/ci.yml)
|
|
4
4
|
[](https://crates.io/crates/opencode-cloud)
|
|
5
|
-
[](https://github.com/pRizz/opencode-cloud/pkgs/container/opencode-cloud-sandbox)
|
|
6
|
+
[](https://hub.docker.com/r/prizz/opencode-cloud-sandbox)
|
|
6
7
|
[](https://docs.rs/opencode-cloud)
|
|
7
8
|
[](https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html)
|
|
8
9
|
[](https://opensource.org/licenses/MIT)
|
|
9
10
|
|
|
10
|
-
A production-ready toolkit for deploying [opencode](https://github.com/anomalyco/opencode) as a persistent cloud service.
|
|
11
|
+
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.
|
|
12
|
+
|
|
13
|
+
## Quick install (cargo)
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cargo install opencode-cloud
|
|
17
|
+
opencode-cloud --version
|
|
18
|
+
```
|
|
11
19
|
|
|
12
20
|
## Features
|
|
13
21
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
22
|
+
- **Sandboxed execution** - opencode runs inside a Docker container, isolated from your host system
|
|
23
|
+
- **Persistent environment** - Your projects, settings, and shell history persist across restarts
|
|
24
|
+
- **Cross-platform CLI** (`opencode-cloud` / `occ`) - Works on Linux and macOS
|
|
25
|
+
- **Service lifecycle commands** - start, stop, restart, status, logs
|
|
26
|
+
- **Platform service integration** - systemd (Linux) / launchd (macOS) for auto-start on boot
|
|
27
|
+
- **Remote host management** - Manage opencode containers on remote servers via SSH
|
|
28
|
+
- **Web-based admin** - Cockpit integration for container administration
|
|
20
29
|
|
|
21
|
-
##
|
|
30
|
+
## How it works
|
|
22
31
|
|
|
23
|
-
|
|
32
|
+
opencode-cloud runs opencode inside a Docker container, providing:
|
|
24
33
|
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
|
|
34
|
+
- **Isolation** - opencode and its AI-generated code run in a sandbox, separate from your host system
|
|
35
|
+
- **Reproducibility** - The container includes a full development environment (languages, tools, runtimes)
|
|
36
|
+
- **Persistence** - Docker volumes preserve your work across container restarts and updates
|
|
37
|
+
- **Security** - Network exposure is opt-in; by default, the service only binds to localhost
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
The CLI manages the container lifecycle, so you don't need to interact with Docker directly.
|
|
30
40
|
|
|
31
|
-
|
|
41
|
+
## Docker Images
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
The sandbox container image is named **`opencode-cloud-sandbox`** (not `opencode-cloud`) to clearly distinguish it from the CLI tool. The CLI (`opencode-cloud` / `occ`) deploys and manages this sandbox container.
|
|
44
|
+
|
|
45
|
+
The image is published to both registries:
|
|
34
46
|
|
|
35
|
-
|
|
47
|
+
| Registry | Image |
|
|
48
|
+
|----------|-------|
|
|
49
|
+
| GitHub Container Registry | [`ghcr.io/prizz/opencode-cloud-sandbox`](https://github.com/pRizz/opencode-cloud/pkgs/container/opencode-cloud-sandbox) |
|
|
50
|
+
| Docker Hub | [`prizz/opencode-cloud-sandbox`](https://hub.docker.com/r/prizz/opencode-cloud-sandbox) |
|
|
36
51
|
|
|
52
|
+
Pull commands:
|
|
53
|
+
|
|
54
|
+
Docker Hub:
|
|
37
55
|
```bash
|
|
38
|
-
|
|
56
|
+
docker pull prizz/opencode-cloud-sandbox:latest
|
|
39
57
|
```
|
|
40
58
|
|
|
41
|
-
|
|
59
|
+
GitHub Container Registry:
|
|
60
|
+
```bash
|
|
61
|
+
docker pull ghcr.io/prizz/opencode-cloud-sandbox:latest
|
|
62
|
+
```
|
|
42
63
|
|
|
64
|
+
**For most users:** Just use the CLI - it handles image pulling/building automatically:
|
|
43
65
|
```bash
|
|
44
|
-
|
|
45
|
-
occ --version
|
|
66
|
+
occ start # Pulls or builds the image as needed
|
|
46
67
|
```
|
|
47
68
|
|
|
48
|
-
|
|
69
|
+
## Requirements
|
|
70
|
+
|
|
71
|
+
- **Rust 1.85+** - Install via [rustup](https://rustup.rs): `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`
|
|
72
|
+
- **Docker** - For running the opencode container
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
### Via cargo (recommended)
|
|
49
77
|
|
|
50
78
|
```bash
|
|
51
79
|
cargo install opencode-cloud
|
|
52
|
-
|
|
80
|
+
occ --version
|
|
53
81
|
```
|
|
54
82
|
|
|
55
83
|
### From source
|
|
@@ -67,7 +95,7 @@ cargo run -p opencode-cloud -- --version
|
|
|
67
95
|
# Show version
|
|
68
96
|
occ --version
|
|
69
97
|
|
|
70
|
-
# Start the service (builds
|
|
98
|
+
# Start the service (builds Docker container on first run, ~10-15 min)
|
|
71
99
|
occ start
|
|
72
100
|
|
|
73
101
|
# Start on a custom port
|
|
@@ -165,15 +193,13 @@ just lint
|
|
|
165
193
|
## Architecture
|
|
166
194
|
|
|
167
195
|
This is a monorepo with:
|
|
168
|
-
- `packages/core` - Rust core library
|
|
169
|
-
- `packages/cli-rust` - Rust CLI binary
|
|
170
|
-
- `packages/cli-node` - Node.js CLI
|
|
171
|
-
|
|
172
|
-
The npm package compiles the Rust core on install (no prebuilt binaries).
|
|
196
|
+
- `packages/core` - Rust core library
|
|
197
|
+
- `packages/cli-rust` - Rust CLI binary (recommended)
|
|
198
|
+
- `packages/cli-node` - Node.js CLI (deprecated, directs users to cargo install)
|
|
173
199
|
|
|
174
200
|
### Cargo.toml Sync Requirement
|
|
175
201
|
|
|
176
|
-
The `packages/core/Cargo.toml` file must use **explicit values** rather than `workspace = true` references.
|
|
202
|
+
The `packages/core/Cargo.toml` file must use **explicit values** rather than `workspace = true` references.
|
|
177
203
|
|
|
178
204
|
When updating package metadata (version, edition, rust-version, etc.), keep both files in sync:
|
|
179
205
|
- `Cargo.toml` (workspace root)
|
package/package.json
CHANGED
package/src/config/mod.rs
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
pub mod paths;
|
|
7
7
|
pub mod schema;
|
|
8
|
+
pub mod validation;
|
|
8
9
|
|
|
9
10
|
use std::fs::{self, File};
|
|
10
11
|
use std::io::{Read, Write};
|
|
@@ -13,8 +14,12 @@ use std::path::PathBuf;
|
|
|
13
14
|
use anyhow::{Context, Result};
|
|
14
15
|
use jsonc_parser::parse_to_serde_value;
|
|
15
16
|
|
|
16
|
-
pub use paths::{get_config_dir, get_config_path, get_data_dir, get_pid_path};
|
|
17
|
-
pub use schema::Config;
|
|
17
|
+
pub use paths::{get_config_dir, get_config_path, get_data_dir, get_hosts_path, get_pid_path};
|
|
18
|
+
pub use schema::{Config, validate_bind_address};
|
|
19
|
+
pub use validation::{
|
|
20
|
+
ValidationError, ValidationWarning, display_validation_error, display_validation_warning,
|
|
21
|
+
validate_config,
|
|
22
|
+
};
|
|
18
23
|
|
|
19
24
|
/// Ensure the config directory exists
|
|
20
25
|
///
|
|
@@ -84,7 +89,7 @@ pub fn load_config() -> Result<Config> {
|
|
|
84
89
|
|
|
85
90
|
// Parse JSONC (JSON with comments)
|
|
86
91
|
let parsed_value = parse_to_serde_value(&contents, &Default::default())
|
|
87
|
-
.map_err(|e| anyhow::anyhow!("Invalid JSONC in config file: {}"
|
|
92
|
+
.map_err(|e| anyhow::anyhow!("Invalid JSONC in config file: {e}"))?
|
|
88
93
|
.ok_or_else(|| anyhow::anyhow!("Config file is empty"))?;
|
|
89
94
|
|
|
90
95
|
// Deserialize into Config struct (deny_unknown_fields will reject unknown keys)
|
package/src/config/paths.rs
CHANGED
|
@@ -72,6 +72,13 @@ pub fn get_pid_path() -> Option<PathBuf> {
|
|
|
72
72
|
get_data_dir().map(|d| d.join("opencode-cloud.pid"))
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/// Get the full path to the hosts configuration file
|
|
76
|
+
///
|
|
77
|
+
/// Returns: `{config_dir}/hosts.json`
|
|
78
|
+
pub fn get_hosts_path() -> Option<PathBuf> {
|
|
79
|
+
get_config_dir().map(|d| d.join("hosts.json"))
|
|
80
|
+
}
|
|
81
|
+
|
|
75
82
|
#[cfg(test)]
|
|
76
83
|
mod tests {
|
|
77
84
|
use super::*;
|
|
@@ -105,4 +112,11 @@ mod tests {
|
|
|
105
112
|
assert!(path.is_some());
|
|
106
113
|
assert!(path.unwrap().ends_with("opencode-cloud.pid"));
|
|
107
114
|
}
|
|
115
|
+
|
|
116
|
+
#[test]
|
|
117
|
+
fn test_hosts_path_ends_with_hosts_json() {
|
|
118
|
+
let path = get_hosts_path();
|
|
119
|
+
assert!(path.is_some());
|
|
120
|
+
assert!(path.unwrap().ends_with("hosts.json"));
|
|
121
|
+
}
|
|
108
122
|
}
|