feat: implement config profile git mounts
- Add git_mounts column to config_profiles table (JSONB) - Create GitMount Pydantic models with validation - Add repo validation in create/update endpoints - Update profile resolver to merge git mounts from includes - Implement auto-clone, branch checkout, and glob expansion - Add parallel processing for git mount resolution - Create GitMountEditor frontend component - Update TypeScript types and API clients - Add CSS styles for git mount UI - Frontend type check and build pass Implements tasks 1.1-7.9 of config-profile-git-mounts spec
This commit is contained in:
@@ -19,8 +19,10 @@ import {
|
||||
type ResolvedProfile,
|
||||
} from "../api/config_profiles";
|
||||
import { listProjects } from "../api/projects";
|
||||
import { listRepositories, type GitRepository } from "../api/git_repositories";
|
||||
import type { Project } from "../types";
|
||||
import { listToolTypes, type ToolType } from "../api/tool_types";
|
||||
import { GitMountEditor } from "../components/git-mount-editor";
|
||||
|
||||
type Status = "loading" | "ready" | "error";
|
||||
type MobileView = "list" | "detail" | "edit";
|
||||
@@ -32,6 +34,7 @@ export const ConfigProfilesPage = () => {
|
||||
const [profiles, setProfiles] = useState<ConfigProfile[]>([]);
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const [toolTypes, setToolTypes] = useState<ToolType[]>([]);
|
||||
const [repositories, setRepositories] = useState<GitRepository[]>([]);
|
||||
|
||||
const [selectedProfileId, setSelectedProfileId] = useState<string | null>(null);
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
@@ -47,6 +50,7 @@ export const ConfigProfilesPage = () => {
|
||||
env_vars: {},
|
||||
runtime_hints: {},
|
||||
mounts: [],
|
||||
git_mounts: [],
|
||||
files: {},
|
||||
is_default: false,
|
||||
});
|
||||
@@ -67,6 +71,19 @@ export const ConfigProfilesPage = () => {
|
||||
setProfiles(profs || []);
|
||||
setProjects(projs || []);
|
||||
setToolTypes(types || []);
|
||||
|
||||
// Load repositories from all projects
|
||||
const allRepos: GitRepository[] = [];
|
||||
for (const project of projs || []) {
|
||||
try {
|
||||
const repos = await listRepositories(project.id);
|
||||
allRepos.push(...repos);
|
||||
} catch {
|
||||
// Skip projects we can't access
|
||||
}
|
||||
}
|
||||
setRepositories(allRepos);
|
||||
|
||||
setStatus("ready");
|
||||
} catch {
|
||||
setStatus("error");
|
||||
@@ -84,6 +101,7 @@ export const ConfigProfilesPage = () => {
|
||||
env_vars: {},
|
||||
runtime_hints: {},
|
||||
mounts: [],
|
||||
git_mounts: [],
|
||||
files: {},
|
||||
is_default: false,
|
||||
});
|
||||
@@ -102,6 +120,7 @@ export const ConfigProfilesPage = () => {
|
||||
env_vars: profile.env_vars,
|
||||
runtime_hints: profile.runtime_hints,
|
||||
mounts: profile.mounts,
|
||||
git_mounts: profile.git_mounts || [],
|
||||
files: profile.files,
|
||||
is_default: profile.is_default,
|
||||
});
|
||||
@@ -1239,6 +1258,14 @@ export const ConfigProfilesPage = () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="form-section">
|
||||
<GitMountEditor
|
||||
mounts={formData.git_mounts || []}
|
||||
repositories={repositories}
|
||||
onChange={(git_mounts) => updateFormField("git_mounts", git_mounts)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="dialog-actions" style={{ marginTop: "1rem", position: "sticky", bottom: "1rem", background: "var(--surface)", padding: "1rem", borderRadius: "0.5rem", border: "1px solid var(--border)" }}>
|
||||
<button type="submit" disabled={saveStatus === "saving"}>
|
||||
<Icon name={isCreating ? "add" : "save"} size="sm" />
|
||||
|
||||
Reference in New Issue
Block a user