refactor: rename Workspace API crate to server API

This commit is contained in:
2026-09-18 06:35:33 +09:00
93 changed files with 6062 additions and 6562 deletions
-1
View File
@@ -19,7 +19,6 @@ thiserror = { workspace = true }
tokio = { workspace = true, features = ["rt", "macros", "net", "io-util", "sync", "time"] }
tokio-tungstenite = { workspace = true }
uuid = { workspace = true }
workspace-api.workspace = true
[dev-dependencies]
tempfile = { workspace = true }
+3 -3
View File
@@ -3,8 +3,8 @@ use serde::Deserialize;
use std::fmt;
use std::time::Duration;
use workspace_api::{DeviceLoginPollRequest, DeviceLoginPollStatus, DeviceLoginStartRequest};
pub use workspace_api::{DeviceLoginPollResponse, DeviceLoginStartResponse};
use server_api::{DeviceLoginPollRequest, DeviceLoginPollStatus, DeviceLoginStartRequest};
pub use server_api::{DeviceLoginPollResponse, DeviceLoginStartResponse};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BackendAuthTarget {
@@ -153,7 +153,7 @@ async fn parse_json_response<T: for<'de> Deserialize<'de>>(
#[cfg(test)]
mod tests {
use super::*;
use workspace_api::DeviceAccessTokenType;
use server_api::DeviceAccessTokenType;
fn poll_response(status: DeviceLoginPollStatus) -> DeviceLoginPollResponse {
DeviceLoginPollResponse {
+5 -5
View File
@@ -2,11 +2,7 @@ use crate::transport::websocket::{Socket as WebSocket, SocketError as WebSocketE
use crate::{BackendApiClient, BackendApiClientError, Client};
use reqwest::Method as HttpMethod;
use serde::Deserialize;
use std::fmt;
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
use tokio_tungstenite::tungstenite::http::HeaderValue;
use tokio_tungstenite::tungstenite::http::header::AUTHORIZATION;
pub use workspace_api::{
pub use server_api::{
BrowserCreateWorkerResponse as BackendCreateWorkerResponse,
CreateWorkspaceWorkerRequest as BackendCreateWorkerRequest, Diagnostic as BackendDiagnostic,
DiagnosticSeverity as BackendDiagnosticSeverity, ListResponse as BackendRuntimeListResponse,
@@ -27,6 +23,10 @@ pub use workspace_api::{
WorkingDirectoryListResponse as BackendWorkingDirectoryListResponse,
WorkingDirectorySummary as BackendWorkingDirectorySummary,
};
use std::fmt;
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
use tokio_tungstenite::tungstenite::http::HeaderValue;
use tokio_tungstenite::tungstenite::http::header::AUTHORIZATION;
#[derive(Debug, Clone, PartialEq)]
pub struct BackendRuntimeTarget {
+2 -2
View File
@@ -1,11 +1,11 @@
use crate::{BackendApiClient, BackendApiClientError};
use reqwest::Method;
use std::fmt;
use workspace_api::{
use server_api::{
InitialRepositoryIntent, RepositoryListResponse, RepositorySummary,
WorkspaceCatalogListResponse, WorkspaceCreateRequest, WorkspaceCreateResponse,
WorkspaceSummary,
};
use std::fmt;
const DEFAULT_WORKSPACE_LIMIT: usize = 200;
+6 -6
View File
@@ -43,16 +43,16 @@ pub use client::{Client, ClientError};
pub use runtime_api::{
RetainedSessionIdentity, WorkerSessionAvailability, WorkerSessionUnavailableReason,
};
pub use server_api::{
CompanionCancelRequest, CompanionLifecycleState, CompanionMessageDisposition,
CompanionMessageRequest, CompanionMessageResponse, CompanionStatusResponse,
CompanionTranscriptItem, CompanionTranscriptProjection, CompanionTranscriptRole,
CompanionTransportSummary, ObjectiveDetail, ObjectiveSummary,
};
pub use server_api::{ServerApi, ServerApiClient, WorkspaceWorkerSessionResponse};
pub use target::{
BackendTarget, BackendWorkerLaunch, Dashboard, ResolvedTarget, StandaloneTarget,
StandaloneWorkerListIntent, StandaloneWorkerResumeIntent, Target, TargetError, TargetKind,
WorkerConnection, WorkerConnectionSelector, WorkerList, WorkerListRequest, WorkerSpawn,
};
pub use workspace_api::{
CompanionCancelRequest, CompanionLifecycleState, CompanionMessageDisposition,
CompanionMessageRequest, CompanionMessageResponse, CompanionStatusResponse,
CompanionTranscriptItem, CompanionTranscriptProjection, CompanionTranscriptRole,
CompanionTransportSummary, ObjectiveDetail, ObjectiveSummary,
};
pub use workspace_product::BackendWorkspaceProductClient;
+9 -9
View File
@@ -1,14 +1,7 @@
use reqwest::Method;
use serde::Serialize;
use serde::de::DeserializeOwned;
use ticket::{
MarkdownText, NewOrchestrationPlanRecord, NewTicket, NewTicketEvent, NewTicketRelation,
OrchestrationPlanKind, OrchestrationPlanRecord, Ticket, TicketBackend, TicketDependencyCheck,
TicketDoctorReport, TicketError, TicketIdOrSlug, TicketIntakeSummary, TicketItemEdit,
TicketListQuery, TicketListState, TicketMarkReady, TicketRef, TicketRelation,
TicketRelationKind, TicketRelationView, TicketStateChange, TicketStateSelector, TicketSummary,
};
use workspace_api::{
use server_api::{
BrowserCreateWorkerResponse, BrowserWorkspaceOrchestratorResponse,
CreateWorkspaceWorkerRequest, ListResponse, MemoryDocumentResponse, MemoryStagingListResponse,
ObjectiveCreateRequest, ObjectiveDetail, ObjectiveEditRequest, ObjectiveLinkTicketRequest,
@@ -17,6 +10,13 @@ use workspace_api::{
TICKET_RELATIONS_QUERY_PATH, WorkerLaunchOptionsResponse, WorkspaceRuntimeDetail,
WorkspaceRuntimeResource,
};
use ticket::{
MarkdownText, NewOrchestrationPlanRecord, NewTicket, NewTicketEvent, NewTicketRelation,
OrchestrationPlanKind, OrchestrationPlanRecord, Ticket, TicketBackend, TicketDependencyCheck,
TicketDoctorReport, TicketError, TicketIdOrSlug, TicketIntakeSummary, TicketItemEdit,
TicketListQuery, TicketListState, TicketMarkReady, TicketRef, TicketRelation,
TicketRelationKind, TicketRelationView, TicketStateChange, TicketStateSelector, TicketSummary,
};
use crate::{BackendApiClient, BackendWorkspaceClientError};
@@ -758,7 +758,7 @@ mod tests {
.as_ref()
.unwrap()
.kind,
workspace_api::MemoryEvidenceOriginKind::WorkerInput
server_api::MemoryEvidenceOriginKind::WorkerInput
);
assert!(
request
-1
View File
@@ -10,7 +10,6 @@ api-macros = { workspace = true, features = ["reqwest", "axum"] }
manifest.workspace = true
protocol.workspace = true
serde = { workspace = true, features = ["derive"] }
workspace-api.workspace = true
workdir.workspace = true
[dev-dependencies]
+77 -2
View File
@@ -13,10 +13,85 @@ pub use api_macros::{ApiContract, HttpMethod};
use protocol::{CompletionEntry, CompletionKind, Segment, WorkerId, WorkerStateSnapshot};
use serde::{Deserialize, Serialize};
use workdir::workspace::{MaterializerKind, RuntimeWorkerRef, RuntimeWorkingDirectorySummary};
use workspace_api::{RepositoryAccessMode, RepositorySource};
pub const RUNTIME_API_VERSION: &str = "v1";
pub const RUNTIME_API_BASE_PATH: &str = "/v1";
/// Runtime transport classification for a materialized Repository source.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RepositorySourceKind {
LocalPath,
File,
Ssh,
Https,
Invalid,
}
impl RepositorySourceKind {
pub const fn is_remote(self) -> bool {
matches!(self, Self::Ssh | Self::Https)
}
pub const fn as_str(self) -> &'static str {
match self {
Self::LocalPath => "local_path",
Self::File => "file",
Self::Ssh => "ssh",
Self::Https => "https",
Self::Invalid => "invalid",
}
}
pub fn parse(value: &str) -> Option<Self> {
Some(match value {
"local_path" => Self::LocalPath,
"file" => Self::File,
"ssh" => Self::Ssh,
"https" => Self::Https,
"http" | "invalid" => Self::Invalid,
_ => return None,
})
}
}
impl<'de> Deserialize<'de> for RepositorySourceKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
Self::parse(&value).ok_or_else(|| {
serde::de::Error::unknown_variant(
&value,
&["local_path", "file", "ssh", "https", "invalid"],
)
})
}
}
/// Runtime transport identity for one Repository source.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct RepositorySource {
pub kind: RepositorySourceKind,
pub uri: String,
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum RepositoryAccessMode {
ReadOnly,
ReadWrite,
}
/// Runtime transport outcome for an explicit Worker restore operation.
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum WorkerRestoreState {
Accepted,
Rejected,
RolledBack,
ReconciliationRequired,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct RuntimeApiError {
@@ -364,7 +439,7 @@ pub struct WorkerResponse {
/// including preflight rejection and uncertain post-side-effect reconciliation.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct WorkerRestoreResponse {
pub state: workspace_api::WorkerRestoreState,
pub state: WorkerRestoreState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub worker: Option<WorkerDetail>,
#[serde(default, skip_serializing_if = "Option::is_none")]
+44 -3
View File
@@ -1,14 +1,55 @@
[package]
name = "server-api"
version = "0.1.0"
edition = "2024"
edition.workspace = true
license.workspace = true
publish = false
[features]
default = []
typescript = ["dep:ts-rs", "protocol/typescript"]
[dependencies]
api-macros = { workspace = true, features = ["reqwest", "axum"] }
protocol.workspace = true
runtime-api.workspace = true
serde = { workspace = true, features = ["derive"] }
workspace-api.workspace = true
ts-rs = { version = "12.0.1", optional = true }
webauthn-rs-proto = "0.5.5"
workdir.workspace = true
[dev-dependencies]
serde_json.workspace = true
tokio = { workspace = true }
tokio.workspace = true
[[example]]
name = "generate_legacy_typescript"
required-features = ["typescript"]
[[example]]
name = "generate_workdir_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_worker_launch_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_companion_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_memory_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_skill_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_auth_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_repository_access_types"
required-features = ["typescript"]
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::auth_api_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::companion_api_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::legacy_catalog_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::memory_api_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::repository_access_api_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::skill_api_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::workdir_api_typescript())
);
}
@@ -0,0 +1,6 @@
fn main() {
print!(
"{}",
server_api::normalized_typescript(server_api::worker_launch_api_typescript())
);
}
File diff suppressed because it is too large Load Diff
-1
View File
@@ -19,7 +19,6 @@ sha2.workspace = true
tempfile.workspace = true
thiserror.workspace = true
tokio = { workspace = true, features = ["process", "rt", "sync", "time"] }
workspace-api = { workspace = true }
[dev-dependencies]
serde_json.workspace = true
+155 -19
View File
@@ -1,17 +1,139 @@
//! Shared Workspace-facing Workdir inventory transport contracts.
//! Shared Workdir inventory domain contracts.
//!
//! These projections describe Workspace inventory and durable occupancy. They
//! intentionally do not expose provider/session handles, host paths, Runtime
//! URLs, or credentials. Runtime-local Workdir operation contracts live in
//! [`crate::http`].
//! These types are a neutral lower-level authority shared by Server and Runtime
//! transport projections. They intentionally do not expose provider/session
//! handles, host paths, Runtime URLs, or credentials.
use serde::{Deserialize, Serialize};
pub use workspace_api::{
RuntimeWorkingDirectoryCleanupTarget, RuntimeWorkingDirectorySummary,
WorkingDirectoryCleanupTarget, WorkingDirectoryMaterializerKind as MaterializerKind,
WorkingDirectoryOccupancy, WorkingDirectoryStatusKind, WorkingDirectorySummary,
};
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum WorkingDirectoryMaterializerKind {
#[default]
RuntimeGitClone,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum WorkingDirectoryStatusKind {
Active,
CleanupPending,
Corrupted,
NotFound,
Unknown,
}
impl WorkingDirectoryStatusKind {
pub const fn as_str(&self) -> &'static str {
match self {
Self::Active => "active",
Self::CleanupPending => "cleanup_pending",
Self::Corrupted => "corrupted",
Self::NotFound => "not_found",
Self::Unknown => "unknown",
}
}
}
impl std::fmt::Display for WorkingDirectoryStatusKind {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct WorkingDirectoryCleanupTarget {
pub kind: String,
pub working_directory_id: String,
pub repository_key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct WorkingDirectoryOccupancy {
pub runtime_id: String,
pub worker_id: String,
pub display_name: String,
pub linked_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct RuntimeWorkingDirectoryCleanupTarget {
pub kind: String,
pub working_directory_id: String,
pub repository_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct RuntimeWorkingDirectorySummary {
pub working_directory_id: String,
pub repository_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub creation_selector: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub creation_ref: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub creation_tree: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_selector: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_ref: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_tree: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub observed_at_epoch_seconds: Option<u64>,
pub materializer_kind: WorkingDirectoryMaterializerKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cleanup_target: Option<RuntimeWorkingDirectoryCleanupTarget>,
pub status: WorkingDirectoryStatusKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cleanliness: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub primary_worker_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub occupied_by: Option<WorkingDirectoryOccupancy>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct WorkingDirectorySummary {
pub working_directory_id: String,
pub repository_key: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub creation_selector: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub creation_ref: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub creation_tree: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_selector: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_ref: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_tree: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub observed_at_epoch_seconds: Option<u64>,
pub materializer_kind: WorkingDirectoryMaterializerKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cleanup_target: Option<WorkingDirectoryCleanupTarget>,
pub status: WorkingDirectoryStatusKind,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cleanliness: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub primary_worker_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub occupied_by: Option<WorkingDirectoryOccupancy>,
}
impl WorkingDirectorySummary {
pub fn is_workspace_managed(&self) -> bool {
self.cleanup_target.is_some()
}
}
pub use WorkingDirectoryMaterializerKind as MaterializerKind;
/// Stable Workspace identity for a Worker hosted by a Runtime.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
@@ -89,15 +211,29 @@ mod tests {
}
#[test]
fn workspace_workdir_projection_reexports_workspace_api_authority() {
assert_eq!(
std::any::TypeId::of::<WorkingDirectorySummary>(),
std::any::TypeId::of::<workspace_api::WorkingDirectorySummary>()
);
assert_eq!(
std::any::TypeId::of::<WorkingDirectoryOccupancy>(),
std::any::TypeId::of::<workspace_api::WorkingDirectoryOccupancy>()
);
fn working_directory_summary_preserves_server_projection_wire_shape() {
let summary = WorkingDirectorySummary {
working_directory_id: "wd-1".to_string(),
repository_key: "repo-1".to_string(),
creation_selector: None,
creation_ref: None,
creation_tree: None,
current_selector: None,
current_ref: None,
current_tree: None,
observed_at_epoch_seconds: None,
materializer_kind: WorkingDirectoryMaterializerKind::RuntimeGitClone,
cleanup_target: None,
status: WorkingDirectoryStatusKind::Active,
cleanliness: None,
primary_worker_id: None,
occupied_by: None,
};
let value = serde_json::to_value(summary).unwrap();
assert_eq!(value["working_directory_id"], "wd-1");
assert_eq!(value["materializer_kind"], "runtime_git_clone");
assert_eq!(value["status"], "active");
assert!(value.get("cleanup_target").is_none());
}
}
+1 -1
View File
@@ -50,7 +50,7 @@ uuid = { workspace = true, features = ["v7"] }
zeroize.workspace = true
tower = { workspace = true, features = ["util"], optional = true }
worker.workspace = true
workspace-api = { path = "../workspace-api" }
server-api = { path = "../server-api" }
workdir.workspace = true
[dev-dependencies]
+2 -2
View File
@@ -74,7 +74,7 @@ impl std::ops::Deref for RepositorySelector {
pub struct WorkingDirectoryRepository {
pub id: String,
pub provider: String,
pub source: workspace_api::RepositorySource,
pub source: server_api::RepositorySource,
pub source_revision: u64,
pub source_fingerprint: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
@@ -131,7 +131,7 @@ pub struct RepositorySshMaterializationAccess {
pub credential_candidates: Vec<RepositorySshCredentialCandidate>,
pub host_trust_id: String,
pub host_trust_revision: u64,
pub access: workspace_api::RepositoryAccessMode,
pub access: server_api::RepositoryAccessMode,
pub expires_at_epoch_seconds: u64,
pub repository_id: String,
pub repository_source_fingerprint: String,
+1 -1
View File
@@ -2584,9 +2584,9 @@ mod tests {
use axum::body::to_bytes;
use axum::http::Method;
use manifest::{Scope, SharedScope};
use runtime_api::WorkerRestoreState;
use sha2::Digest as _;
use tower::ServiceExt;
use workspace_api::WorkerRestoreState;
#[derive(Clone)]
struct TestRuntimeAuthorizer(String);
@@ -377,7 +377,20 @@ impl runtime_api::RuntimeApi for RuntimeManagementApi {
.map_err(RuntimeHttpRestError::runtime)
.map_err(api_error)?;
Ok(runtime_api::WorkerRestoreResponse {
state: result.state,
state: match result.state {
server_api::WorkerRestoreState::Accepted => {
runtime_api::WorkerRestoreState::Accepted
}
server_api::WorkerRestoreState::Rejected => {
runtime_api::WorkerRestoreState::Rejected
}
server_api::WorkerRestoreState::RolledBack => {
runtime_api::WorkerRestoreState::RolledBack
}
server_api::WorkerRestoreState::ReconciliationRequired => {
runtime_api::WorkerRestoreState::ReconciliationRequired
}
},
worker: result.worker.map(response).transpose()?,
reason_code: result.reason_code,
message: result.message,
+1 -1
View File
@@ -1355,8 +1355,8 @@ mod tests {
#[test]
fn workspace_issuer_trust_cli_persists_across_reload_and_writes_private_mode() {
use server_api::WorkspacePublicIdentityBundle;
use sha2::{Digest as _, Sha256};
use workspace_api::WorkspacePublicIdentityBundle;
let temp = tempfile::tempdir().unwrap();
let identity = RuntimeIdentityMaterial::generate("WK-1").unwrap();
+8 -8
View File
@@ -46,6 +46,7 @@ use protocol::subscription::{
SubscriptionWorkerState,
};
use protocol::{Event, Method};
use server_api::WorkerRestoreState;
use std::collections::BTreeMap;
#[cfg(feature = "ws-server")]
use std::collections::VecDeque;
@@ -55,7 +56,6 @@ use std::sync::{Arc, Mutex, MutexGuard, Weak};
use tokio::sync::broadcast;
use tokio::sync::mpsc;
use uuid::Uuid;
use workspace_api::WorkerRestoreState;
/// Workspace-scoped Runtime authorization context supplied by a trusted backend.
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -4835,8 +4835,8 @@ mod tests {
repository: WorkingDirectoryRepository {
id: "repository-1".to_string(),
provider: "git".to_string(),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.test/repo.git".to_string(),
},
source_revision: 1,
@@ -4859,7 +4859,7 @@ mod tests {
}],
host_trust_id: "host-trust-1".to_string(),
host_trust_revision: 1,
access: workspace_api::RepositoryAccessMode::ReadOnly,
access: server_api::RepositoryAccessMode::ReadOnly,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repository-1".to_string(),
repository_source_fingerprint: "sha256:source".to_string(),
@@ -4977,7 +4977,7 @@ mod tests {
],
host_trust_id: "host-trust-1".to_string(),
host_trust_revision: 1,
access: workspace_api::RepositoryAccessMode::ReadOnly,
access: server_api::RepositoryAccessMode::ReadOnly,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repository-1".to_string(),
repository_source_fingerprint: "sha256:source".to_string(),
@@ -5066,8 +5066,8 @@ mod tests {
repository: WorkingDirectoryRepository {
id: "repository-1".to_string(),
provider: "git".to_string(),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.test/repo.git".to_string(),
},
source_revision: 1,
@@ -5097,7 +5097,7 @@ mod tests {
],
host_trust_id: "host-trust-1".to_string(),
host_trust_revision: 1,
access: workspace_api::RepositoryAccessMode::ReadOnly,
access: server_api::RepositoryAccessMode::ReadOnly,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repository-1".to_string(),
repository_source_fingerprint: "sha256:source".to_string(),
+2 -2
View File
@@ -3583,8 +3583,8 @@ mod tests {
repository: WorkingDirectoryRepository {
id: "repo-main".to_string(),
provider: "git".to_string(),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: repo.display().to_string(),
},
source_revision: 1,
+1 -1
View File
@@ -455,7 +455,7 @@ impl WorkspaceClient for RuntimeOwnedWorkspaceClient {
fn list_workspace_workers(
&self,
request: worker::WorkspaceWorkerDiscoveryRequest,
) -> Result<workspace_api::WorkspaceWorkerDiscoveryPage, WorkspaceClientError> {
) -> Result<server_api::WorkspaceWorkerDiscoveryPage, WorkspaceClientError> {
let mut path = format!(
"/api/w/{}/worker-discovery/workers?limit={}",
self.workspace_id, request.limit
+44 -46
View File
@@ -842,8 +842,8 @@ impl RuntimeGitMaterializer {
binding.command_environment.insert(
"YOI_REPOSITORY_ACCESS".to_string(),
match access.access {
workspace_api::RepositoryAccessMode::ReadOnly => "read_only",
workspace_api::RepositoryAccessMode::ReadWrite => "read_write",
server_api::RepositoryAccessMode::ReadOnly => "read_only",
server_api::RepositoryAccessMode::ReadWrite => "read_write",
}
.to_string(),
);
@@ -884,7 +884,7 @@ impl RuntimeGitMaterializer {
Self::validate_plain_http_source(request)?;
if matches!(
request.repository.source.kind,
workspace_api::RepositorySourceKind::Https | workspace_api::RepositorySourceKind::Ssh
server_api::RepositorySourceKind::Https | server_api::RepositorySourceKind::Ssh
) {
validate_remote_source_uri(request)?;
let materialization = request.materialization.as_ref().ok_or_else(|| {
@@ -906,10 +906,10 @@ impl RuntimeGitMaterializer {
}
}
match request.repository.source.kind {
workspace_api::RepositorySourceKind::LocalPath
| workspace_api::RepositorySourceKind::File
| workspace_api::RepositorySourceKind::Https => {}
workspace_api::RepositorySourceKind::Ssh => {
server_api::RepositorySourceKind::LocalPath
| server_api::RepositorySourceKind::File
| server_api::RepositorySourceKind::Https => {}
server_api::RepositorySourceKind::Ssh => {
let ssh = request
.materialization
.as_ref()
@@ -922,7 +922,7 @@ impl RuntimeGitMaterializer {
})?;
validate_ssh_materialization_access(ssh)?;
}
workspace_api::RepositorySourceKind::Invalid => {
server_api::RepositorySourceKind::Invalid => {
return Err(WorkingDirectoryDiagnostic::new(
"working_directory_repository_source_invalid",
"configured Repository source is invalid and cannot be materialized",
@@ -939,7 +939,7 @@ impl RuntimeGitMaterializer {
) -> Result<WorkingDirectoryRequest, WorkingDirectoryDiagnostic> {
let mut request = request.clone();
if request.repository.provider != "git"
|| request.repository.source.kind != workspace_api::RepositorySourceKind::Ssh
|| request.repository.source.kind != server_api::RepositorySourceKind::Ssh
{
return Ok(request);
}
@@ -1911,7 +1911,7 @@ struct RepositorySshCommandPolicy {
username: Option<String>,
port: Option<u16>,
repository_path: String,
access: workspace_api::RepositoryAccessMode,
access: server_api::RepositoryAccessMode,
}
impl RepositorySshCommandPolicy {
@@ -2053,9 +2053,7 @@ fn repository_command_matches(command: &str, policy: &RepositorySshCommandPolicy
} else {
return false;
};
if operation == "receive-pack"
&& policy.access != workspace_api::RepositoryAccessMode::ReadWrite
{
if operation == "receive-pack" && policy.access != server_api::RepositoryAccessMode::ReadWrite {
return false;
}
let argument = argument
@@ -2218,7 +2216,7 @@ impl RepositoryCommandAccess {
runtime_root: &Path,
request: &WorkingDirectoryRequest,
) -> Result<Option<Self>, WorkingDirectoryDiagnostic> {
if request.repository.source.kind != workspace_api::RepositorySourceKind::Ssh {
if request.repository.source.kind != server_api::RepositorySourceKind::Ssh {
return Ok(None);
}
let Some(ssh) = request
@@ -2403,7 +2401,7 @@ fn validate_ssh_materialization_access(
fn validate_remote_source_uri(
request: &WorkingDirectoryRequest,
) -> Result<(), WorkingDirectoryDiagnostic> {
if request.repository.source.kind == workspace_api::RepositorySourceKind::Ssh {
if request.repository.source.kind == server_api::RepositorySourceKind::Ssh {
let source =
parse_repository_ssh_source(&request.repository.source.uri).ok_or_else(|| {
WorkingDirectoryDiagnostic::new(
@@ -2441,7 +2439,7 @@ fn validate_remote_source_uri(
"remote Repository source URI is invalid",
)
})?;
if request.repository.source.kind != workspace_api::RepositorySourceKind::Https {
if request.repository.source.kind != server_api::RepositorySourceKind::Https {
return Ok(());
}
if url.scheme() != "https"
@@ -2512,7 +2510,7 @@ fn repository_git_command(
let mut command = isolated_git_command();
let file_policy = if matches!(
request.repository.source.kind,
workspace_api::RepositorySourceKind::LocalPath | workspace_api::RepositorySourceKind::File
server_api::RepositorySourceKind::LocalPath | server_api::RepositorySourceKind::File
) {
"always"
} else {
@@ -2589,7 +2587,7 @@ fn test_repository_git_invocation_count() -> usize {
fn run_repository_git_stdout(
mut command: Command,
source_kind: workspace_api::RepositorySourceKind,
source_kind: server_api::RepositorySourceKind,
) -> Result<String, WorkingDirectoryDiagnostic> {
#[cfg(test)]
TEST_REPOSITORY_GIT_INVOCATIONS.with(|count| count.set(count.get().saturating_add(1)));
@@ -2837,10 +2835,10 @@ fn resolve_cloned_commit(
fn apply_repository_access_policy(
repository_root: &Path,
access: workspace_api::RepositoryAccessMode,
access: server_api::RepositoryAccessMode,
) -> Result<(), WorkingDirectoryDiagnostic> {
match access {
workspace_api::RepositoryAccessMode::ReadOnly => {
server_api::RepositoryAccessMode::ReadOnly => {
let mut disable_push = isolated_git_command();
disable_push.arg("-C").arg(repository_root).args([
"remote",
@@ -2851,7 +2849,7 @@ fn apply_repository_access_policy(
]);
run_repository_git(disable_push, "working_directory_repository_policy_failed")
}
workspace_api::RepositoryAccessMode::ReadWrite => {
server_api::RepositoryAccessMode::ReadWrite => {
if git_stdout(
repository_root,
["config", "--get-all", "remote.origin.pushurl"],
@@ -3122,7 +3120,7 @@ mod tests {
}],
host_trust_id: "trust-1".to_string(),
host_trust_revision: 4,
access: workspace_api::RepositoryAccessMode::ReadOnly,
access: server_api::RepositoryAccessMode::ReadOnly,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repo-main".to_string(),
repository_source_fingerprint: "sha256:test".to_string(),
@@ -3310,8 +3308,8 @@ mod tests {
repository: WorkingDirectoryRepository {
id: "repo-main".to_string(),
provider: "git".to_string(),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: repo.display().to_string(),
},
source_revision: 1,
@@ -3594,7 +3592,7 @@ mod tests {
assert!(!runtime_root.path().join(".repository-cache").exists());
let mut file_request = request(repo.path());
file_request.repository.source.kind = workspace_api::RepositorySourceKind::File;
file_request.repository.source.kind = server_api::RepositorySourceKind::File;
file_request.repository.source.uri = format!("file://{}", repo.path().display());
file_request.repository.source_revision = 2;
file_request.repository.source_fingerprint = "sha256:file-source".to_string();
@@ -3723,7 +3721,7 @@ mod tests {
],
host_trust_id: "trust-1".to_string(),
host_trust_revision: 1,
access: workspace_api::RepositoryAccessMode::ReadWrite,
access: server_api::RepositoryAccessMode::ReadWrite,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repo-main".to_string(),
repository_source_fingerprint: "sha256:test".to_string(),
@@ -3735,8 +3733,8 @@ mod tests {
}),
});
let mut ssh_operation = request.clone();
ssh_operation.repository.source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
ssh_operation.repository.source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.test/repo.git".to_string(),
};
let command_access = RepositoryCommandAccess::prepare(runtime_root.path(), &ssh_operation)
@@ -3810,8 +3808,8 @@ mod tests {
request.backend_workdir_id = Some(working_directory_id.clone());
request.materialization.as_mut().unwrap().ssh = None;
let mut authorized_ssh_request = request.clone();
authorized_ssh_request.repository.source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
authorized_ssh_request.repository.source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.test/repo.git".to_string(),
};
assert!(
@@ -3910,7 +3908,7 @@ mod tests {
let mut rotated = initial_materialization.clone();
rotated.operation_id = "operation-agent-rotated".to_string();
rotated.ssh.as_mut().unwrap().credential_candidates[0].credential_revision = 2;
rotated.ssh.as_mut().unwrap().access = workspace_api::RepositoryAccessMode::ReadOnly;
rotated.ssh.as_mut().unwrap().access = server_api::RepositoryAccessMode::ReadOnly;
materializer
.authorize_repository_access(&WorkingDirectoryRepositoryAccessRequest {
working_directory_id: id.clone(),
@@ -4028,7 +4026,7 @@ mod tests {
let mut read_write = rotated;
read_write.operation_id = "operation-agent-read-write".to_string();
read_write.ssh.as_mut().unwrap().credential_candidates[0].credential_revision = 3;
read_write.ssh.as_mut().unwrap().access = workspace_api::RepositoryAccessMode::ReadWrite;
read_write.ssh.as_mut().unwrap().access = server_api::RepositoryAccessMode::ReadWrite;
let read_write_command_policy =
RepositorySshCommandPolicy::from_access(read_write.ssh.as_ref().unwrap()).unwrap();
materializer
@@ -4099,7 +4097,7 @@ mod tests {
}],
host_trust_id: "trust-1".to_string(),
host_trust_revision: 1,
access: workspace_api::RepositoryAccessMode::ReadOnly,
access: server_api::RepositoryAccessMode::ReadOnly,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repo-main".to_string(),
repository_source_fingerprint: "sha256:test".to_string(),
@@ -4251,8 +4249,8 @@ mod tests {
assert_eq!(policy.repository_path, "team/repo.git");
let mut request = request(Path::new("."));
request.repository.source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
request.repository.source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: uri.to_string(),
};
request.materialization = Some(crate::catalog::RepositoryMaterializationContext {
@@ -4294,8 +4292,8 @@ mod tests {
};
let mut https = request(repo.path());
https.repository.source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Https,
https.repository.source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Https,
uri: "https://token@example.test/repo.git".to_string(),
};
https.materialization = Some(context(None));
@@ -4330,15 +4328,15 @@ mod tests {
);
for (offset, kind) in [
workspace_api::RepositorySourceKind::LocalPath,
workspace_api::RepositorySourceKind::File,
workspace_api::RepositorySourceKind::Https,
server_api::RepositorySourceKind::LocalPath,
server_api::RepositorySourceKind::File,
server_api::RepositorySourceKind::Https,
]
.into_iter()
.enumerate()
{
let mut mismatched_http = request(repo.path());
mismatched_http.repository.source = workspace_api::RepositorySource {
mismatched_http.repository.source = server_api::RepositorySource {
kind,
uri: "http://example.test/repo.git".to_string(),
};
@@ -4358,8 +4356,8 @@ mod tests {
}
let mut ssh = request(repo.path());
ssh.repository.source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
ssh.repository.source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.test/repo.git".to_string(),
};
ssh.materialization = Some(context(Some(
@@ -4371,7 +4369,7 @@ mod tests {
}],
host_trust_id: "trust-1".to_string(),
host_trust_revision: 1,
access: workspace_api::RepositoryAccessMode::ReadOnly,
access: server_api::RepositoryAccessMode::ReadOnly,
expires_at_epoch_seconds: u64::MAX,
repository_id: "repo-main".to_string(),
repository_source_fingerprint: "sha256:test".to_string(),
@@ -4396,8 +4394,8 @@ mod tests {
let runtime_root = tempfile::tempdir().unwrap();
let materializer = RuntimeGitMaterializer::new(runtime_root.path());
let mut remote = request(Path::new("."));
remote.repository.source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
remote.repository.source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Ssh,
uri: "ssh://git@example.invalid/repo.git".to_string(),
};
remote.materialization = Some(crate::catalog::RepositoryMaterializationContext {
@@ -8,8 +8,8 @@ use base64::Engine as _;
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
use ring::signature::Ed25519KeyPair;
use serde::{Deserialize, Serialize};
use server_api::WorkspacePublicIdentityBundle;
use sha2::{Digest, Sha256};
use workspace_api::WorkspacePublicIdentityBundle;
use crate::auth::RuntimeAuthError;
+1 -1
View File
@@ -28,7 +28,7 @@ toml = { workspace = true }
tracing = { workspace = true }
tools = { workspace = true }
workdir = { workspace = true }
workspace-api = { workspace = true }
server-api = { workspace = true }
minijinja = "2.19.0"
chrono = "0.4"
config-source = { path = "../config-source" }
@@ -23,7 +23,7 @@ use workdir::{
WorkdirSessionCapabilities, WorkdirSessionHandle, WriteRequest, WriteResult,
};
use workspace_api::{
use server_api::{
WorkingDirectoryCreateRequest as WorkdirCreateRequest,
WorkingDirectoryCreateResponse as WorkdirCreateResponse,
WorkingDirectoryListResponse as WorkdirListResponse,
@@ -168,7 +168,7 @@ fn input_schema() -> serde_json::Value {
mod tests {
use std::sync::Mutex;
use workspace_api::{
use server_api::{
WorkspaceWorkerDiscoveryItem, WorkspaceWorkerDiscoveryPage, WorkspaceWorkerSubject,
};
+2 -2
View File
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
use crate::worker::WorkspaceClient;
pub use workspace_api::{
pub use server_api::{
SkillActivationStatus, SkillCatalogEntry, SkillCatalogResponse, SkillDetailResponse,
SkillDiagnostic, SkillDiagnosticSeverity, SkillProjectionIdentity, SkillProjectionStatus,
SkillProvenance, SkillResourceRef, SkillSourceKind,
@@ -29,7 +29,7 @@ pub enum SkillClientError {
#[error("Skill API response JSON is invalid: {0}")]
Json(#[from] serde_json::Error),
#[error("Skill API response violates the shared contract: {0}")]
InvalidResponse(#[from] workspace_api::SkillApiValidationError),
InvalidResponse(#[from] server_api::SkillApiValidationError),
#[error("Skill API returned HTTP {status}: {body}")]
Http {
status: reqwest::StatusCode,
+1 -1
View File
@@ -559,7 +559,7 @@ pub trait WorkspaceClient: std::fmt::Debug + Send + Sync {
fn list_workspace_workers(
&self,
_request: WorkspaceWorkerDiscoveryRequest,
) -> Result<workspace_api::WorkspaceWorkerDiscoveryPage, WorkspaceClientError> {
) -> Result<server_api::WorkspaceWorkerDiscoveryPage, WorkspaceClientError> {
Err(WorkspaceClientError::Unavailable(
"Workspace Worker discovery authority is unavailable".to_string(),
))
-51
View File
@@ -1,51 +0,0 @@
[package]
name = "workspace-api"
version = "0.1.0"
edition.workspace = true
license.workspace = true
publish = false
[features]
default = []
typescript = ["dep:ts-rs", "protocol/typescript"]
[dependencies]
protocol.workspace = true
serde = { workspace = true, features = ["derive"] }
ts-rs = { version = "12.0.1", optional = true }
webauthn-rs-proto = "0.5.5"
[[example]]
name = "generate_typescript"
required-features = ["typescript"]
[dev-dependencies]
serde_json.workspace = true
[[example]]
name = "generate_workdir_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_worker_launch_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_companion_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_memory_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_skill_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_auth_api_types"
required-features = ["typescript"]
[[example]]
name = "generate_repository_access_types"
required-features = ["typescript"]
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::auth_api_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::companion_api_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::memory_api_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::repository_access_api_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::skill_api_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::catalog_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::workdir_api_typescript());
}
@@ -1,3 +0,0 @@
fn main() {
print!("{}", workspace_api::worker_launch_api_typescript());
}
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -12,7 +12,7 @@ path = "src/main.rs"
[features]
default = ["typescript"]
typescript = ["dep:ts-rs", "workspace-api/typescript"]
typescript = ["dep:ts-rs", "server-api/typescript"]
[dependencies]
async-trait.workspace = true
@@ -42,7 +42,6 @@ tokio = { workspace = true, features = ["fs", "macros", "net", "rt-multi-thread"
tower.workspace = true
tokio-tungstenite = { workspace = true, features = ["rustls-tls-webpki-roots"] }
worker.workspace = true
workspace-api.workspace = true
workdir = { workspace = true, features = ["http-client"] }
worker-runtime.workspace = true
toml.workspace = true
+1 -1
View File
@@ -1,8 +1,8 @@
use axum::http::{HeaderMap, header};
use chrono::{DateTime, Duration, Utc};
pub use server_api::{ActorAuthMethod, AuthPublicConfig, AuthenticatedUser, RequestActor};
use sha2::{Digest, Sha256};
use uuid::Uuid;
pub use workspace_api::{ActorAuthMethod, AuthPublicConfig, AuthenticatedUser, RequestActor};
use crate::{Error, Result, store::ControlPlaneStore};
+2 -2
View File
@@ -1,9 +1,9 @@
use workspace_api::{
use server_api::{
CompanionLifecycleState, CompanionMessageDisposition, CompanionTransportSummary, Diagnostic,
DiagnosticSeverity,
};
pub use workspace_api::{
pub use server_api::{
CompanionCancelRequest, CompanionMessageRequest, CompanionMessageResponse,
CompanionStatusResponse, CompanionTranscriptProjection,
};
+40 -27
View File
@@ -275,12 +275,12 @@ pub struct WorkerSummary {
pub diagnostics: Vec<RuntimeDiagnostic>,
}
impl From<RuntimeDiagnostic> for workspace_api::Diagnostic {
impl From<RuntimeDiagnostic> for server_api::Diagnostic {
fn from(diagnostic: RuntimeDiagnostic) -> Self {
let severity = match diagnostic.severity {
DiagnosticSeverity::Info => workspace_api::DiagnosticSeverity::Info,
DiagnosticSeverity::Warning => workspace_api::DiagnosticSeverity::Warning,
DiagnosticSeverity::Error => workspace_api::DiagnosticSeverity::Error,
DiagnosticSeverity::Info => server_api::DiagnosticSeverity::Info,
DiagnosticSeverity::Warning => server_api::DiagnosticSeverity::Warning,
DiagnosticSeverity::Error => server_api::DiagnosticSeverity::Error,
};
Self {
code: diagnostic.code,
@@ -290,21 +290,21 @@ impl From<RuntimeDiagnostic> for workspace_api::Diagnostic {
}
}
impl From<RuntimeSourceSummary> for workspace_api::RuntimeSourceSummary {
impl From<RuntimeSourceSummary> for server_api::RuntimeSourceSummary {
fn from(source: RuntimeSourceSummary) -> Self {
let kind = match source.kind {
RuntimeSourceKind::EmbeddedWorkerRuntime => {
workspace_api::RuntimeSourceKind::EmbeddedWorkerRuntime
server_api::RuntimeSourceKind::EmbeddedWorkerRuntime
}
RuntimeSourceKind::RemoteHttp => workspace_api::RuntimeSourceKind::RemoteHttp,
RuntimeSourceKind::RemoteHttp => server_api::RuntimeSourceKind::RemoteHttp,
};
let status = match source.status {
RuntimeSourceStatus::Active => workspace_api::RuntimeSourceStatus::Active,
RuntimeSourceStatus::Reserved => workspace_api::RuntimeSourceStatus::Reserved,
RuntimeSourceStatus::Active => server_api::RuntimeSourceStatus::Active,
RuntimeSourceStatus::Reserved => server_api::RuntimeSourceStatus::Reserved,
};
let identity_authority = match source.identity_authority {
RuntimeIdentityAuthority::RuntimeRegistryProjection => {
workspace_api::RuntimeIdentityAuthority::RuntimeRegistryProjection
server_api::RuntimeIdentityAuthority::RuntimeRegistryProjection
}
};
Self {
@@ -316,7 +316,7 @@ impl From<RuntimeSourceSummary> for workspace_api::RuntimeSourceSummary {
}
}
impl From<RuntimeSummary> for workspace_api::RuntimeSummary {
impl From<RuntimeSummary> for server_api::RuntimeSummary {
fn from(runtime: RuntimeSummary) -> Self {
Self {
runtime_id: runtime.runtime_id,
@@ -336,9 +336,9 @@ impl From<RuntimeSummary> for workspace_api::RuntimeSummary {
pub(crate) fn workspace_worker_summary(
summary: WorkerSummary,
resource_key: String,
working_directory: Option<workspace_api::WorkingDirectorySummary>,
) -> workspace_api::WorkerSummary {
workspace_api::WorkerSummary {
working_directory: Option<server_api::WorkingDirectorySummary>,
) -> server_api::WorkerSummary {
server_api::WorkerSummary {
runtime_id: summary.worker.runtime_id,
worker_id: summary.worker.worker_id,
resource_key,
@@ -348,7 +348,7 @@ pub(crate) fn workspace_worker_summary(
profile: summary.profile,
singleton_key: summary.singleton_key,
tags: summary.tags,
workspace: workspace_api::WorkerWorkspaceSummary {
workspace: server_api::WorkerWorkspaceSummary {
visibility: summary.workspace.visibility,
identity: summary.workspace.identity,
workspace_id: summary.workspace.workspace_id,
@@ -358,11 +358,11 @@ pub(crate) fn workspace_worker_summary(
last_seen_at: summary.last_seen_at,
pinned: summary.pinned,
retention_state: summary.retention_state,
implementation: workspace_api::WorkerImplementationSummary {
implementation: server_api::WorkerImplementationSummary {
kind: summary.implementation.kind,
display_hint: summary.implementation.display_hint,
},
capabilities: workspace_api::WorkerCapabilitySummary {
capabilities: server_api::WorkerCapabilitySummary {
can_stop: summary.capabilities.can_stop,
can_spawn_followup: summary.capabilities.can_spawn_followup,
},
@@ -374,7 +374,7 @@ pub(crate) fn workspace_worker_summary(
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub struct WorkerRestoreResult {
pub state: workspace_api::WorkerRestoreState,
pub state: server_api::WorkerRestoreState,
#[serde(skip_serializing_if = "Option::is_none")]
pub worker: Option<WorkerSummary>,
pub diagnostics: Vec<RuntimeDiagnostic>,
@@ -613,7 +613,7 @@ pub enum WorkerOperationState {
Rejected,
}
impl From<WorkerOperationState> for workspace_api::WorkerOperationState {
impl From<WorkerOperationState> for server_api::WorkerOperationState {
fn from(state: WorkerOperationState) -> Self {
match state {
WorkerOperationState::Accepted => Self::Accepted,
@@ -877,7 +877,7 @@ pub trait WorkspaceWorkerRuntime: Send + Sync {
fn restore_worker(&self, worker_id: &str) -> WorkerRestoreResult {
WorkerRestoreResult {
state: workspace_api::WorkerRestoreState::Rejected,
state: server_api::WorkerRestoreState::Rejected,
worker: None,
diagnostics: vec![diagnostic(
"worker_restore_unsupported",
@@ -2365,7 +2365,7 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime {
fn restore_worker(&self, worker_id: &str) -> WorkerRestoreResult {
let Some(worker_ref) = self.worker_ref(worker_id) else {
return WorkerRestoreResult {
state: workspace_api::WorkerRestoreState::Rejected,
state: server_api::WorkerRestoreState::Rejected,
worker: None,
diagnostics: vec![diagnostic(
"embedded_worker_id_invalid",
@@ -2389,7 +2389,7 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime {
}
}
Err(err) => WorkerRestoreResult {
state: workspace_api::WorkerRestoreState::ReconciliationRequired,
state: server_api::WorkerRestoreState::ReconciliationRequired,
worker: None,
diagnostics: vec![embedded_runtime_diagnostic(&err)],
},
@@ -4318,7 +4318,20 @@ impl WorkspaceWorkerRuntime for RemoteWorkerRuntime {
_ => Vec::new(),
};
WorkerRestoreResult {
state,
state: match state {
runtime_api::WorkerRestoreState::Accepted => {
server_api::WorkerRestoreState::Accepted
}
runtime_api::WorkerRestoreState::Rejected => {
server_api::WorkerRestoreState::Rejected
}
runtime_api::WorkerRestoreState::RolledBack => {
server_api::WorkerRestoreState::RolledBack
}
runtime_api::WorkerRestoreState::ReconciliationRequired => {
server_api::WorkerRestoreState::ReconciliationRequired
}
},
worker: worker.map(|worker| self.map_worker_detail(worker)),
diagnostics,
}
@@ -4326,7 +4339,7 @@ impl WorkspaceWorkerRuntime for RemoteWorkerRuntime {
Err(diagnostic) => WorkerRestoreResult {
// A transport/protocol failure cannot prove that the Runtime
// rejected before side effects. Preserve uncertainty.
state: workspace_api::WorkerRestoreState::ReconciliationRequired,
state: server_api::WorkerRestoreState::ReconciliationRequired,
worker: None,
diagnostics: vec![diagnostic],
},
@@ -5769,7 +5782,7 @@ mod tests {
assert_eq!(
result.state,
workspace_api::WorkerRestoreState::ReconciliationRequired
server_api::WorkerRestoreState::ReconciliationRequired
);
assert!(result.worker.is_none());
assert_eq!(result.diagnostics.len(), 1);
@@ -6206,8 +6219,8 @@ mod tests {
repository: worker_runtime::catalog::WorkingDirectoryRepository {
id: "repository-1".to_string(),
provider: "git".to_string(),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/provider/repository.git".to_string(),
},
source_revision: 7,
+2 -2
View File
@@ -48,11 +48,11 @@ pub use server::{
AuthConfig, ServerConfig, WorkspaceApi, WorkspaceServerApi, build_router,
build_workspace_server_router, serve, serve_workspace_catalog,
};
pub use store::{ControlPlaneStore, SqliteWorkspaceStore, WorkspaceRecord};
pub use workspace_api::{
pub use server_api::{
GitCommitSummary, GitRemoteSummary, GitRepositorySummary, RepositorySummary,
WorkspaceCreateResponse,
};
pub use store::{ControlPlaneStore, SqliteWorkspaceStore, WorkspaceRecord};
pub use workspace_catalog::{
InitialRepositoryIntent, WorkspaceCatalogService, WorkspaceCreateRequest, WorkspaceCreateResult,
};
@@ -1,6 +1,6 @@
use memory::extract::{CandidateKind, StagingRecord};
use memory::schema::{EvidenceOrigin, EvidenceOriginKind, SourceEvidenceRef, SourceRef};
use workspace_api::{
use server_api::{
Diagnostic, DiagnosticSeverity, MemoryCandidateKind, MemoryEvidenceOrigin,
MemoryEvidenceOriginKind, MemorySourceEvidenceRef, MemorySourceRef, MemoryStagingEntry,
MemoryStagingEvidence, MemoryStagingListResponse, MemoryStagingRecord,
@@ -4,16 +4,16 @@ use std::path::{Component, Path, PathBuf};
use config_source::{ConfigContentType, ConfigSchemaContribution, VirtualPath};
use manifest::{ProfileSource, builtin_profile_catalog_snapshot, resolve_profile_artifact_value};
use serde::Deserialize;
use server_api::{
ProfileSettingsResponse, WorkspaceMetadataSettingsResponse, WorkspaceProfileSourceProvenance,
WorkspaceProfileSourceSummary, WorkspaceProfileSummary,
};
use sha2::{Digest, Sha256};
use worker::EffectivePromptCatalog;
use worker_runtime::config_bundle::{
ConfigBundle, ConfigBundleMetadata, ConfigBundleProvenance, ConfigProfileDescriptor,
};
use worker_runtime::profile_archive::{ProfileSourceArchive, ProfileSourceArchiveInput};
use workspace_api::{
ProfileSettingsResponse, WorkspaceMetadataSettingsResponse, WorkspaceProfileSourceProvenance,
WorkspaceProfileSourceSummary, WorkspaceProfileSummary,
};
use crate::config_source::{
WorkspaceConfigSchemaProvider, WorkspaceConfigState, evaluate_workspace_config_state,
+1 -1
View File
@@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize};
pub use workspace_api::{
pub use server_api::{
ObjectiveDetail, ObjectiveEventDetail, ObjectiveLinkedTicketSummary, ObjectiveResourceSummary,
ObjectiveSummary, QueryPage,
};
+5 -8
View File
@@ -4,7 +4,7 @@ use std::{
process::Command,
};
use workspace_api::{
use server_api::{
Diagnostic, DiagnosticSeverity, GitCommitSummary, GitRemoteSummary, GitRepositorySummary,
RepositoryDiagnostic, RepositoryObservedStatus, RepositorySource, RepositorySummary,
};
@@ -629,7 +629,7 @@ mod tests {
let projection = reader.list();
assert_eq!(
projection.items[0].source.kind,
workspace_api::RepositorySourceKind::Invalid
server_api::RepositorySourceKind::Invalid
);
let diagnostics = projection.items[0].diagnostics.as_ref().unwrap();
assert!(diagnostics.iter().any(|diagnostic| {
@@ -642,7 +642,7 @@ mod tests {
#[test]
fn remote_source_is_visible_but_local_provider_operations_fail_closed() {
let source = RepositorySource {
kind: workspace_api::RepositorySourceKind::Ssh,
kind: server_api::RepositorySourceKind::Ssh,
uri: "git@example.test:org/repository.git".to_string(),
};
let reader = RepositoryRegistryReader::new(vec![ConfiguredRepository {
@@ -660,10 +660,7 @@ mod tests {
let projection = reader.list();
let summary = &projection.items[0];
assert_eq!(
summary.source.kind,
workspace_api::RepositorySourceKind::Ssh
);
assert_eq!(summary.source.kind, server_api::RepositorySourceKind::Ssh);
assert_eq!(
summary.observed_status,
RepositoryObservedStatus::Unverified
@@ -766,7 +763,7 @@ mod tests {
);
let source_descriptor = RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
kind: server_api::RepositorySourceKind::LocalPath,
uri: path.display().to_string(),
};
let reader = RepositoryRegistryReader::new(vec![ConfiguredRepository {
@@ -11,16 +11,16 @@ use ring::hmac;
use ring::rand::{SecureRandom, SystemRandom};
use rusqlite::{OptionalExtension, TransactionBehavior, params};
use serde::Deserialize;
use sha2::{Digest, Sha256};
use ssh_key::private::Ed25519Keypair;
use ssh_key::{Algorithm, HashAlg, LineEnding, PrivateKey, PublicKey};
use workspace_api::{
use server_api::{
CreateRepositorySshCredentialRequest, DeleteRepositorySshCredentialRequest,
DeleteRepositorySshHostTrustRequest, GenerateRepositorySshCredentialRequest,
PutRepositorySshHostTrustRequest, RepositoryAccessMode, RepositoryAccessProjection,
RepositorySshAccessBinding, RepositorySshCredential, RepositorySshHostTrust,
RepositorySshPublicKey, RotateRepositorySshCredentialRequest,
};
use sha2::{Digest, Sha256};
use ssh_key::private::Ed25519Keypair;
use ssh_key::{Algorithm, HashAlg, LineEnding, PrivateKey, PublicKey};
use crate::config_source::{
EvaluatedConfigCandidate, WorkspaceConfigSchemaProvider, WorkspaceConfigState,
@@ -138,7 +138,7 @@ pub fn project_repository_access_state(
fn validate_repository_access_source(
repository_key: &str,
source: &workspace_api::RepositorySource,
source: &server_api::RepositorySource,
) -> Result<()> {
if crate::repository_source::is_plain_http_repository_source(source) {
return Err(Error::InvalidInput(format!(
@@ -205,7 +205,7 @@ fn project_repository_access_evaluation(
}
let mut bindings = Vec::with_capacity(config.repository_access.len());
for (repository_key, access) in config.repository_access {
workspace_api::validate_repository_key(&repository_key)
server_api::validate_repository_key(&repository_key)
.map_err(|error| Error::InvalidInput(format!("invalid Repository key: {error}")))?;
validate_identifier("credential_id", &access.ssh.credential)?;
validate_identifier("host_trust_id", &access.ssh.host_trust)?;
@@ -213,7 +213,7 @@ fn project_repository_access_evaluation(
.get_repository_by_key(workspace_id, &repository_key)?
.ok_or_else(|| Error::InvalidInput(format!("unknown Repository `{repository_key}`")))?;
validate_repository_access_source(&repository_key, &repository.source)?;
if repository.source.kind != workspace_api::RepositorySourceKind::Ssh {
if repository.source.kind != server_api::RepositorySourceKind::Ssh {
return Err(Error::InvalidInput(format!(
"Repository `{repository_key}` is not an ssh:// Repository"
)));
@@ -1940,8 +1940,8 @@ mod tests {
DEFAULT_SCHEMA_VERSION, SnapshotEnvironment, ToolchainContract, VirtualPath,
WorkspaceConfigSchemaBundle,
};
use server_api::{RepositoryObservedStatus, RepositorySource, RepositorySourceKind};
use ssh_key::private::Ed25519Keypair;
use workspace_api::{RepositoryObservedStatus, RepositorySource, RepositorySourceKind};
fn test_private_key(seed: u8) -> (String, String) {
let key = PrivateKey::from(Ed25519Keypair::from_seed(&[seed; 32]));
@@ -1995,8 +1995,8 @@ mod tests {
assert!(error.to_string().contains("unsupported plain HTTP"));
assert!(error.to_string().contains("HTTPS or SSH"));
let mismatched = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::Https,
let mismatched = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::Https,
uri: "http://git.example.test/team/project.git".to_string(),
};
let error = validate_repository_access_source("remote", &mismatched).unwrap_err();
@@ -1,8 +1,8 @@
use std::path::Path;
use server_api::{RepositorySource, RepositorySourceKind};
use sha2::{Digest, Sha256};
use url::Url;
use workspace_api::{RepositorySource, RepositorySourceKind};
use crate::{Error, Result};
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -4,12 +4,12 @@ use config_source::{
ConfigSchemaContribution, MarkdownDocumentProjection, VirtualPath, project_markdown_document,
};
use serde::Deserialize;
use worker::skill::SkillActivationResponse;
use workspace_api::{
use server_api::{
SKILL_CATALOG_AUTHORITY, SkillActivationStatus, SkillCatalogEntry, SkillCatalogResponse,
SkillDetailResponse, SkillDiagnostic, SkillDiagnosticSeverity, SkillProjectionIdentity,
SkillProjectionStatus, SkillProvenance, SkillResourceRef, SkillSourceKind,
};
use worker::skill::SkillActivationResponse;
use crate::config_source::{
WorkspaceConfigSchemaProvider, WorkspaceConfigState, evaluate_workspace_config_state,
+14 -14
View File
@@ -11,8 +11,8 @@ use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use uuid::Uuid;
use server_api::{RepositoryObservedStatus, RepositorySource};
use worker_runtime::identity::{RuntimeWorkerRef, WorkerId};
use workspace_api::{RepositoryObservedStatus, RepositorySource};
use crate::workspace_deletion::WorkspaceDeletionStore;
use crate::{Error, Result};
@@ -7496,15 +7496,15 @@ fn repository_registration_intent_matches(
}
fn validate_repository_record_identity(record: &RepositoryRecord) -> Result<()> {
workspace_api::validate_repository_key(&record.repository_key)
server_api::validate_repository_key(&record.repository_key)
.map_err(|error| Error::InvalidInput(format!("invalid Repository key: {error}")))?;
Ok(())
}
fn read_repository_record(row: &rusqlite::Row<'_>) -> rusqlite::Result<RepositoryRecord> {
let source_kind_value = row.get::<_, String>(5)?;
let source_kind = workspace_api::RepositorySourceKind::parse(&source_kind_value)
.unwrap_or(workspace_api::RepositorySourceKind::Invalid);
let source_kind = server_api::RepositorySourceKind::parse(&source_kind_value)
.unwrap_or(server_api::RepositorySourceKind::Invalid);
let source_revision = row.get::<_, u64>(8)?;
let source_fingerprint = row.get::<_, String>(9)?;
let mut source = RepositorySource {
@@ -7517,7 +7517,7 @@ fn read_repository_record(row: &rusqlite::Row<'_>) -> rusqlite::Result<Repositor
if source_revision == 0
|| crate::repository_source::repository_source_fingerprint(&source) != source_fingerprint
{
source.kind = workspace_api::RepositorySourceKind::Invalid;
source.kind = server_api::RepositorySourceKind::Invalid;
observed_status = RepositoryObservedStatus::Invalid;
}
Ok(RepositoryRecord {
@@ -12411,7 +12411,7 @@ mod tests {
kind: "git".to_string(),
provider: Some("git".to_string()),
source: RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/repo-a".to_string(),
},
default_ref: Some("HEAD".to_string()),
@@ -13255,7 +13255,7 @@ INSERT INTO worker_registry (
kind: "git".to_string(),
provider: Some("git".to_string()),
source: RepositorySource {
kind: workspace_api::RepositorySourceKind::File,
kind: server_api::RepositorySourceKind::File,
uri: "file:///tmp/main".to_string(),
},
default_ref: Some("develop".to_string()),
@@ -13672,8 +13672,8 @@ INSERT INTO worker_registry (
repository_key: "Invalid_Key".to_string(),
kind: "git".to_string(),
provider: Some("git".to_string()),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/repo".to_string(),
},
default_ref: Some("develop".to_string()),
@@ -13723,8 +13723,8 @@ INSERT INTO worker_registry (
repository_key: "main".to_string(),
kind: "git".to_string(),
provider: Some("git".to_string()),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/repo".to_string(),
},
default_ref: Some("develop".to_string()),
@@ -13798,14 +13798,14 @@ INSERT INTO worker_registry (
kind: "git".to_string(),
provider: Some("git".to_string()),
source: RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/repo".to_string(),
},
default_ref: Some("HEAD".to_string()),
source_revision: 1,
source_fingerprint: crate::repository_source::repository_source_fingerprint(
&RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/repo".to_string(),
},
),
@@ -13955,7 +13955,7 @@ INSERT INTO worker_registry (
kind: "git".to_string(),
provider: Some("git".to_string()),
source: RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/repo".to_string(),
},
default_ref: Some("HEAD".to_string()),
@@ -549,14 +549,14 @@ mod tests {
repository_key: "main".to_string(),
kind: "git".to_string(),
provider: Some("git".to_string()),
source: workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
source: server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: "/tmp/main".to_string(),
},
default_ref: Some("develop".to_string()),
source_revision: 1,
source_fingerprint: "sha256:test".to_string(),
observed_status: workspace_api::RepositoryObservedStatus::Unverified,
observed_status: server_api::RepositoryObservedStatus::Unverified,
observed_at: None,
created_at: "2026-08-24T00:00:00Z".to_string(),
updated_at: "2026-08-24T00:00:00Z".to_string(),
@@ -879,7 +879,7 @@ fn hex_sha256(bytes: &[u8]) -> String {
mod tests {
use super::*;
use crate::store::{AccountRecord, ControlPlaneStore, RepositoryRecord, WorkspaceRecord};
use workspace_api::{RepositoryObservedStatus, RepositorySource, RepositorySourceKind};
use server_api::{RepositoryObservedStatus, RepositorySource, RepositorySourceKind};
fn attempt_owner() -> WorkdirRemovalAttemptOwner {
WorkdirRemovalAttemptOwner {
@@ -4,8 +4,8 @@ use chrono::{SecondsFormat, Utc};
use sha2::{Digest, Sha256};
use uuid::Uuid;
pub use workspace_api::{InitialRepositoryIntent, WorkspaceCreateRequest};
use workspace_api::{RepositoryObservedStatus, RepositorySource};
pub use server_api::{InitialRepositoryIntent, WorkspaceCreateRequest};
use server_api::{RepositoryObservedStatus, RepositorySource};
use crate::repository_source::{parse_repository_source, repository_source_fingerprint};
use crate::store::{
@@ -96,7 +96,7 @@ impl WorkspaceCatalogService {
normalize_required("display_name", request.display_name, MAX_DISPLAY_NAME_BYTES)?;
let repository_source = validate_repository_source(&request.repository.uri)?;
let repository_uri = repository_source.uri.clone();
workspace_api::validate_repository_key(&request.repository.repository_key)
server_api::validate_repository_key(&request.repository.repository_key)
.map_err(|error| Error::InvalidInput(format!("invalid Repository key: {error}")))?;
let repository_key = request.repository.repository_key.clone();
let default_ref = request
@@ -228,7 +228,7 @@ mod tests {
InMemoryWorkspaceSigningMaterialStore, WorkspaceSigningMaterialStore,
WorkspaceSigningPrivateMaterial, identity_error,
};
use workspace_api::RepositorySourceKind;
use server_api::RepositorySourceKind;
struct FailFirstMaterialWrite {
inner: Arc<InMemoryWorkspaceSigningMaterialStore>,
@@ -1,7 +1,6 @@
use chrono::Utc;
use rusqlite::{OptionalExtension, params};
use sha2::{Digest, Sha256};
use workspace_api::{
use server_api::{
WORKSPACE_DELETION_MAX_BLOCKER_MESSAGE_BYTES, WORKSPACE_DELETION_MAX_BLOCKERS,
WORKSPACE_DELETION_MAX_CHILD_OPERATION_IDS, WORKSPACE_DELETION_MAX_OPERATION_ID_BYTES,
WORKSPACE_DELETION_MAX_RESOURCE_VALUE_BYTES, WORKSPACE_DELETION_MAX_REVISION_BYTES,
@@ -9,6 +8,7 @@ use workspace_api::{
WorkspaceDeletionPreflightResponse, WorkspaceDeletionRequest, WorkspaceDeletionResourceCounts,
WorkspaceDeletionState,
};
use sha2::{Digest, Sha256};
use crate::store::{SqliteWorkspaceStore, WorkspaceRecord};
use crate::{Error, Result};
@@ -200,7 +200,7 @@ impl WorkspaceDeletionStore for SqliteWorkspaceStore {
) -> Result<WorkspaceDeletionReservation> {
validate_operation_id(&request.operation_id)?;
if request.expected_revision.len() > WORKSPACE_DELETION_MAX_REVISION_BYTES
|| request.confirmation.len() > workspace_api::WORKSPACE_DELETION_MAX_CONFIRMATION_BYTES
|| request.confirmation.len() > server_api::WORKSPACE_DELETION_MAX_CONFIRMATION_BYTES
{
return Err(Error::InvalidInput(
"Workspace deletion request exceeds bounded field limits".to_string(),
+1 -1
View File
@@ -15,7 +15,7 @@ client = { workspace = true }
memory = { workspace = true }
manifest = { workspace = true }
worker = { workspace = true }
workspace-api = { workspace = true }
server-api = { workspace = true }
session-store = { workspace = true }
session-analytics = { workspace = true }
ticket = { workspace = true }
+1 -1
View File
@@ -148,7 +148,7 @@ fn run_with_backend(
return Err(ObjectiveCliError::new("create --title must not be empty"));
}
let objective = backend
.create_objective(&workspace_api::ObjectiveCreateRequest {
.create_objective(&server_api::ObjectiveCreateRequest {
title: title.to_string(),
body_md: objective_body_template(),
state: "active".to_string(),
+15 -18
View File
@@ -21,7 +21,7 @@ pub(crate) struct InitOptions {
pub(crate) async fn run_init(
options: InitOptions,
) -> Result<workspace_api::WorkspaceCreateResponse, ParseError> {
) -> Result<server_api::WorkspaceCreateResponse, ParseError> {
let repository_uri = options
.repository_root
.to_str()
@@ -82,8 +82,8 @@ pub(crate) fn discover_repository_root(path: &Path) -> Result<PathBuf, ParseErro
fn select_workspace_from_repository_catalog(
repository: &OpenRepositoryIdentity,
catalog: &[(
workspace_api::WorkspaceSummary,
Vec<workspace_api::RepositorySummary>,
server_api::WorkspaceSummary,
Vec<server_api::RepositorySummary>,
)],
) -> Result<String, ParseError> {
let matches = catalog
@@ -122,22 +122,21 @@ struct OpenRepositoryIdentity {
}
impl OpenRepositoryIdentity {
fn matches(&self, source: &workspace_api::RepositorySource) -> bool {
fn matches(&self, source: &server_api::RepositorySource) -> bool {
match source.kind {
workspace_api::RepositorySourceKind::LocalPath => fs::canonicalize(&source.uri)
server_api::RepositorySourceKind::LocalPath => fs::canonicalize(&source.uri)
.ok()
.is_some_and(|path| path == self.root),
workspace_api::RepositorySourceKind::File => source
server_api::RepositorySourceKind::File => source
.uri
.strip_prefix("file://")
.and_then(|path| fs::canonicalize(path).ok())
.is_some_and(|path| path == self.root),
workspace_api::RepositorySourceKind::Ssh
| workspace_api::RepositorySourceKind::Https => self
server_api::RepositorySourceKind::Ssh | server_api::RepositorySourceKind::Https => self
.remote_uris
.iter()
.any(|uri| normalize_git_uri(uri) == normalize_git_uri(&source.uri)),
workspace_api::RepositorySourceKind::Invalid => false,
server_api::RepositorySourceKind::Invalid => false,
}
}
}
@@ -306,8 +305,8 @@ mod tests {
use super::*;
use crate::{ClientDefaultConnection, read_client_config_from_global_path};
fn workspace_summary(id: &str, name: &str) -> workspace_api::WorkspaceSummary {
workspace_api::WorkspaceSummary {
fn workspace_summary(id: &str, name: &str) -> server_api::WorkspaceSummary {
server_api::WorkspaceSummary {
workspace_id: id.to_string(),
owner_account_id: "owner-account".to_string(),
display_name: name.to_string(),
@@ -317,17 +316,15 @@ mod tests {
}
}
fn repository_summary(
source: workspace_api::RepositorySource,
) -> workspace_api::RepositorySummary {
workspace_api::RepositorySummary {
fn repository_summary(source: server_api::RepositorySource) -> server_api::RepositorySummary {
server_api::RepositorySummary {
repository_key: "main".to_string(),
kind: "git".to_string(),
provider: "builtin:git".to_string(),
source,
source_revision: 1,
source_fingerprint: "fingerprint".to_string(),
observed_status: workspace_api::RepositoryObservedStatus::Unverified,
observed_status: server_api::RepositoryObservedStatus::Unverified,
observed_at: None,
default_selector: Some("develop".to_string()),
record_authority: "server_db".to_string(),
@@ -345,8 +342,8 @@ mod tests {
.status()
.unwrap();
let identity = discover_open_repository(repository.path()).unwrap();
let source = workspace_api::RepositorySource {
kind: workspace_api::RepositorySourceKind::LocalPath,
let source = server_api::RepositorySource {
kind: server_api::RepositorySourceKind::LocalPath,
uri: identity.root.display().to_string(),
};
let matching_repository = repository_summary(source);