feat: migrate repository and workdir domains to ServerApi

This commit is contained in:
2026-09-23 06:51:05 +09:00
parent 6d65d50ec1
commit 7a975765ac
22 changed files with 6711 additions and 261 deletions
@@ -1,10 +1,12 @@
// @generated by yoi-repository-openapi-typescript@1. Do not edit.
// Input: openapi/server-api.json
// Input contract: 0.1.0 (sha256:0026ff3d0f1d267e4de3f154a14f4ef3f7554b603a376820f0775e5deb16a083)
// Input contract: 0.1.0 (sha256:e3f776a17079ce202725bb97de607426f4bfad9afe390ba7bbf76186e871be59)
// Options: repository-operation-schema-closure,openapi-3.1,format:uint64=safe-number,strict-safe-integers,sorted-output
// Output: web/workspace/src/lib/generated/repository-api.ts
// Regenerate/check: cargo run -q -p server-api --example generate_repository_openapi_types -- --check
export type ConfirmRepositorySshHostTrustRequest = { expected_host_trust_revision?: number | null; host_key: string; operation_id: string; runtime_id: string; };
export type CreateWorkspaceRepositoryRequest = { default_ref?: string | null; repository_key: string; source: string; };
export type CreateWorkspaceRepositoryResponse = { replayed: boolean; repository_key: string; workspace_id: string; };
@@ -13,10 +15,18 @@ export type Diagnostic = { code: string; message: string; severity: DiagnosticSe
export type DiagnosticSeverity = "info" | "warning" | "error";
export type GitCommitSummary = { author_date: string; author_email: string; author_name: string; hash: string; parents: Array<string>; refs: Array<string>; short_hash: string; summary: string; };
export type GitRemoteSummary = { fetch_url: string; name: string; };
export type GitRepositorySummary = { branch?: string | null; dirty: boolean; head?: string | null; remotes: Array<GitRemoteSummary>; status: string; };
export type HostListResponse = { diagnostics: Array<Diagnostic>; items: Array<HostSummary>; limit: number; source: string; workspace_id: string; };
export type HostSummary = { arch: string; diagnostics: Array<Diagnostic>; host_id: string; kind: string; label: string; last_seen_at?: string | null; observed_at: string; os: string; runtime_id: string; status: string; };
export type HostWorkerListResponse = { diagnostics: Array<Diagnostic>; items: Array<WorkerSummary>; limit: number; source: string; workspace_id: string; };
export type RepositoryApiError = { diagnostics?: Array<Diagnostic>; error: string; message: string; };
export type RepositoryDetailResponse = { item: RepositorySummary; source: string; workspace_id: string; };
@@ -25,10 +35,44 @@ export type RepositoryDiagnostic = { code: string; message: string; severity: st
export type RepositoryListResponse = { diagnostics: Array<Diagnostic>; items: Array<RepositorySummary>; source: string; workspace_id: string; };
export type RepositoryLogResponse = { default_selector?: string | null; diagnostics: Array<Diagnostic>; items: Array<GitCommitSummary>; limit: number; repository_key: string; workspace_id: string; };
export type RepositoryObservedStatus = "unverified" | "ready" | "invalid";
export type RepositorySource = { kind: RepositorySourceKind; uri: string; };
export type RepositorySourceKind = "local_path" | "file" | "ssh" | "https" | "invalid";
export type RepositorySshConnectionProbeRequest = { runtime_id: string; };
export type RepositorySshConnectionProbeResponse = { candidates: Array<RepositorySshHostKeyCandidate>; expected_host_trust_revision?: number | null; host_trust_id: string; hostname: string; port: number; repository_key: string; runtime_id: string; trust_state: RepositorySshConnectionTrustState; workspace_id: string; };
export type RepositorySshConnectionTrustState = "untrusted" | "verified" | "changed";
export type RepositorySshHostKeyCandidate = { algorithm: string; fingerprint: string; host_key: string; };
export type RepositorySshHostTrust = { created_at: string; current_revision: number; fingerprint: string; host_key: string; host_trust_id: string; hostname: string; key_algorithm: string; port: number; referenced_repositories?: Array<string>; updated_at: string; workspace_id: string; };
export type RepositorySummary = { default_selector?: string | null; diagnostics?: Array<RepositoryDiagnostic> | null; git?: GitRepositorySummary | null; kind: string; observed_at?: string | null; observed_status: RepositoryObservedStatus; provider: string; record_authority: string; repository_key: string; source: RepositorySource; source_fingerprint: string; source_revision: number; };
export type WorkerCapabilitySummary = { can_spawn_followup: boolean; can_stop: boolean; };
export type WorkerImplementationSummary = { display_hint: string; kind: string; };
export type WorkerSummary = { capabilities: WorkerCapabilitySummary; diagnostics?: Array<Diagnostic>; display_name?: string; host_id: string; implementation: WorkerImplementationSummary; label: string; last_seen_at?: string | null; pinned?: boolean; profile?: string | null; resource_key: string; retention_state?: string; runtime_id: string; singleton_key?: string | null; state: string; tags?: Array<string>; workdir_attachments?: Array<WorkerWorkdirAttachmentSummary>; worker_id: string; worker_state?: unknown; workspace: WorkerWorkspaceSummary; };
export type WorkerWorkdirAttachmentSummary = { alias: string; working_directory: WorkingDirectorySummary; };
export type WorkerWorkspaceSummary = { identity: string; visibility: string; workspace_id?: string | null; };
export type WorkingDirectoryCleanupTarget = { kind: string; repository_key: string; working_directory_id: string; };
export type WorkingDirectoryMaterializerKind = "runtime_git_clone" | "client_hosted_external";
export type WorkingDirectoryOccupancy = { display_name: string; linked_at: string; runtime_id: string; worker_id: string; };
export type WorkingDirectorySource = { kind: "repository"; repository_key: string; } | { grant_id: string; kind: "external_grant"; };
export type WorkingDirectoryStatusKind = "active" | "cleanup_pending" | "corrupted" | "not_found" | "unknown";
export type WorkingDirectorySummary = { cleanliness?: string | null; cleanup_target?: WorkingDirectoryCleanupTarget | null; creation_ref?: string | null; creation_selector?: string | null; creation_tree?: string | null; current_ref?: string | null; current_selector?: string | null; current_tree?: string | null; display_name?: string | null; materializer_kind: WorkingDirectoryMaterializerKind; observed_at_epoch_seconds?: number | null; occupied_by?: WorkingDirectoryOccupancy | null; source: WorkingDirectorySource; status: WorkingDirectoryStatusKind; working_directory_id: string; };
+100 -24
View File
@@ -1,34 +1,110 @@
// Generated from server-api. Do not edit by hand.
// Regenerate: cargo run -q -p server-api --features typescript --example generate_workdir_api_types > web/workspace/src/lib/generated/workdir-api.ts
// @generated by yoi-workdir-openapi-typescript@1. Do not edit.
// Input: openapi/server-api.json
// Input contract: 0.1.0 (sha256:e3f776a17079ce202725bb97de607426f4bfad9afe390ba7bbf76186e871be59)
// Options: workdir-operation-schema-closure,openapi-3.1,strict-integer-ranges,sorted-output
// Output: web/workspace/src/lib/generated/workdir-api.ts
// Regenerate/check: cargo run -q -p server-api --example generate_workdir_api_types -- --check
export type CommandOutput = { content: string; exit_code?: number | null; next_cursor?: number | null; output_path?: string | null; status: CommandStatus; timed_out: boolean; truncated: boolean; };
export type CommandOutputRequest = { cursor: number; handle: string; limit: number; wait: boolean; };
export type CommandRequest = { command: string; cwd?: FsPath | null; output_limit: number; spill_dir?: string | null; timeout_secs: number; tool_call_id?: string | null; };
export type CommandStatus = "running" | "completed" | "failed" | "timed_out" | "cancelled";
export type CurrentWorkerWorkdirAttachRequest = { alias: string; working_directory_id: string; };
export type CurrentWorkerWorkdirAttachmentResponse = { alias: string; attached: boolean; capabilities: WorkdirSessionCapabilities; working_directory_id: string; workspace_id: string; };
export type CurrentWorkerWorkdirOperationRequest = { operation: WorkdirSessionOperation; target_workdir: string; };
export type Diagnostic = { code: string; message: string; severity: DiagnosticSeverity; };
export type DiagnosticSeverity = "info" | "warning" | "error";
export type Diagnostic = { code: string, severity: DiagnosticSeverity, message: string, };
export type EditRequest = { expected_hash: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]; new_string: string; old_string: string; path: FsPath; replace_all: boolean; };
export type EditResult = { bytes_written: number; content_hash: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]; replacements: number; };
export type EntryKind = "file" | "directory" | "symlink" | "other";
export type ExternalWorkdirGrantCreateRequest = { display_name: string; provider_instance_id: string; read_only: boolean; ttl_seconds: number; };
export type ExternalWorkdirGrantResponse = { display_name: string; expires_at: string; generation: number; grant_id: string; permissions: string; provider_instance_id: string; status: string; working_directory_id: string; workspace_id: string; };
export type FsPath = string;
export type GlobRequest = { limit: number; path: FsPath; pattern: string; };
export type GlobResult = { paths: Array<FsPath>; truncated: boolean; };
export type GrepOutputMode = "content" | "files_with_matches" | "count";
export type GrepRequest = { after_context: number; before_context: number; case_insensitive: boolean; file_type?: string | null; glob?: string | null; limit: number; multiline: boolean; offset: number; output_mode: GrepOutputMode; path: FsPath; pattern: string; };
export type GrepResult = { match_count: number; matched_files: number; output: string; truncated: boolean; };
export type ListEntry = { kind: EntryKind; path: FsPath; size: number; };
export type ListRequest = { limit: number; path: FsPath; };
export type ListResult = { entries: Array<ListEntry>; total_bytes: number; total_entries: number; truncated: boolean; };
export type ReadRequest = { limit: number; max_bytes: number; offset: number; path: FsPath; };
export type ReadResult = { bytes: Array<number>; content_hash: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]; path: FsPath; start_line: number; total_lines: number; truncated: boolean; };
export type RepositoryApiError = { diagnostics?: Array<Diagnostic>; error: string; message: string; };
export type StatRequest = { path: FsPath; };
export type StatResult = { kind: EntryKind; path: FsPath; size: number; };
export type WorkdirOperationApiError = { code?: WorkdirTransportErrorCode | null; diagnostics?: Array<Diagnostic> | null; error?: string | null; message: string; };
export type WorkdirScopeAuthorizationRequest = { path: FsPath; permission: WorkdirToolScopePermission; rules: Array<WorkdirToolScopeRule>; };
export type WorkdirScopeOverlapRequest = { left: WorkdirToolScopeRule; right: WorkdirToolScopeRule; };
export type WorkdirSessionCapabilities = { bits: number; };
export type WorkdirSessionOperation = { operation: "authorize_scope"; request: WorkdirScopeAuthorizationRequest; } | { operation: "scope_rules_overlap"; request: WorkdirScopeOverlapRequest; } | { operation: "stat"; request: StatRequest; } | { operation: "read"; request: ReadRequest; } | { operation: "write"; request: WriteRequest; } | { operation: "edit"; request: EditRequest; } | { operation: "list"; request: ListRequest; } | { operation: "glob"; request: GlobRequest; } | { operation: "grep"; request: GrepRequest; } | { operation: "command_start"; request: CommandRequest; } | { operation: "command_status"; request: string; } | { operation: "command_output"; request: CommandOutputRequest; } | { operation: "command_cancel"; request: string; };
export type WorkdirSessionOperationResult = { operation: "authorize_scope"; } | { operation: "scope_rules_overlap"; result: { overlaps: boolean; }; } | { operation: "stat"; result: StatResult; } | { operation: "read"; result: ReadResult; } | { operation: "write"; result: WriteResult; } | { operation: "edit"; result: EditResult; } | { operation: "list"; result: ListResult; } | { operation: "glob"; result: GlobResult; } | { operation: "grep"; result: GrepResult; } | { operation: "command_start"; result: string; } | { operation: "command_status"; result: CommandStatus; } | { operation: "command_output"; result: CommandOutput; } | { operation: "command_cancel"; };
export type WorkdirToolScopePermission = "read" | "write";
export type WorkdirToolScopeRule = { permission: WorkdirToolScopePermission; recursive: boolean; symlink_policy?: string; target: FsPath; };
export type WorkdirTransportErrorCode = "not_found" | "conflict" | "unsupported" | "invalid_request" | "denied" | "out_of_scope" | "symlink_out_of_scope" | "broken_symlink" | "symlink_target_is_directory" | "read_only" | "is_directory" | "symlink_directory_not_traversed" | "unknown_command" | "unavailable" | "io" | "transport" | "internal";
export type WorkingDirectoryCleanupTarget = { kind: string; repository_key: string; working_directory_id: string; };
export type WorkingDirectoryCreateRequest = { display_name?: string | null; operation_id?: string | null; repository_key: string; runtime_id?: string | null; selector?: string | null; };
export type WorkingDirectoryCreateResponse = { diagnostics: Array<Diagnostic>; item: WorkingDirectorySummary; runtime_id: string; workspace_id: string; };
export type WorkingDirectoryDetailResponse = { diagnostics: Array<Diagnostic>; item: WorkingDirectorySummary; runtime_id?: string | null; workspace_id: string; };
export type WorkingDirectoryListResponse = { diagnostics: Array<Diagnostic>; items: Array<WorkingDirectorySummary>; workspace_id: string; };
export type WorkingDirectoryMaterializerKind = "runtime_git_clone" | "client_hosted_external";
export type WorkingDirectoryOccupancy = { display_name: string; linked_at: string; runtime_id: string; worker_id: string; };
export type WorkingDirectoryRemovalDisposition = "removed" | "retained" | "attention_required";
export type WorkingDirectoryRemovalRequest = { reason: string; };
export type WorkingDirectoryRemovalResponse = { disposition: WorkingDirectoryRemovalDisposition; failure_category?: string | null; retryable: boolean; working_directory_id: string; };
export type WorkingDirectorySource = { kind: "repository"; repository_key: string; } | { grant_id: string; kind: "external_grant"; };
export type WorkingDirectoryStatusKind = "active" | "cleanup_pending" | "corrupted" | "not_found" | "unknown";
export type WorkingDirectoryCleanupTarget = { kind: string, working_directory_id: string, repository_key: string, };
export type WorkingDirectorySummary = { cleanliness?: string | null; cleanup_target?: WorkingDirectoryCleanupTarget | null; creation_ref?: string | null; creation_selector?: string | null; creation_tree?: string | null; current_ref?: string | null; current_selector?: string | null; current_tree?: string | null; display_name?: string | null; materializer_kind: WorkingDirectoryMaterializerKind; observed_at_epoch_seconds?: number | null; occupied_by?: WorkingDirectoryOccupancy | null; source: WorkingDirectorySource; status: WorkingDirectoryStatusKind; working_directory_id: string; };
export type WorkingDirectoryOccupancy = { runtime_id: string, worker_id: string, display_name: string, linked_at: string, };
export type WriteRequest = { content: Array<number>; expected_hash?: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number] | null; path: FsPath; };
export type WorkingDirectorySource = { "kind": "repository", repository_key: string, } | { "kind": "external_grant", grant_id: string, };
export type WorkingDirectorySummary = { working_directory_id: string,
/**
* Optional human-facing label, never a routing key.
*/
display_name?: string | null, source: WorkingDirectorySource, creation_selector?: string | null, creation_ref?: string | null, creation_tree?: string | null, current_selector?: string | null, current_ref?: string | null, current_tree?: string | null, observed_at_epoch_seconds?: number | null, materializer_kind: WorkingDirectoryMaterializerKind, cleanup_target?: WorkingDirectoryCleanupTarget | null, status: WorkingDirectoryStatusKind, cleanliness?: string | null, occupied_by?: WorkingDirectoryOccupancy | null, };
export type WorkingDirectoryCreateRequest = { runtime_id?: string | null,
/**
* Optional human-facing label, independent of every Worker attachment alias.
*/
display_name?: string | null, repository_key: string, selector?: string | null, operation_id?: string | null, };
export type WorkingDirectoryListResponse = { workspace_id: string, items: Array<WorkingDirectorySummary>, diagnostics: Array<Diagnostic>, };
export type WorkingDirectoryDetailResponse = { workspace_id: string, runtime_id?: string | null, item: WorkingDirectorySummary, diagnostics: Array<Diagnostic>, };
export type WorkingDirectoryCreateResponse = { workspace_id: string, runtime_id: string, item: WorkingDirectorySummary, diagnostics: Array<Diagnostic>, };
export type WriteResult = { bytes_written: number; created: boolean; };
@@ -1,10 +1,5 @@
import type { ApiResult } from "$lib/workspace/api/http";
import type {
GitCommitSummary,
RepositoryLogResponse,
RepositorySshConnectionProbeResponse,
RepositorySshConnectionTrustState,
RepositorySshHostKeyCandidate,
WorkspaceAuthConfig,
WorkspaceCatalogListResponse,
WorkspaceCreateResponse,
@@ -24,22 +19,25 @@ import type {
import type {
CreateWorkspaceRepositoryResponse,
Diagnostic,
GitCommitSummary,
GitRemoteSummary,
GitRepositorySummary,
HostListResponse,
HostSummary,
RepositoryApiError,
RepositoryDetailResponse,
RepositoryDiagnostic,
RepositoryListResponse,
RepositoryLogResponse,
RepositorySource,
RepositorySourceKind,
RepositorySshConnectionProbeResponse,
RepositorySshConnectionTrustState,
RepositorySshHostKeyCandidate,
RepositorySummary,
} from "$lib/generated/repository-api.ts";
export type {
GitCommitSummary,
RepositoryLogResponse,
RepositorySshConnectionProbeResponse,
RepositorySshHostKeyCandidate,
WorkspaceCatalogListResponse,
WorkspaceCreateResponse,
WorkspaceDeletionOperationResponse,
@@ -51,13 +49,19 @@ export type {
export type {
CreateWorkspaceRepositoryRequest,
CreateWorkspaceRepositoryResponse,
GitCommitSummary,
GitRemoteSummary,
GitRepositorySummary,
HostListResponse,
HostSummary,
RepositoryApiError,
RepositoryDetailResponse,
RepositoryListResponse,
RepositoryLogResponse,
RepositorySource,
RepositorySourceKind,
RepositorySshConnectionProbeResponse,
RepositorySshHostKeyCandidate,
RepositorySummary,
} from "$lib/generated/repository-api.ts";
@@ -1094,6 +1098,77 @@ export function parseWorkspaceDeletionOperationResponse(
};
}
export function parseHostListResponse(value: unknown): HostListResponse {
const response = object(value, "host list response");
exactKeys(
response,
["workspace_id", "limit", "items", "source", "diagnostics"],
"host list response",
);
const limit = repositorySourceRevision(
response.limit,
"host list response.limit",
);
return {
workspace_id: repositoryString(
response.workspace_id,
"host list response.workspace_id",
),
limit,
items: repositoryArray(response.items, "host list response.items").map(
(item, index) => parseHostSummary(item, `host list response.items[${index}]`),
),
source: repositoryString(response.source, "host list response.source"),
diagnostics: repositoryArray(
response.diagnostics,
"host list response.diagnostics",
).map((item, index) =>
repositoryApiDiagnostic(
item,
`host list response.diagnostics[${index}]`,
)
),
};
}
function parseHostSummary(value: unknown, path: string): HostSummary {
const host = object(value, path);
exactKeys(
host,
[
"runtime_id",
"host_id",
"label",
"kind",
"status",
"observed_at",
"last_seen_at",
"os",
"arch",
"diagnostics",
],
path,
);
return {
runtime_id: repositoryString(host.runtime_id, `${path}.runtime_id`),
host_id: repositoryString(host.host_id, `${path}.host_id`),
label: repositoryString(host.label, `${path}.label`),
kind: repositoryString(host.kind, `${path}.kind`),
status: repositoryString(host.status, `${path}.status`),
observed_at: repositoryString(host.observed_at, `${path}.observed_at`),
last_seen_at: optionalNullableRepositoryString(
host.last_seen_at,
`${path}.last_seen_at`,
),
os: repositoryString(host.os, `${path}.os`),
arch: repositoryString(host.arch, `${path}.arch`),
diagnostics: repositoryArray(host.diagnostics, `${path}.diagnostics`).map(
(item, index) =>
repositoryApiDiagnostic(item, `${path}.diagnostics[${index}]`),
),
};
}
export function parseRepositoryLogResponse(
value: unknown,
): RepositoryLogResponse {
@@ -71,19 +71,6 @@ export type Runtime = {
};
};
export type Host = {
runtime_id: string;
host_id: string;
label: string;
kind: string;
status: string;
observed_at: string;
last_seen_at: string | null;
os: string;
arch: string;
diagnostics: Diagnostic[];
};
export type WorkerCapabilities = {
can_stop: boolean;
can_spawn_followup: boolean;
@@ -1,10 +1,24 @@
import { loadJson, workspaceApiPath } from "$lib/workspace/api/http";
import type { Host, ListResponse } from "$lib/workspace/sidebar/types";
import {
parseHostListResponse,
type HostListResponse,
} from "$lib/workspace/api/workspace-model";
import type { PageLoad } from "./$types";
const HOST_API_LOAD_POLICY = {
diagnosticLabel: "Host API",
maxResponseBytes: 4 * 1024 * 1024,
} as const;
export const load: PageLoad = async ({ fetch, params }) => {
const apiPath = (path: string) => workspaceApiPath(params.workspaceId, path);
const hosts = await loadJson<ListResponse<Host>>(fetch, apiPath("/hosts"));
const hosts = await loadJson<HostListResponse>(
fetch,
apiPath("/hosts"),
undefined,
parseHostListResponse,
HOST_API_LOAD_POLICY,
);
return {
workspaceId: params.workspaceId,
@@ -3,7 +3,7 @@
ConfirmRepositorySshHostTrustRequest,
RepositorySshConnectionProbeRequest,
RepositorySshConnectionProbeResponse
} from '$lib/generated/legacy-server-api';
} from '$lib/generated/repository-api';
import { parseRepositorySshHostTrust } from '$lib/workspace/api/repository-access';
import { formatDate, workspaceApiPath } from '$lib/workspace/api/http';
import { parseRepositorySshConnectionProbeResponse } from '$lib/workspace/api/workspace-model';