-
Notifications
You must be signed in to change notification settings - Fork 49
feat: add session-config repo support (spec.configRepo) #606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add session-config repo support (spec.configRepo) #606
Conversation
Sessions can now reference a Git repository containing Claude Code configuration (CLAUDE.md, .claude/ rules/skills/agents, .mcp.json) that is overlaid into the workspace at pod init time. The config repo is cloned once by hydrate.sh with retry logic and error reporting via /workspace/.config-repo-error. Workspace repo files take precedence over config repo files (cp -rn overlay). Template: https://github.com/ambient-code/session-config-reference Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Store a workspace-level default session-config repo in ProjectSettings CRD so users don't have to paste a config repo URL every time they create a session. - Replace orphaned spec.repositories with spec.defaultConfigRepo in CRD - Add GET/PUT /api/projects/:project/project-settings backend endpoints - Remove dead code: EnrichProjectSettingsWithProviders and its tests - Add config repo fields to Create Workspace, Settings, and Create Session dialogs (pre-fills from workspace defaults, overridable) - Add React Query hooks and API client for project settings - Add 10 unit tests (Ginkgo) and 4 e2e tests (Cypress) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude Code ReviewSummaryThis PR adds support for session-level configuration repositories ( Overall Assessment: High-quality implementation with strong adherence to project standards. Clean code removal, comprehensive test coverage, and proper security patterns throughout. Issues by Severity🚫 Blocker IssuesNone - No blocking issues found. 🔴 Critical Issues1. Missing User Token Client Validation in Backend Handler Location: The handlers use user-scoped clients correctly ( _, reqDyn := GetK8sClientsForRequest(c)
if reqDyn == nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or missing token"})
c.Abort()
return
}Problem: Per CLAUDE.md line 530-535 and reqK8s, reqDyn := GetK8sClientsForRequest(c)
if reqK8s == nil { // Check reqK8s, not reqDyn
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or missing token"})
c.Abort()
return
}Why this matters: If Fix: Change to check 2. Type Assertion Without Safety Check Location: spec, _, _ := unstructured.NestedMap(obj.Object, "spec")
if spec == nil {
spec = map[string]interface{}{}
}Problem: Per CLAUDE.md line 452-456 and // ❌ FORBIDDEN: Direct type assertions without checking
obj.Object["spec"].(map[string]interface{})
// ✅ REQUIRED: Use unstructured.Nested* helpers
spec, found, err := unstructured.NestedMap(obj.Object, "spec")
if \!found || err \!= nil {
return fmt.Errorf("spec not found")
}Current code: You're ignoring the Fix: spec, found, err := unstructured.NestedMap(obj.Object, "spec")
if err \!= nil {
log.Printf("Failed to get spec: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read spec"})
return
}
if \!found {
spec = map[string]interface{}{}
}🟡 Major Issues3. Direct Type Assertion in Sessions Handler Location: spec := session["spec"].(map[string]interface{})Problem: This violates the type-safety rule (CLAUDE.md line 452-456). While this is existing code in the Create flow where Recommendation: spec, ok := session["spec"].(map[string]interface{})
if \!ok {
log.Printf("Invalid spec type in session")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to set config repo"})
return
}4. Frontend: Missing Type Definition for Config Repo Location: The type definition is missing from the PR changes. The file was added but not shown in the diff. Verify: Ensure this file exists and has proper types: export type ProjectSettingsCR = {
defaultConfigRepo?: {
gitUrl: string;
branch?: string;
};
};
export type UpdateProjectSettingsRequest = {
defaultConfigRepo?: {
gitUrl: string;
branch?: string;
};
};🔵 Minor Issues5. Inconsistent Error Messages Location: c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read project settings"})vs line 78: c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to read project settings"})Observation: The messages are identical for GET and UPDATE failures. Consider making them more specific:
6. Frontend: Potential Race Condition in useEffect Location: useEffect(() => {
if (projectSettings?.defaultConfigRepo?.gitUrl) {
const current = form.getValues();The code is cut off at line 100, but if this is setting form values in useEffect without proper dependencies, it could cause render loops. Recommendation: Ensure the dependency array includes useEffect(() => {
if (projectSettings?.defaultConfigRepo?.gitUrl) {
form.setValue('configRepoUrl', projectSettings.defaultConfigRepo.gitUrl);
if (projectSettings.defaultConfigRepo.branch) {
form.setValue('configRepoBranch', projectSettings.defaultConfigRepo.branch);
}
}
}, [projectSettings, form]); // Ensure proper dependencies7. Missing Context in Operator Log Messages Location: base = append(base, corev1.EnvVar{Name: "CONFIG_REPO_GIT_URL", Value: gitURL})Observation: No log message when config repo env vars are injected. For debugging, consider adding: if gitURL, ok := configRepo["gitUrl"].(string); ok && strings.TrimSpace(gitURL) \!= "" {
log.Printf("Injecting config repo for session %s/%s: %s", namespace, sessionName, gitURL)
base = append(base, corev1.EnvVar{Name: "CONFIG_REPO_GIT_URL", Value: gitURL})
}8. Dead Code Removal Not Reflected in Routes Location: Check You removed
Action: Confirm with: cd components/backend && grep -r "EnrichProjectSettingsWithProviders" .
grep -r "repository" routes.goPositive Highlights✅ Excellent Test Coverage: 10 unit tests (Ginkgo) + 4 e2e tests (Cypress) covering happy path, edge cases, and error conditions. ✅ Proper Security Patterns: User token authentication enforced, RBAC checks, proper auth tests with ✅ Clean Code Removal: Removed 196 lines of dead code ( ✅ Consistent Naming: ✅ React Query Best Practices: Proper query hooks with invalidation, cache management, and mutation patterns per ✅ Shadcn UI Compliance: All UI components use Shadcn ( ✅ Type Safety (Frontend): Zero ✅ CRD Updates: Proper OpenAPI schema in ✅ Error Handling: Non-fatal handling in ✅ Idempotent Operations: Retry logic in RecommendationsPrioritized Action ItemsBefore Merge:
Post-Merge (Nice-to-Have):
Architecture & DesignDesign Pattern: The separation of concerns is excellent:
Hydration Strategy: The API Design: RESTful endpoints ( Testing AssessmentUnit Tests (
E2E Tests (
Coverage: Excellent. All major flows covered. Security Review✅ Authentication: User token required for all operations Performance Considerations
Mitigation: Already implemented - non-fatal error handling, depth=1 clone, single-branch fetch. Future Optimization: Consider caching config repos at the cluster level (shared PVC), but out of scope for this PR. Final VerdictApprove with Minor Fixes ⭐⭐⭐⭐☆ This is a well-architected feature with strong adherence to project standards. The two critical issues are straightforward to fix and don't affect functionality - they're about consistency and defensive programming. Estimated Fix Time: 5 minutes Strengths: Clean code removal, comprehensive tests, proper React Query patterns, security-conscious, excellent UX (pre-fill from workspace defaults). Weaknesses: Minor type-safety oversights in error handling paths (easily fixed). 🔍 View AI decision process (logs available for 90 days) 📋 View memory system files loaded (click to expand)What Amber Loaded for Code ReviewAmber automatically loaded these repository standards from the memory system:
Impact: This review used your repository's specific code quality standards, security patterns, and best practices from the memory system (PRs #359, #360) - not just generic code review guidelines. |
No description provided.