Skip to content

Conversation

@sallyom
Copy link
Collaborator

@sallyom sallyom commented Jan 8, 2026

@github-actions

This comment has been minimized.

@sallyom sallyom changed the title feat: display git branch in Context Modal repository list [WIP] display git branch in Context Modal repository list Jan 8, 2026
@sallyom
Copy link
Collaborator Author

sallyom commented Jan 8, 2026

The git repo context needs more of an overhaul than this PR- the platform needs to be aware of remotes and branches in general. This PR offers a slight improvement, but doesn't help with the platform's overall awareness of branches and remotes.
I'm seeing an edge case where if I add a 2nd branch as context, the platform doesn't know what to do with it - the frontend happily reports it's been cloned - but the actual pod does not include the new branch:

(app-root) sh-5.1$ git branch
* git-context-show-branch
  main
Screenshot 2026-01-08 at 11 53 49 AM

@sallyom sallyom marked this pull request as draft January 8, 2026 20:00
sallyom added a commit to sallyom/platform that referenced this pull request Jan 8, 2026
…ut branch

Implements the remaining functionality from the git repo context feature:

1. **Fix 2nd branch checkout issue (Runner)**:
   - Modified `clone_repo_at_runtime()` in main.py to handle branch switching
   - When repo already exists, now fetches and checks out the requested branch
   - Previously skipped clone entirely if repo directory existed

2. **Add /repos/status endpoint (Runner)**:
   - New GET endpoint to query actual checked-out branches
   - Returns list of repos with current branch info from git
   - Used by operator to sync actual state to status

3. **Fetch and store current branch (Operator)**:
   - Added `fetchActualBranchesFromRunner()` helper function
   - Calls runner's /repos/status endpoint during reconciliation
   - Updates status.reconciledRepos with both intended and actual branch
   - New field: `currentBranch` alongside existing `branch` field

4. **Display actual branch (Frontend)**:
   - Updated RepositoriesAccordion to support `currentBranch` field
   - Changed data source from spec.repos to status.reconciledRepos
   - Badge now shows actual checked-out branch from runner

**User Impact**:
- Can now add same repo with different branches as context
- Context Modal displays the actual checked-out branch
- Runner properly switches branches when user adds 2nd branch
- System maintains both intended (spec) and actual (status) branch info

Fixes the issue described in PR ambient-code#498 where adding a 2nd branch for the
same repo would show in UI but not actually checkout in the runner pod.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from codecov bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@sallyom sallyom force-pushed the git-context-show-branch branch from 6f4ad67 to 4844743 Compare January 9, 2026 16:05
@codecov
Copy link

codecov bot commented Jan 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sallyom sallyom force-pushed the git-context-show-branch branch 5 times, most recently from d60500d to eab1369 Compare January 9, 2026 21:16
@github-actions

This comment was marked as outdated.

@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 9, 2026
@sallyom sallyom force-pushed the git-context-show-branch branch from d838363 to 6d97fd5 Compare January 12, 2026 15:30
@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@sallyom sallyom force-pushed the git-context-show-branch branch from cee97b7 to 769ca2f Compare January 12, 2026 16:09
@github-actions

This comment was marked as outdated.

@github-actions

This comment was marked as outdated.

@sallyom sallyom force-pushed the git-context-show-branch branch from 9ad5a71 to 3ba68db Compare January 12, 2026 21:36
@github-actions

This comment was marked as outdated.

@sallyom sallyom force-pushed the git-context-show-branch branch from 3ba68db to 9ad5a71 Compare January 12, 2026 21:59
@github-actions

This comment was marked as outdated.

@sallyom sallyom force-pushed the git-context-show-branch branch from 9ad5a71 to 7bd109d Compare January 12, 2026 22:07
@github-actions

This comment was marked as outdated.

@sallyom

This comment was marked as outdated.

@Gkrumbach07
Copy link
Collaborator

Why use timestamp, can't you use the session id so it's easier to trace back

…tory handling

- Updated ClaudeCodeAdapter to use local variables for message IDs to prevent race conditions during concurrent runs.
- Introduced a new `restart_session_tool` for handling session restarts via MCP tools.
- Enhanced repository cloning logic to create and checkout feature branches named 'ambient/<session-id>' when cloning at runtime.
- Modified the add_repo function to only trigger notifications for newly cloned repositories, preventing duplicate notifications.
- Improved logging for better observability of session and repository operations.

This refactor enhances the reliability and clarity of session management and repository interactions within the ClaudeCodeAdapter.
@sallyom sallyom force-pushed the git-context-show-branch branch 5 times, most recently from 9837d9b to 3a2cce2 Compare January 13, 2026 05:28
and allow for multiple branches within a git repo to be added in context
modal.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: sallyom <somalley@redhat.com>
@sallyom sallyom force-pushed the git-context-show-branch branch from 3a2cce2 to 571281c Compare January 13, 2026 05:35
@ambient-code ambient-code deleted a comment from github-actions bot Jan 13, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 13, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 13, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 13, 2026
@ambient-code ambient-code deleted a comment from github-actions bot Jan 13, 2026
@github-actions
Copy link
Contributor

Claude Code Review

Summary

This PR adds git branch visualization and multi-branch support for repositories in the Context and File Explorer modals. The implementation spans backend (Go), frontend (TypeScript/React), operator (Go), and runner (Python) components. Overall, the code quality is good with solid architecture patterns, but there are several critical security issues and code quality concerns that must be addressed before merge.

Key Changes:

  • Added autoBranch field to AgenticSession CRD and session types
  • Implemented ComputeAutoBranch() helper for consistent branch naming
  • Enhanced frontend to display branch badges in UI
  • Added /repos/status endpoint for fetching active git branches
  • Improved runner to create feature branches on repo clone
  • Updated operator to sync repo status to CR

Issues by Severity

🚫 Blocker Issues

NONE - No blocking issues that prevent merge after critical issues are fixed.

🔴 Critical Issues

1. Type Assertions Without Checking (Backend) - VIOLATED RULE #4

// components/backend/handlers/sessions.go:1559
session.Metadata = updated.Object["metadata"].(map[string]interface{})

Issue: Direct type assertion without checking. This will panic if metadata is not a map.

Required Fix (from CLAUDE.md patterns):

metadata, found, err := unstructured.NestedMap(updated.Object, "metadata")
if !found || err != nil {
    log.Printf("Failed to get metadata: %v", err)
    c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to parse session metadata"})
    return
}
session.Metadata = metadata

Location: components/backend/handlers/sessions.go:1559 (and similar at line 1473)


2. Missing User Token Validation on New Endpoint - VIOLATED RULE #1

// components/backend/handlers/sessions.go:1721
func GetReposStatus(c *gin.Context) {
    project := c.GetString("project")
    // ... NO user token validation!

Issue: The new GetReposStatus endpoint does NOT call GetK8sClientsForRequest(c) to validate the user token. This violates the User Token Authentication Required rule.

Required Fix:

func GetReposStatus(c *gin.Context) {
    project := c.GetString("project")
    sessionName := c.Param("sessionName")
    
    // REQUIRED: Validate user token
    reqK8s, reqDyn := GetK8sClientsForRequest(c)
    if reqK8s == nil {
        c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or missing token"})
        c.Abort()
        return
    }
    
    // ... rest of handler
}

Location: components/backend/handlers/sessions.go:1721


3. Frontend: Missing Error Boundary for New useReposStatus Query

// components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx
const { data: reposStatus } = useReposStatus(params.name, params.sessionName);

Issue: No error handling for the new useReposStatus query. If the backend endpoint fails, the UI will silently fail or show undefined data.

Required Fix:

const { data: reposStatus, error: reposStatusError } = useReposStatus(params.name, params.sessionName);

// Handle error state
if (reposStatusError) {
  console.error('Failed to fetch repos status:', reposStatusError);
  // Optionally show user-friendly error message
}

Location: components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx:84


🟡 Major Issues

4. Inconsistent Error Handling in RemoveRepo

// components/backend/handlers/sessions.go:1490-1493
reconciledRepos, found, err := unstructured.NestedSlice(status, "reconciledRepos")
if !found || err != nil {
    log.Printf("Failed to get reconciledRepos: %v", err)
    reconciledRepos = []interface{}{}
}

Issue: Logs error but continues silently. This could hide data corruption issues.

Recommendation: Consider returning an error if err != nil (actual error vs. simply not found).

Location: components/backend/handlers/sessions.go:1490-1493


5. Python: Race Condition Risk with _restart_requested Flag

# components/runners/claude-code-runner/adapter.py:415
adapter_ref._restart_requested = True

Issue: The _restart_requested flag is set in an async context without locking. If multiple concurrent runs occur, this could cause race conditions.

Recommendation: Use asyncio.Lock() or make this flag thread-safe.

Location: components/runners/claude-code-runner/adapter.py:415


6. Frontend: Polling Interval Not Conditional

// components/frontend/src/services/queries/use-sessions.ts:115
export const useReposStatus = (projectName: string, sessionName: string) => {
  return useQuery({
    queryKey: ["reposStatus", projectName, sessionName],
    queryFn: () => sessionApi.getReposStatus(projectName, sessionName),
    refetchInterval: 5000, // Always polls every 5s
  });
};

Issue: Always polls every 5 seconds, even when session is not running. This wastes resources.

Recommendation: Make refetchInterval conditional based on session phase:

refetchInterval: (query) => {
  const session = queryClient.getQueryData(['sessions', projectName, sessionName]);
  return session?.status?.phase === 'Running' ? 5000 : false;
}

Location: components/frontend/src/services/queries/use-sessions.ts:115


🔵 Minor Issues

7. Missing JSDoc Comments for New Functions

New backend functions lack documentation:

  • ComputeAutoBranch (components/backend/handlers/helpers.go:55)
  • GetReposStatus (components/backend/handlers/sessions.go:1721)

Recommendation: Add GoDoc comments explaining purpose, parameters, and return values.


8. Frontend: Hardcoded Colors in Badge Component

// components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/accordions/repositories-accordion.tsx:145
<Badge className="ml-2 bg-purple-100 text-purple-800">

Issue: Hardcoded colors don't respect dark mode or theme system.

Recommendation: Use Shadcn badge variants or define theme-aware colors in Tailwind config.

Location: components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/accordions/repositories-accordion.tsx:145


9. Operator: Missing OwnerReference on Status Update (Potential)

The operator updates status.reconciledRepos but doesn't show explicit OwnerReference setting in the diff. Verify that OwnerReferences are maintained when updating status.

Location: components/operator/internal/handlers/sessions.go:125-134


10. Python: Logging Verbosity

# components/runners/claude-code-runner/adapter.py:561
logger.info(f"[ClaudeSDKClient Message #{message_count}]: {message}")

Issue: Logs every message from Claude SDK. This could be noisy in production.

Recommendation: Use logger.debug() for per-message logs, keep logger.info() for summaries.


Positive Highlights

Excellent: ComputeAutoBranch() helper provides single source of truth for branch naming
Good: Proper use of unstructured.NestedString in several places (e.g., sessions.go:1503)
Good: Frontend uses React Query hooks consistently for new useReposStatus
Good: CRD update includes proper reconciledRepos array in status subresource
Good: Runner creates feature branches automatically (improves UX)
Good: Idempotency check in clone_repo_at_runtime prevents duplicate notifications
Strong: Frontend properly uses Shadcn UI components (Badge, Accordion, etc.)

Recommendations

Priority 1 (Must Fix Before Merge)

  1. Fix type assertion in sessions.go:1559 - Use unstructured.NestedMap()
  2. Add user token validation to GetReposStatus - Call GetK8sClientsForRequest(c)
  3. Add error handling for useReposStatus in frontend - Check for query errors

Priority 2 (Should Fix)

  1. Fix inconsistent error handling in RemoveRepo (reconciledRepos logic)
  2. Add conditional polling to useReposStatus to avoid unnecessary API calls
  3. Add thread safety to _restart_requested flag in Python adapter

Priority 3 (Nice to Have)

  1. Add JSDoc/GoDoc comments for new functions
  2. Use theme-aware colors for branch badges
  3. Reduce logging verbosity in Python adapter

Testing Recommendations

  • Test GetReposStatus with invalid/missing user tokens (should return 401)
  • Test RemoveRepo with repos that only exist in status.reconciledRepos (not in spec)
  • Test frontend behavior when useReposStatus query fails
  • Test concurrent repo additions (verify idempotency)
  • Verify feature branch creation on runner pod startup

Pre-Merge Checklist

Before approving:


Overall Assessment: This is a solid feature with good architecture decisions, but has 3 critical security/safety issues that must be fixed before merge. The code follows most established patterns but violates a few key rules from CLAUDE.md. After addressing the critical issues, this PR will be ready to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants