workspace: gate workdir assignment
This commit is contained in:
@@ -126,6 +126,7 @@ export type WorkingDirectorySummary = {
|
||||
resolved_tree?: string | null;
|
||||
status: string;
|
||||
cleanliness?: string | null;
|
||||
primary_worker_id?: number | null;
|
||||
management_kind?: "backend_managed" | "runtime_unmanaged" | string | null;
|
||||
cleanup_target: {
|
||||
kind: string;
|
||||
|
||||
@@ -53,6 +53,8 @@ const options: WorkerLaunchOptionsResponse = {
|
||||
materializer_kind: "local_git_worktree",
|
||||
resolved_commit: "0123456789abcdef",
|
||||
status: "active",
|
||||
cleanliness: "clean",
|
||||
primary_worker_id: null,
|
||||
cleanup_target: {
|
||||
kind: "git_worktree",
|
||||
working_directory_id: "wd-1-repo",
|
||||
|
||||
@@ -35,11 +35,16 @@ export function defaultWorkerLaunchForm(
|
||||
const preferredProfile =
|
||||
options?.profiles.find((candidate) => candidate.id === "builtin:coder") ??
|
||||
options?.profiles[0];
|
||||
const preferredWorkingDirectory =
|
||||
options?.working_directories.find((directory) =>
|
||||
directory.status === "active"
|
||||
) ??
|
||||
options?.working_directories[0];
|
||||
const availableWorkingDirectories = options?.working_directories.filter((directory) =>
|
||||
directory.status === "active" &&
|
||||
directory.cleanliness === "clean" &&
|
||||
directory.primary_worker_id == null
|
||||
) ?? [];
|
||||
const selectedRuntime = current.runtime_id
|
||||
? options?.runtimes.find((runtime) => runtime.runtime_id === current.runtime_id)
|
||||
: preferredRuntime;
|
||||
const workdirlessRuntime = selectedRuntime?.working_directory_required === false;
|
||||
const preferredWorkingDirectory = workdirlessRuntime ? undefined : availableWorkingDirectories[0];
|
||||
const preferredRepository =
|
||||
options?.repositories.find((repository) =>
|
||||
repository.id === current.working_directory_repository_id
|
||||
@@ -54,7 +59,7 @@ export function defaultWorkerLaunchForm(
|
||||
? current.profile
|
||||
: preferredProfile?.id || "",
|
||||
initial_text: current.initial_text,
|
||||
working_directory_id: options?.working_directories.some(
|
||||
working_directory_id: !workdirlessRuntime && availableWorkingDirectories.some(
|
||||
(directory) =>
|
||||
directory.working_directory_id === current.working_directory_id,
|
||||
)
|
||||
|
||||
@@ -43,7 +43,16 @@
|
||||
let isNewWorkingDirectorySelected = $derived(workingDirectoryId === NEW_WORKING_DIRECTORY_VALUE);
|
||||
let selectedRuntime = $derived(options?.runtimes.find((runtime) => runtime.runtime_id === runtimeId));
|
||||
let selectedRuntimeAllowsNoWorkdir = $derived(selectedRuntime?.working_directory_required === false);
|
||||
let hasSelectedExistingWorkdir = $derived(Boolean(workingDirectoryId && !isNewWorkingDirectorySelected));
|
||||
let hasSelectedExistingWorkdir = $derived(Boolean(
|
||||
workingDirectoryId && !isNewWorkingDirectorySelected && !selectedRuntimeAllowsNoWorkdir,
|
||||
));
|
||||
let availableWorkingDirectories = $derived(
|
||||
selectedRuntimeAllowsNoWorkdir
|
||||
? []
|
||||
: (options?.working_directories ?? []).filter((directory) =>
|
||||
directory.status === 'active' && directory.cleanliness === 'clean' && directory.primary_worker_id == null
|
||||
),
|
||||
);
|
||||
let canStartWorker = $derived(Boolean(
|
||||
runtimeId &&
|
||||
profile &&
|
||||
@@ -65,6 +74,13 @@
|
||||
return () => controller.abort();
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (selectedRuntimeAllowsNoWorkdir && workingDirectoryId) {
|
||||
workingDirectoryId = '';
|
||||
relativeCwd = '';
|
||||
}
|
||||
});
|
||||
|
||||
async function loadLaunchOptions(signal?: AbortSignal) {
|
||||
loading = true;
|
||||
optionsError = null;
|
||||
@@ -109,6 +125,10 @@
|
||||
submitError = { message: 'select a runtime before creating a workdir', diagnostics: [] };
|
||||
return;
|
||||
}
|
||||
if (selectedRuntimeAllowsNoWorkdir) {
|
||||
submitError = { message: 'embedded Runtime does not create workdirs', diagnostics: [] };
|
||||
return;
|
||||
}
|
||||
if (!workingDirectoryRepositoryId) {
|
||||
submitError = { message: 'select a repository before creating a workdir', diagnostics: [] };
|
||||
return;
|
||||
@@ -124,7 +144,6 @@
|
||||
runtime_id: runtimeId,
|
||||
repository_id: workingDirectoryRepositoryId,
|
||||
selector: workingDirectorySelector || null,
|
||||
policy: { dirty_state: 'clean_point_only', cleanup: 'manual_or_worker_stop' },
|
||||
}),
|
||||
},
|
||||
);
|
||||
@@ -245,16 +264,16 @@
|
||||
<span>Run at</span>
|
||||
<select class="worker-inline-select wd-select" bind:value={workingDirectoryId} aria-label="Workdir">
|
||||
{#if selectedRuntimeAllowsNoWorkdir}
|
||||
<option value="">No workdir · embedded conversation only</option>
|
||||
<option value="">No workdir</option>
|
||||
{:else}
|
||||
<option value="" disabled>Select workdir</option>
|
||||
{#each availableWorkingDirectories as directory}
|
||||
<option value={directory.working_directory_id}>
|
||||
{directory.repository_id} · {directory.requested_selector ?? 'HEAD'}
|
||||
</option>
|
||||
{/each}
|
||||
<option value={NEW_WORKING_DIRECTORY_VALUE}>New workdir…</option>
|
||||
{/if}
|
||||
{#each options?.working_directories ?? [] as directory}
|
||||
<option value={directory.working_directory_id} disabled={directory.status !== 'active'}>
|
||||
{directory.repository_id} · {directory.requested_selector ?? 'HEAD'}
|
||||
</option>
|
||||
{/each}
|
||||
<option value={NEW_WORKING_DIRECTORY_VALUE}>New workdir…</option>
|
||||
</select>
|
||||
<span>in</span>
|
||||
<select class="worker-inline-select runtime-select" bind:value={runtimeId} required aria-label="Runtime">
|
||||
|
||||
Reference in New Issue
Block a user