@opencode-cloud/core 10.3.0 → 11.0.0
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 +2 -2
- package/package.json +1 -1
- package/src/config/validation.rs +18 -18
- package/src/docker/Dockerfile +4 -0
- package/src/docker/progress.rs +8 -8
- package/src/docker/state.rs +4 -4
- package/src/host/schema.rs +4 -4
- package/src/host/ssh_config.rs +18 -18
- package/src/host/storage.rs +5 -5
package/Cargo.toml
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "opencode-cloud-core"
|
|
3
|
-
version = "
|
|
3
|
+
version = "11.0.0"
|
|
4
4
|
edition = "2024"
|
|
5
|
-
rust-version = "1.
|
|
5
|
+
rust-version = "1.89"
|
|
6
6
|
license = "MIT"
|
|
7
7
|
repository = "https://github.com/pRizz/opencode-cloud"
|
|
8
8
|
homepage = "https://github.com/pRizz/opencode-cloud"
|
package/package.json
CHANGED
package/src/config/validation.rs
CHANGED
|
@@ -96,26 +96,26 @@ pub fn validate_config(config: &Config) -> Result<Vec<ValidationWarning>, Valida
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// Legacy auth fields present
|
|
99
|
-
if let Some(ref username) = config.auth_username
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
99
|
+
if let Some(ref username) = config.auth_username
|
|
100
|
+
&& !username.is_empty()
|
|
101
|
+
{
|
|
102
|
+
warnings.push(ValidationWarning {
|
|
103
|
+
field: "auth_username".to_string(),
|
|
104
|
+
message: "Legacy auth fields present; consider using 'occ user add' instead"
|
|
105
|
+
.to_string(),
|
|
106
|
+
fix_command: "occ config set auth_username ''".to_string(),
|
|
107
|
+
});
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
if let Some(ref password) = config.auth_password
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
110
|
+
if let Some(ref password) = config.auth_password
|
|
111
|
+
&& !password.is_empty()
|
|
112
|
+
{
|
|
113
|
+
warnings.push(ValidationWarning {
|
|
114
|
+
field: "auth_password".to_string(),
|
|
115
|
+
message: "Legacy auth fields present; consider using 'occ user add' instead"
|
|
116
|
+
.to_string(),
|
|
117
|
+
fix_command: "occ config set auth_password ''".to_string(),
|
|
118
|
+
});
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
Ok(warnings)
|
package/src/docker/Dockerfile
CHANGED
|
@@ -36,6 +36,10 @@ FROM ubuntu:24.04 AS base
|
|
|
36
36
|
|
|
37
37
|
# OCI Labels for image metadata
|
|
38
38
|
LABEL org.opencontainers.image.title="opencode-cloud"
|
|
39
|
+
# NOTE: This exact label format is parsed by scripts/extract-oci-description.py
|
|
40
|
+
# (called from .github/workflows/docker-publish.yml) to populate multi-arch
|
|
41
|
+
# manifest annotations for GHCR. If you change this line (format, quoting, or
|
|
42
|
+
# key), update the extraction logic too.
|
|
39
43
|
LABEL org.opencontainers.image.description="AI-assisted development environment with opencode"
|
|
40
44
|
LABEL org.opencontainers.image.url="https://github.com/pRizz/opencode-cloud"
|
|
41
45
|
LABEL org.opencontainers.image.source="https://github.com/pRizz/opencode-cloud"
|
package/src/docker/progress.rs
CHANGED
|
@@ -210,17 +210,17 @@ impl ProgressReporter {
|
|
|
210
210
|
|
|
211
211
|
// Check if we should throttle this update
|
|
212
212
|
if !is_step_message {
|
|
213
|
-
if let Some(last) = self.last_update_by_id.get(id)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
213
|
+
if let Some(last) = self.last_update_by_id.get(id)
|
|
214
|
+
&& now.duration_since(*last) < SPINNER_UPDATE_THROTTLE
|
|
215
|
+
{
|
|
216
|
+
return; // Throttle: too soon since last update
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
// Skip if message is identical to last one
|
|
220
|
-
if let Some(last_msg) = self.last_message_by_id.get(id)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
220
|
+
if let Some(last_msg) = self.last_message_by_id.get(id)
|
|
221
|
+
&& last_msg == message
|
|
222
|
+
{
|
|
223
|
+
return;
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
package/src/docker/state.rs
CHANGED
|
@@ -71,10 +71,10 @@ pub fn load_state() -> Option<ImageState> {
|
|
|
71
71
|
|
|
72
72
|
/// Clear image state (e.g., after image removal)
|
|
73
73
|
pub fn clear_state() -> anyhow::Result<()> {
|
|
74
|
-
if let Some(path) = get_state_path()
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
if let Some(path) = get_state_path()
|
|
75
|
+
&& path.exists()
|
|
76
|
+
{
|
|
77
|
+
std::fs::remove_file(&path)?;
|
|
78
78
|
}
|
|
79
79
|
Ok(())
|
|
80
80
|
}
|
package/src/host/schema.rs
CHANGED
|
@@ -139,10 +139,10 @@ impl HostConfig {
|
|
|
139
139
|
let mut parts = vec!["ssh".to_string()];
|
|
140
140
|
|
|
141
141
|
// Port (if non-default)
|
|
142
|
-
if let Some(port) = self.port
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
142
|
+
if let Some(port) = self.port
|
|
143
|
+
&& port != 22
|
|
144
|
+
{
|
|
145
|
+
parts.push(format!("-p {port}"));
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// Identity file
|
package/src/host/ssh_config.rs
CHANGED
|
@@ -137,21 +137,21 @@ pub fn write_ssh_config_entry(
|
|
|
137
137
|
})?;
|
|
138
138
|
|
|
139
139
|
// Ensure .ssh directory exists with proper permissions
|
|
140
|
-
if let Some(ssh_dir) = config_path.parent()
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
})
|
|
140
|
+
if let Some(ssh_dir) = config_path.parent()
|
|
141
|
+
&& !ssh_dir.exists()
|
|
142
|
+
{
|
|
143
|
+
fs::create_dir_all(ssh_dir).map_err(|e| {
|
|
144
|
+
HostError::SshConfigWrite(format!("Failed to create .ssh directory: {e}"))
|
|
145
|
+
})?;
|
|
145
146
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
147
|
+
// Set directory permissions to 700 on Unix
|
|
148
|
+
#[cfg(unix)]
|
|
149
|
+
{
|
|
150
|
+
use std::os::unix::fs::PermissionsExt;
|
|
151
|
+
let perms = fs::Permissions::from_mode(0o700);
|
|
152
|
+
fs::set_permissions(ssh_dir, perms).map_err(|e| {
|
|
153
|
+
HostError::SshConfigWrite(format!("Failed to set .ssh permissions: {e}"))
|
|
154
|
+
})?;
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
@@ -164,10 +164,10 @@ pub fn write_ssh_config_entry(
|
|
|
164
164
|
if let Some(u) = user {
|
|
165
165
|
entry.push_str(&format!(" User {u}\n"));
|
|
166
166
|
}
|
|
167
|
-
if let Some(p) = port
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
167
|
+
if let Some(p) = port
|
|
168
|
+
&& p != 22
|
|
169
|
+
{
|
|
170
|
+
entry.push_str(&format!(" Port {p}\n"));
|
|
171
171
|
}
|
|
172
172
|
if let Some(key) = identity_file {
|
|
173
173
|
entry.push_str(&format!(" IdentityFile {key}\n"));
|
package/src/host/storage.rs
CHANGED
|
@@ -54,11 +54,11 @@ pub fn save_hosts(hosts: &HostsFile) -> Result<(), HostError> {
|
|
|
54
54
|
.ok_or_else(|| HostError::SaveFailed("Could not determine hosts file path".to_string()))?;
|
|
55
55
|
|
|
56
56
|
// Ensure config directory exists
|
|
57
|
-
if let Some(parent) = hosts_path.parent()
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
if let Some(parent) = hosts_path.parent()
|
|
58
|
+
&& !parent.exists()
|
|
59
|
+
{
|
|
60
|
+
fs::create_dir_all(parent)
|
|
61
|
+
.map_err(|e| HostError::SaveFailed(format!("Failed to create directory: {e}")))?;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// Create backup if file exists
|