Allow agent creation outside git repos
This commit is contained in:
@@ -1524,6 +1524,9 @@ function AgentFlowModal({
|
|||||||
? daemonAvailabilityError ??
|
? daemonAvailabilityError ??
|
||||||
"Repository details will load automatically once the selected host is back online."
|
"Repository details will load automatically once the selected host is back online."
|
||||||
: null;
|
: null;
|
||||||
|
const isNonGitDirectory =
|
||||||
|
repoRequestStatus === "error" &&
|
||||||
|
/not in a git repository/i.test(repoRequestError?.message ?? "");
|
||||||
const repoInfoStatus: "idle" | "loading" | "ready" | "error" = !shouldInspectRepo
|
const repoInfoStatus: "idle" | "loading" | "ready" | "error" = !shouldInspectRepo
|
||||||
? "idle"
|
? "idle"
|
||||||
: repoAvailabilityError
|
: repoAvailabilityError
|
||||||
@@ -1531,11 +1534,16 @@ function AgentFlowModal({
|
|||||||
: repoRequestStatus === "loading"
|
: repoRequestStatus === "loading"
|
||||||
? "loading"
|
? "loading"
|
||||||
: repoRequestStatus === "error"
|
: repoRequestStatus === "error"
|
||||||
? "error"
|
? isNonGitDirectory
|
||||||
|
? "idle"
|
||||||
|
: "error"
|
||||||
: repoRequestStatus === "success"
|
: repoRequestStatus === "success"
|
||||||
? "ready"
|
? "ready"
|
||||||
: "idle";
|
: "idle";
|
||||||
const repoInfoError = repoAvailabilityError ?? repoRequestError?.message ?? null;
|
const repoInfoError = repoAvailabilityError ?? (isNonGitDirectory ? null : repoRequestError?.message ?? null);
|
||||||
|
const gitHelperText = isNonGitDirectory
|
||||||
|
? "No git repository detected. Git options are disabled for this directory."
|
||||||
|
: null;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!shouldInspectRepo) {
|
if (!shouldInspectRepo) {
|
||||||
@@ -1575,6 +1583,35 @@ function AgentFlowModal({
|
|||||||
});
|
});
|
||||||
}, [repoInfo]);
|
}, [repoInfo]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isNonGitDirectory) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
createNewBranch ||
|
||||||
|
createWorktree ||
|
||||||
|
baseBranch.trim().length > 0 ||
|
||||||
|
branchName.trim().length > 0 ||
|
||||||
|
worktreeSlug.trim().length > 0
|
||||||
|
) {
|
||||||
|
setCreateNewBranch(false);
|
||||||
|
setCreateWorktree(false);
|
||||||
|
setBaseBranch("");
|
||||||
|
setBranchName("");
|
||||||
|
setWorktreeSlug("");
|
||||||
|
setBranchNameEdited(false);
|
||||||
|
setWorktreeSlugEdited(false);
|
||||||
|
shouldSyncBaseBranchRef.current = true;
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
baseBranch,
|
||||||
|
branchName,
|
||||||
|
createNewBranch,
|
||||||
|
createWorktree,
|
||||||
|
isNonGitDirectory,
|
||||||
|
worktreeSlug,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleCreate = useCallback(async () => {
|
const handleCreate = useCallback(async () => {
|
||||||
const trimmedPath = workingDir.trim();
|
const trimmedPath = workingDir.trim();
|
||||||
if (!trimmedPath) {
|
if (!trimmedPath) {
|
||||||
@@ -1638,7 +1675,7 @@ function AgentFlowModal({
|
|||||||
createWorktree ||
|
createWorktree ||
|
||||||
(trimmedBaseBranch.length > 0 && trimmedBaseBranch !== currentBranch);
|
(trimmedBaseBranch.length > 0 && trimmedBaseBranch !== currentBranch);
|
||||||
|
|
||||||
const gitOptions = shouldIncludeBase
|
const gitOptions = shouldIncludeBase && !isNonGitDirectory
|
||||||
? {
|
? {
|
||||||
...(trimmedBaseBranch ? { baseBranch: trimmedBaseBranch } : {}),
|
...(trimmedBaseBranch ? { baseBranch: trimmedBaseBranch } : {}),
|
||||||
...(createNewBranch
|
...(createNewBranch
|
||||||
@@ -1904,6 +1941,9 @@ function AgentFlowModal({
|
|||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
const gitBlockingError = useMemo(() => {
|
const gitBlockingError = useMemo(() => {
|
||||||
|
if (isNonGitDirectory) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const trimmedBase = baseBranch.trim();
|
const trimmedBase = baseBranch.trim();
|
||||||
const currentBranch = repoInfo?.currentBranch ?? "";
|
const currentBranch = repoInfo?.currentBranch ?? "";
|
||||||
const isCustomBase =
|
const isCustomBase =
|
||||||
@@ -1950,6 +1990,7 @@ function AgentFlowModal({
|
|||||||
branchName,
|
branchName,
|
||||||
createNewBranch,
|
createNewBranch,
|
||||||
createWorktree,
|
createWorktree,
|
||||||
|
isNonGitDirectory,
|
||||||
repoInfo,
|
repoInfo,
|
||||||
validateWorktreeName,
|
validateWorktreeName,
|
||||||
worktreeSlug,
|
worktreeSlug,
|
||||||
@@ -2189,6 +2230,8 @@ function AgentFlowModal({
|
|||||||
branches={repoInfo?.branches ?? []}
|
branches={repoInfo?.branches ?? []}
|
||||||
status={repoInfoStatus}
|
status={repoInfoStatus}
|
||||||
repoError={repoInfoError}
|
repoError={repoInfoError}
|
||||||
|
helperText={gitHelperText}
|
||||||
|
isGitDisabled={Boolean(gitHelperText)}
|
||||||
warning={
|
warning={
|
||||||
!createWorktree && repoInfo?.isDirty
|
!createWorktree && repoInfo?.isDirty
|
||||||
? "Working directory has uncommitted changes"
|
? "Working directory has uncommitted changes"
|
||||||
@@ -3075,6 +3118,7 @@ interface GitOptionsSectionProps {
|
|||||||
branches: Array<{ name: string; isCurrent: boolean }>;
|
branches: Array<{ name: string; isCurrent: boolean }>;
|
||||||
status: "idle" | "loading" | "ready" | "error";
|
status: "idle" | "loading" | "ready" | "error";
|
||||||
repoError: string | null;
|
repoError: string | null;
|
||||||
|
helperText?: string | null;
|
||||||
warning: string | null;
|
warning: string | null;
|
||||||
createNewBranch: boolean;
|
createNewBranch: boolean;
|
||||||
onToggleCreateNewBranch: (value: boolean) => void;
|
onToggleCreateNewBranch: (value: boolean) => void;
|
||||||
@@ -3085,6 +3129,7 @@ interface GitOptionsSectionProps {
|
|||||||
worktreeSlug: string;
|
worktreeSlug: string;
|
||||||
onWorktreeSlugChange: (value: string) => void;
|
onWorktreeSlugChange: (value: string) => void;
|
||||||
gitValidationError: string | null;
|
gitValidationError: string | null;
|
||||||
|
isGitDisabled?: boolean;
|
||||||
isBaseDropdownOpen: boolean;
|
isBaseDropdownOpen: boolean;
|
||||||
onToggleBaseDropdown: () => void;
|
onToggleBaseDropdown: () => void;
|
||||||
onCloseDropdown: () => void;
|
onCloseDropdown: () => void;
|
||||||
@@ -3096,6 +3141,7 @@ function GitOptionsSection({
|
|||||||
branches,
|
branches,
|
||||||
status,
|
status,
|
||||||
repoError,
|
repoError,
|
||||||
|
helperText,
|
||||||
warning,
|
warning,
|
||||||
createNewBranch,
|
createNewBranch,
|
||||||
onToggleCreateNewBranch,
|
onToggleCreateNewBranch,
|
||||||
@@ -3106,6 +3152,7 @@ function GitOptionsSection({
|
|||||||
worktreeSlug,
|
worktreeSlug,
|
||||||
onWorktreeSlugChange,
|
onWorktreeSlugChange,
|
||||||
gitValidationError,
|
gitValidationError,
|
||||||
|
isGitDisabled,
|
||||||
isBaseDropdownOpen,
|
isBaseDropdownOpen,
|
||||||
onToggleBaseDropdown,
|
onToggleBaseDropdown,
|
||||||
onCloseDropdown,
|
onCloseDropdown,
|
||||||
@@ -3122,6 +3169,7 @@ function GitOptionsSection({
|
|||||||
const currentBranchLabel =
|
const currentBranchLabel =
|
||||||
branches.find((branch) => branch.isCurrent)?.name ?? "";
|
branches.find((branch) => branch.isCurrent)?.name ?? "";
|
||||||
const baseInputRef = useRef<TextInput | null>(null);
|
const baseInputRef = useRef<TextInput | null>(null);
|
||||||
|
const gitInputsDisabled = Boolean(isGitDisabled) || status === "loading";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isBaseDropdownOpen) {
|
if (isBaseDropdownOpen) {
|
||||||
@@ -3143,13 +3191,14 @@ function GitOptionsSection({
|
|||||||
value={baseBranch}
|
value={baseBranch}
|
||||||
placeholder={currentBranchLabel || "main"}
|
placeholder={currentBranchLabel || "main"}
|
||||||
onPress={onToggleBaseDropdown}
|
onPress={onToggleBaseDropdown}
|
||||||
disabled={status === "loading"}
|
disabled={gitInputsDisabled}
|
||||||
errorMessage={repoError}
|
errorMessage={repoError}
|
||||||
warningMessage={!gitValidationError ? warning : null}
|
warningMessage={!gitValidationError && !isGitDisabled ? warning : null}
|
||||||
helperText={
|
helperText={
|
||||||
status === "loading"
|
helperText ??
|
||||||
|
(status === "loading"
|
||||||
? "Inspecting repository…"
|
? "Inspecting repository…"
|
||||||
: "Search existing branches, then tap to select."
|
: "Search existing branches, then tap to select.")
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<DropdownSheet
|
<DropdownSheet
|
||||||
@@ -3215,6 +3264,7 @@ function GitOptionsSection({
|
|||||||
description="Create a feature branch before launching the agent"
|
description="Create a feature branch before launching the agent"
|
||||||
value={createNewBranch}
|
value={createNewBranch}
|
||||||
onToggle={onToggleCreateNewBranch}
|
onToggle={onToggleCreateNewBranch}
|
||||||
|
disabled={isGitDisabled}
|
||||||
/>
|
/>
|
||||||
{createNewBranch ? (
|
{createNewBranch ? (
|
||||||
<TextInput
|
<TextInput
|
||||||
@@ -3233,6 +3283,7 @@ function GitOptionsSection({
|
|||||||
description="Use an isolated directory so your current branch stays untouched"
|
description="Use an isolated directory so your current branch stays untouched"
|
||||||
value={createWorktree}
|
value={createWorktree}
|
||||||
onToggle={onToggleCreateWorktree}
|
onToggle={onToggleCreateWorktree}
|
||||||
|
disabled={isGitDisabled}
|
||||||
/>
|
/>
|
||||||
{createWorktree ? (
|
{createWorktree ? (
|
||||||
<TextInput
|
<TextInput
|
||||||
|
|||||||
Reference in New Issue
Block a user