feat(git): support configurable git remote name#1548
feat(git): support configurable git remote name#1548deepakrawat-dce wants to merge 4 commits intocoleam00:devfrom
Conversation
Archon hardcoded 'origin' as the git remote name in all fetch/push/reset operations. This breaks for repos that use non-standard remote names (e.g. enterprise monorepos with numbered remotes like '260', '262', '264'). Add `worktree.remote` config option in `.archon/config.yaml` and auto-detection via `getDefaultRemote()` when not configured: 1. 'origin' if it exists (standard convention) 2. The sole remote if only one is configured 3. Actionable error if ambiguous (multiple non-origin remotes) Thread the remote name through all git operations: syncWorkspace, syncRepository, getDefaultBranch, getRemoteUrl, worktree creation (issue/PR/ task/fork), branch tracking, and remote branch deletion. All existing callers default to 'origin' so this is fully backwards-compatible.
📝 WalkthroughWalkthroughAdds repository-level git-remote support: introduces ChangesGit Remote Configurability
Sequence Diagram(s)sequenceDiagram
participant Config
participant Orchestrator
participant WorktreeProvider
participant GitModule
participant RepoFS
Config->>Orchestrator: loadRepoConfig(repoPath)
Orchestrator->>WorktreeProvider: request worktree create (repoPath, repoConf)
alt repoConf.worktree.remote present
WorktreeProvider->>WorktreeProvider: use configured remote (trimmed)
else repoConf.worktree.remote missing
WorktreeProvider->>GitModule: getDefaultRemote(repoPath)
GitModule-->>WorktreeProvider: remote name or null
alt remote null
WorktreeProvider-->>RepoFS: throw actionable "ambiguous remote" error
end
end
WorktreeProvider->>GitModule: syncWorkspace(workspacePath, baseBranch?, { remote })
GitModule->>GitModule: git fetch <remote> <branch>
GitModule->>GitModule: git reset --hard <remote>/<branch>
WorktreeProvider->>GitModule: create branch / set-upstream using <remote>/<branch>
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/isolation/src/pr-state.ts (1)
42-54: ⚡ Quick winUse
getRemoteUrl()here instead of duplicating the git call.This PR already added a remote-aware helper in
@archon/git, but this path still shells out directly. Reusing the helper keeps the no-remote/error behavior centralized and avoids the two implementations drifting again.Suggested fix
-import { execFileAsync } from '@archon/git'; +import { execFileAsync, getRemoteUrl } from '@archon/git';- let remoteUrl = ''; - try { - const { stdout } = await execFileAsync('git', ['-C', repoPath, 'remote', 'get-url', remote], { - timeout: 10000, - }); - remoteUrl = stdout.trim(); - } catch (error) { + let remoteUrl = ''; + try { + remoteUrl = (await getRemoteUrl(repoPath, remote)) ?? ''; + } catch (error) { getLog().debug( { err: error as Error, repoPath, branch }, 'isolation.pr_state_remote_lookup_failed' ); cache?.set(branch, 'NONE'); return 'NONE'; }As per coding guidelines, "Use
@archon/gitfunctions for git operations; useexecFileAsync(notexec) when calling git directly".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/isolation/src/pr-state.ts` around lines 42 - 54, Replace the direct git shell-out using execFileAsync that sets remoteUrl with the shared helper getRemoteUrl from `@archon/git`: call getRemoteUrl(repoPath, remote) (or the helper's appropriate param order) instead of execFileAsync, assign its result to remoteUrl, and preserve the existing error handling path (log via getLog().debug with the caught error, set cache?.set(branch, 'NONE') and return 'NONE') so behavior remains identical; remove the duplicated git call and import getRemoteUrl where pr-state.ts currently references execFileAsync/remoteUrl.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/git/src/repo.ts`:
- Around line 54-60: The remotes array may contain CRLF/trailing whitespace
(e.g., "origin\r") so remotes.includes('origin') can fail; update the
construction of remotes in repo.ts (the code that builds the remotes variable)
to normalize entries by trimming each item after split (e.g., .split('\n').map(r
=> r.trim()).filter(r => r.length > 0)) and then use the normalized remotes when
checking for 'origin' (and when returning remotes[0]) so CRLF or trailing spaces
won't break detection.
- Around line 62-66: The catch block in packages/git/src/repo.ts is swallowing
any git execution error and returning null (seen around the
get_default_remote_failed log), which incorrectly signals "no default remote";
change it to rethrow or propagate the git error except in the explicit case of
"no remote configured": in the catch in the function that queries the default
remote (references repoPath, getLog(), and the get_default_remote_failed log
key), inspect the error (err.stderr / exit code) and if it clearly indicates "no
remote" return null, otherwise rethrow the error so callers see the actual git
failure instead of the ambiguous null sentinel.
---
Nitpick comments:
In `@packages/isolation/src/pr-state.ts`:
- Around line 42-54: Replace the direct git shell-out using execFileAsync that
sets remoteUrl with the shared helper getRemoteUrl from `@archon/git`: call
getRemoteUrl(repoPath, remote) (or the helper's appropriate param order) instead
of execFileAsync, assign its result to remoteUrl, and preserve the existing
error handling path (log via getLog().debug with the caught error, set
cache?.set(branch, 'NONE') and return 'NONE') so behavior remains identical;
remove the duplicated git call and import getRemoteUrl where pr-state.ts
currently references execFileAsync/remoteUrl.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d656e48b-0636-4ddf-865b-01f8ac12f6dc
📒 Files selected for processing (10)
packages/core/src/config/config-loader.tspackages/core/src/config/config-types.tspackages/git/src/branch.tspackages/git/src/git.test.tspackages/git/src/index.tspackages/git/src/repo.tspackages/isolation/src/pr-state.tspackages/isolation/src/providers/worktree.test.tspackages/isolation/src/providers/worktree.tspackages/isolation/src/types.ts
Use 'jan', 'feb', 'mar' as example remote names instead of numbered remotes that reference a specific organization.
- Split on /\r?\n/ instead of '\n' so Windows CRLF doesn't break
origin detection (e.g. 'origin\r' fails includes('origin'))
- Let git execution errors propagate instead of swallowing them as
null — callers now see the real failure instead of a misleading
"set worktree.remote" message
|
@deepakrawat-dce related to #1419 — worktree.baseBranch config vs configurable remote name share git-config concerns. |
|
Hi @deepakrawat-dce — thanks for opening this PR. This repository uses a PR template at
Could you fill those out (even briefly)? The template If a section genuinely doesn't apply, just write "N/A" in |
|
🔗 Related issue: This PR is related to issue #1273 ("syncWorkspace always resets managed source clone to origin/main, ignoring configured default_branch"). Supporting configurable remote names complements the branch-detection fix for that issue. |
Review SummaryVerdict: blocking-issues Your PR adds a well-scoped, well-tested feature that removes the hardcoded Blocking issues
Suggested fixes
Minor / nice-to-have
ComplimentsThe end-to-end test coverage in Reviewed via maintainer-review-pr workflow (Pi/Minimax). Aspects run: code-review, error-handling, test-coverage, comment-quality, docs-impact. |
Address review feedback: - Load repo config before syncWorkspace in orchestrator-agent.ts and pass the resolved remote name - Thread remote through cleanupMergedWorktrees → isSafeToRemove → getPrState so PR-state detection works for non-origin remotes - Add getDefaultBranch remote param to getWorktreeStatusBreakdown - Add config-loader tests: propagates remote, trims whitespace, undefined when not configured - Add worktree test: fromBranch + custom remote (task workflow) - Document worktree.remote in configuration.md reference - Add CHANGELOG entry under [Unreleased] - Generalize comment examples (remove org-specific language) - Fix redundant docstring in getRemoteUrl
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/core/src/orchestrator/orchestrator-agent.ts (1)
774-780:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSync notification always says "origin/" even when a different remote is configured.
remoteis scoped insidediscoverAllWorkflowsand is not surfaced throughDiscoverResult, so this user-facing message will be misleading wheneverworktree.remoteis set to something other than'origin'.🛠️ Proposed fix
Add
remotetoDiscoverResultand thread it through:interface DiscoverResult { workflows: WorkflowWithSource[]; errors: readonly WorkflowLoadError[]; syncResult?: WorkspaceSyncResult; syncError?: string; config?: MergedConfig; + remote?: string; }Inside
discoverAllWorkflows, return the resolved value:- return { workflows, errors: allErrors, syncResult, syncError, config }; + return { workflows, errors: allErrors, syncResult, syncError, config, remote };At the destructuring call site (lines 752–758):
const { workflows: workflowsWithSource, errors: workflowErrors, syncResult, syncError, config: discoveredConfig, + remote: syncRemote, } = await discoverAllWorkflows(conversation);In the notification template:
- content: `Synced with origin/${syncResult.branch} \u2014 updated ${syncResult.previousHead} \u2192 ${syncResult.newHead}`, + content: `Synced with ${syncRemote ?? 'origin'}/${syncResult.branch} \u2014 updated ${syncResult.previousHead} \u2192 ${syncResult.newHead}`,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/orchestrator/orchestrator-agent.ts` around lines 774 - 780, The message hardcodes "origin/" because the remote name is not included in DiscoverResult; update the discoverAllWorkflows return type (DiscoverResult) to include a remote string, set that remote from worktree.remote inside discoverAllWorkflows, thread it through to where syncResult is produced (ensure the destructuring/site that consumes discoverAllWorkflows includes remote), and replace the hardcoded "origin/" in the platform.sendStructuredEvent payload with the remote value from syncResult (e.g., use syncResult.remote/${syncResult.branch}) so the notification reflects the configured remote.packages/core/src/services/cleanup-service.ts (1)
587-611:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd
remoteparameter to thecleanupMergedEnvironmentswrapper's options type.The wrapper at
isolation-operations.ts:168–174accepts{ includeClosed?: boolean }, but the underlyingcleanupMergedWorktreesfunction now accepts{ includeClosed?: boolean; remote?: string }. Without updating the wrapper's type, callers using the public API cannot pass theremoteoption.Fix in
isolation-operations.tsexport async function cleanupMergedEnvironments( codebaseId: string, mainPath: string, - options: { includeClosed?: boolean } = {} + options: { includeClosed?: boolean; remote?: string } = {} ): Promise<CleanupOperationResult> { return cleanupMergedWorktrees(codebaseId, mainPath, options); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/services/cleanup-service.ts` around lines 587 - 611, The wrapper function cleanupMergedEnvironments currently types its options as { includeClosed?: boolean } but calls cleanupMergedWorktrees which accepts { includeClosed?: boolean; remote?: string }, so update the wrapper's options type to include remote?: string and forward options.remote when invoking cleanupMergedWorktrees (ensure the function signature/parameter typing for cleanupMergedEnvironments and any related call site or exported type reflect remote?: string so callers can pass the remote option).
🧹 Nitpick comments (1)
packages/core/src/services/cleanup-service.ts (1)
308-316: Scheduled cleanup diverges from on-demand cleanup for non-origin remotes.
runScheduledCleanup(line 311) callsgetDefaultBranch(mainRepoPath)without aremote, hardcoding'origin'behavior. After this PR, the on-demandcleanupMergedWorktreesis remote-aware, but the periodic background cycle is not. For a repo configured withworktree.remote: upstream, the scheduler could fail to detect branches as merged (if they are merged intoupstream/mainbut haven't reachedorigin/main), leaving worktrees behind indefinitely.This is pre-existing behavior not changed by this PR, but the delta is now observable. A follow-up task to thread repo-config remote loading into
runScheduledCleanup's per-environment loop would close the gap.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/core/src/services/cleanup-service.ts` around lines 308 - 316, runScheduledCleanup currently calls getDefaultBranch(mainRepoPath) with the implicit 'origin' behavior and should be made remote-aware like cleanupMergedWorktrees; in the per-environment loop, load the repo config (repo-config/worktree.remote) for mainRepoPath and pass the configured remote down to getDefaultBranch and/or isBranchMerged (or call cleanupMergedWorktrees with the remote) so branch-merger checks use the correct remote (e.g., pass remote into getDefaultBranch, isBranchMerged, and any calls referencing env.branch_name) to ensure the scheduler detects merges against non-origin remotes such as upstream.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/core/src/services/cleanup-service.ts`:
- Around line 448-452: The worktree remote argument isn't flowing through the
isolation cleanup path: update the IsolationResolverDeps.cleanup.getBreakdown
type to accept an optional third parameter (remote?: string), adjust the
IsolationResolver implementation (the cleanup.getBreakdown caller/implementer)
to forward the remote to the underlying getWorktreeStatusBreakdown logic, and
update the command handler call site that currently does
getWorktreeStatusBreakdown(codebase.id, codebase.default_cwd) to load the repo
config (worktree.remote) and pass that value as the third argument so merge
detection uses the correct remote.
---
Outside diff comments:
In `@packages/core/src/orchestrator/orchestrator-agent.ts`:
- Around line 774-780: The message hardcodes "origin/" because the remote name
is not included in DiscoverResult; update the discoverAllWorkflows return type
(DiscoverResult) to include a remote string, set that remote from
worktree.remote inside discoverAllWorkflows, thread it through to where
syncResult is produced (ensure the destructuring/site that consumes
discoverAllWorkflows includes remote), and replace the hardcoded "origin/" in
the platform.sendStructuredEvent payload with the remote value from syncResult
(e.g., use syncResult.remote/${syncResult.branch}) so the notification reflects
the configured remote.
In `@packages/core/src/services/cleanup-service.ts`:
- Around line 587-611: The wrapper function cleanupMergedEnvironments currently
types its options as { includeClosed?: boolean } but calls
cleanupMergedWorktrees which accepts { includeClosed?: boolean; remote?: string
}, so update the wrapper's options type to include remote?: string and forward
options.remote when invoking cleanupMergedWorktrees (ensure the function
signature/parameter typing for cleanupMergedEnvironments and any related call
site or exported type reflect remote?: string so callers can pass the remote
option).
---
Nitpick comments:
In `@packages/core/src/services/cleanup-service.ts`:
- Around line 308-316: runScheduledCleanup currently calls
getDefaultBranch(mainRepoPath) with the implicit 'origin' behavior and should be
made remote-aware like cleanupMergedWorktrees; in the per-environment loop, load
the repo config (repo-config/worktree.remote) for mainRepoPath and pass the
configured remote down to getDefaultBranch and/or isBranchMerged (or call
cleanupMergedWorktrees with the remote) so branch-merger checks use the correct
remote (e.g., pass remote into getDefaultBranch, isBranchMerged, and any calls
referencing env.branch_name) to ensure the scheduler detects merges against
non-origin remotes such as upstream.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: edd0d4b1-1289-49fb-ad66-af1eaed9ad68
📒 Files selected for processing (9)
CHANGELOG.mdpackages/core/src/config/config-loader.test.tspackages/core/src/config/config-types.tspackages/core/src/orchestrator/orchestrator-agent.tspackages/core/src/services/cleanup-service.tspackages/docs-web/src/content/docs/reference/configuration.mdpackages/git/src/repo.tspackages/isolation/src/providers/worktree.test.tspackages/isolation/src/types.ts
✅ Files skipped from review due to trivial changes (3)
- CHANGELOG.md
- packages/core/src/config/config-loader.test.ts
- packages/isolation/src/types.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/isolation/src/providers/worktree.test.ts
- packages/git/src/repo.ts
| export async function getWorktreeStatusBreakdown( | ||
| codebaseId: string, | ||
| mainRepoPath: string | ||
| mainRepoPath: string, | ||
| remote?: string | ||
| ): Promise<WorktreeStatusBreakdown> { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify all callers of getWorktreeStatusBreakdown and whether they pass remote
rg -n --type ts -A 3 "getWorktreeStatusBreakdown\s*("Repository: coleam00/Archon
Length of output: 170
🏁 Script executed:
#!/bin/bash
# Fix regex: escape parenthesis properly
rg -n --type ts "getWorktreeStatusBreakdown" -A 3Repository: coleam00/Archon
Length of output: 4480
🏁 Script executed:
#!/bin/bash
# Also verify the function signature in cleanup-service.ts around lines 448-452
rg -n -B 2 -A 8 "export async function getWorktreeStatusBreakdown" packages/core/src/services/cleanup-service.tsRepository: coleam00/Archon
Length of output: 484
🏁 Script executed:
#!/bin/bash
# Check the command-handler.ts line 1004 context
sed -n '998,1015p' packages/core/src/handlers/command-handler.tsRepository: coleam00/Archon
Length of output: 774
🏁 Script executed:
#!/bin/bash
# Read the full getWorktreeStatusBreakdown implementation
sed -n '448,520p' packages/core/src/services/cleanup-service.tsRepository: coleam00/Archon
Length of output: 2163
🏁 Script executed:
#!/bin/bash
# Check orchestrator.ts context around line 91
sed -n '80,110p' packages/core/src/orchestrator/orchestrator.tsRepository: coleam00/Archon
Length of output: 1180
🏁 Script executed:
#!/bin/bash
# Check if there's repo config loading at the command-handler call site
sed -n '990,1020p' packages/core/src/handlers/command-handler.tsRepository: coleam00/Archon
Length of output: 1229
🏁 Script executed:
#!/bin/bash
# Check the getDefaultBranch signature and default behavior
rg -n -B 2 -A 5 "export.*function getDefaultBranch" packages/core/srcRepository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Search for where getBreakdown is called in IsolationResolver
rg -n "getBreakdown" packages -t ts -A 3Repository: coleam00/Archon
Length of output: 661
🏁 Script executed:
#!/bin/bash
# Check if loadConfig or loadRepoConfig is used in the command-handler.ts handler
grep -n "loadRepoConfig\|loadConfig" packages/core/src/handlers/command-handler.tsRepository: coleam00/Archon
Length of output: 364
🏁 Script executed:
#!/bin/bash
# Find getDefaultBranch definition
rg -n "getDefaultBranch" packages/core/src/services/cleanup-service.ts -B 2 -A 3Repository: coleam00/Archon
Length of output: 1006
🏁 Script executed:
#!/bin/bash
# See how getBreakdown is actually called in IsolationResolver
rg -n "getBreakdown" packages/isolation/src/resolver.ts -B 5 -A 5Repository: coleam00/Archon
Length of output: 470
🏁 Script executed:
#!/bin/bash
# Check the full cleanup function that uses getBreakdown
sed -n '40,200p' packages/isolation/src/resolver.tsRepository: coleam00/Archon
Length of output: 5127
🏁 Script executed:
#!/bin/bash
# Find where getBreakdown is actually invoked in IsolationResolver
rg -n "this\.cleanup\?.getBreakdown\|\.getBreakdown\(" packages/isolation/src/resolver.ts -B 2 -A 2Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Check the getDefaultBranch function signature
rg -n "^export.*function getDefaultBranch" packages/core/src/services/cleanup-service.ts -A 3Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/all/bin/bash
# Check if loadRepoConfig is available in command-handler context
rg -n "loadRepoConfig" packages/core/src/handlers/command-handler.tsRepository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Search for getDefaultBranch more broadly
rg -n "getDefaultBranch" packages/core/src/services/cleanup-service.ts | head -20Repository: coleam00/Archon
Length of output: 293
🏁 Script executed:
#!/bin/bash
# Find the actual definition of getDefaultBranch
rg -n "function getDefaultBranch" packages/core/srcRepository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Search in all .ts files for getDefaultBranch import and definition
rg -n "getDefaultBranch" packages/core/src -A 2 | head -40Repository: coleam00/Archon
Length of output: 2960
🏁 Script executed:
#!/bin/bash
# Look at the imports in cleanup-service.ts to find where getDefaultBranch comes from
head -50 packages/core/src/services/cleanup-service.tsRepository: coleam00/Archon
Length of output: 1973
🏁 Script executed:
#!/bin/bash
# Find getDefaultBranch definition in `@archon/git`
rg -n "export.*getDefaultBranch" packages/git/src -A 5Repository: coleam00/Archon
Length of output: 520
🏁 Script executed:
#!/bin/bash
# Also search for it in git package more broadly
find packages/git -name "*.ts" -exec grep -l "getDefaultBranch" {} \;Repository: coleam00/Archon
Length of output: 166
🏁 Script executed:
#!/bin/bash
# Check if repo config has a remote field and how it's accessed
rg -n "worktree\.remote" packages/core/src -B 2 -A 2Repository: coleam00/Archon
Length of output: 833
🏁 Script executed:
#!/bin/bash
# Look at the Codebase type to see if it has remote info
rg -n "type Codebase\|interface Codebase" packages/core/src -A 10Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Check the config-loader to see what repo config contains
head -100 packages/core/src/config/config-loader.tsRepository: coleam00/Archon
Length of output: 3379
🏁 Script executed:
#!/bin/bash
# Check the Codebase type definition
rg -n "export.*interface Codebase\|export.*type Codebase" packages/core/src -A 15Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Check if codebase has remote field or if it needs to be loaded from config
rg -n "codebase\." packages/core/src/handlers/command-handler.ts | grep -i remoteRepository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# See what fields the Codebase has in the database
rg -n "type CodebaseRow\|interface CodebaseRow" packages/core/src -A 15Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Look for Codebase import in command-handler to understand where it comes from
grep -n "Codebase" packages/core/src/handlers/command-handler.ts | head -10Repository: coleam00/Archon
Length of output: 762
🏁 Script executed:
#!/bin/bash
# Find Codebase type in types or db
find packages/core/src -name "*.ts" -exec grep -l "type Codebase\|interface Codebase" {} \;Repository: coleam00/Archon
Length of output: 205
🏁 Script executed:
#!/bin/bash
# Search more broadly for Codebase type definition
rg -n "Codebase" packages/core/src/db -A 5 | grep -E "type|interface" -A 5Repository: coleam00/Archon
Length of output: 5849
🏁 Script executed:
#!/bin/bash
# Get the Codebase type definition
grep -n "export.*type Codebase\|export.*interface Codebase" packages/core/src/types/index.ts -A 15Repository: coleam00/Archon
Length of output: 474
🏁 Script executed:
#!/bin/bash
# Check if there's a loadRepoConfig call or similar available in command-handler
sed -n '550,560p' packages/core/src/handlers/command-handler.tsRepository: coleam00/Archon
Length of output: 378
🏁 Script executed:
#!/bin/bash
# Check how repo config is used elsewhere to understand the pattern
rg -n "loadRepoConfig\|loadConfig" packages/core/src/handlers -B 2 -A 5Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Verify the IsolationResolver's actual function signature expectation
sed -n '45,55p' packages/isolation/src/resolver.tsRepository: coleam00/Archon
Length of output: 437
🏁 Script executed:
#!/bin/bash
# Check how cleanup functions are called in IsolationResolver to see if remote can be passed through
rg -n "cleanup.getBreakdown\|\.cleanup\?.getBreakdown" packages/isolation/src/resolver.ts -B 3 -A 3Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Verify if loadRepoConfig is accessible in command-handler context
rg -n "loadRepoConfig\|loadConfig" packages/core/src/config/config-loader.ts | head -5Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Double-check: search for all places getBreakdown is actually called in IsolationResolver
rg -n "getBreakdown" packages/isolation/src/resolver.ts -B 5 -A 5Repository: coleam00/Archon
Length of output: 470
🏁 Script executed:
#!/bin/bash
# Verify if makeRoom function also has the same signature issue
sed -n '46,52p' packages/isolation/src/resolver.tsRepository: coleam00/Archon
Length of output: 352
🏁 Script executed:
#!/bin/bash
# Check if there are any recent changes to getWorktreeStatusBreakdown signature
git log -p --all -S "getWorktreeStatusBreakdown" -- packages/core/src/services/cleanup-service.ts | head -100Repository: coleam00/Archon
Length of output: 41
🏁 Script executed:
#!/bin/bash
# Check if TypeScript compilation would catch this type mismatch
# by looking at the actual assignment in orchestrator.ts
sed -n '85,95p' packages/core/src/orchestrator/orchestrator.tsRepository: coleam00/Archon
Length of output: 463
🏁 Script executed:
#!/bin/bash
# Verify the complete picture: search for all instances of remote configuration in cleanup/isolation contexts
rg -n "remote" packages/isolation/src/resolver.tsRepository: coleam00/Archon
Length of output: 139
🏁 Script executed:
#!/bin/bash
# Check if there are any type assertions or overloads for getBreakdown
rg -n "getBreakdown" packages/core/src/orchestrator/orchestrator.ts -B 5 -A 5Repository: coleam00/Archon
Length of output: 475
🏁 Script executed:
#!/bin/bash
# Check if TypeScript compilation errors are expected or if there's a tsconfig that might suppress this
rg -n "getWorktreeStatusBreakdown" packages/core/src/orchestrator/orchestrator.ts -B 2 -A 2Repository: coleam00/Archon
Length of output: 390
🏁 Script executed:
#!/bin/bash
# Check the types more carefully - does the assignment work despite the signature mismatch?
# Let's look at the complete function in cleanup-service to verify the parameter count
sed -n '448,455p' packages/core/src/services/cleanup-service.tsRepository: coleam00/Archon
Length of output: 336
🏁 Script executed:
#!/bin/bash
# Verify the interface definition once more and check if there's been a recent update
sed -n '48,52p' packages/isolation/src/resolver.tsRepository: coleam00/Archon
Length of output: 294
🏁 Script executed:
#!/bin/bash
# Search for any TypeScript error suppressions around this code
rg -n "@ts-ignore\|@ts-expect-error" packages/core/src/orchestrator/orchestrator.ts -B 3 -A 3Repository: coleam00/Archon
Length of output: 41
Type signature mismatch and missing remote parameter flow in worktree status breakdown.
getWorktreeStatusBreakdown function signature has 3 parameters including optional remote, and its implementation passes remote to getDefaultBranch(repoPath, remote) at line 466. However, the IsolationResolverDeps.cleanup.getBreakdown interface (packages/isolation/src/resolver.ts:50) is defined with only 2 parameters: (codebaseId: string, repoPath: string). This type incompatibility prevents remote from being passed through the isolation resolver path.
Additionally, the command-handler.ts call (line 1004) passes only 2 arguments: getWorktreeStatusBreakdown(codebase.id, codebase.default_cwd), meaning repos with non-origin remotes configured via worktree.remote will always use 'origin' for merge detection, producing incorrect merged/stale counts in /worktree status output.
Fix requires:
- Update
IsolationResolverDeps.cleanup.getBreakdowninterface to accept an optional 3rd parameter for remote - Update the IsolationResolver implementation to pass remote through the cleanup path
- Load repo config in command-handler.ts at line 1004 and pass the configured remote to
getWorktreeStatusBreakdown
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/core/src/services/cleanup-service.ts` around lines 448 - 452, The
worktree remote argument isn't flowing through the isolation cleanup path:
update the IsolationResolverDeps.cleanup.getBreakdown type to accept an optional
third parameter (remote?: string), adjust the IsolationResolver implementation
(the cleanup.getBreakdown caller/implementer) to forward the remote to the
underlying getWorktreeStatusBreakdown logic, and update the command handler call
site that currently does getWorktreeStatusBreakdown(codebase.id,
codebase.default_cwd) to load the repo config (worktree.remote) and pass that
value as the third argument so merge detection uses the correct remote.
Summary
'origin'as the git remote name in all fetch/push/reset operations, breaking repos with non-standard remotes.jan,feb,marfor release-based workflows) cannot use Archon's worktree isolation at all.worktree.remoteconfig option,getDefaultRemote()auto-detection, and threaded remote name through all git operations.UX Journey
Before
After
Architecture Diagram
Before
After
Connection inventory:
remotein options${remote}/instead oforigin/worktree.remoteremoteparamLabel Snapshot
risk: lowsize: Mgit,isolation,configgit:repo,isolation:worktree,core:configChange Metadata
featuremulti(git + isolation + core)Linked Issue
Validation Evidence (required)
Security Impact (required)
NoNo(same git fetch/push, just configurable remote name)NoNoYes: N/ACompatibility / Migration
Yes— all new parameters have defaults matching prior behavior ('origin')Yes— new optionalworktree.remotefield in.archon/config.yamlNoworktree.remotebehave identically.Human Verification (required)
getDefaultRemote()correctly auto-detects sole remote; confirmedworktree.remoteconfig is respectedSide Effects / Blast Radius (required)
'origin'default. No behavior change for repos that already useorigin.resolveRemote()method logs at info level when auto-detecting a non-origin remoteRollback Plan (required)
worktree.remoteconfig field is the toggle — removing it reverts tooriginbehaviorRisks and Mitigations
Risk:
getDefaultRemote()now throws on git errors instead of returning null, which could surface unexpected errors in edge cases.resolveRemote()which is inside acreateWorktree()try/catch that already surfaces errors with actionable messages. The error path is intentional — better to fail fast with the real error than mislead the user.Risk: CRLF handling via
/\r?\n/regex could theoretically split differently on exotic git builds..trim()on each entry catches any trailing whitespace.Summary by CodeRabbit
New Features
worktree.remotesetting in.archon/config.yaml, enabling support for repositories with non-standard remote names.originand fallback to the sole configured remote.Documentation