mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 18:33:15 +00:00
* feat: authenticate git operations via sandbox proxy instead of credential files
* feat: authenticate git operations via sandbox proxy instead of credential files
* feat: authenticate git operations via sandbox proxy instead of credential files
* removing logger.info
* formatting and linting
* fix: resolve lint errors in server.py (imports, unused vars, undefined names)
* feat: use opaque proxy headers for GitHub auth in sandbox
* linting formatting and test changes
* linting
* Delete .claude directory
* Delete tests/evals directory
* fix: address PR review — guard missing tokens, quote shell paths, add proxy auth tests
* fix: restore authorship, branch_name support, and installation token for PR creation
* linitng
* fix: move installation token fetch before commit, clean up dead proxy validation code
* feat: stop auto-cloning and let agent manage repo setup [closes OPE-21]
* feat: stop auto-cloning and let agent manage repo setup [closes OPE-21]
* fix: address review feedback — restore agents_md, add git user config, lint fixes
* fix: drop github_token arg from sandbox creation, use generic create_sandbox factory with langsmith-only proxy config
* fix: use _get_langsmith_api_key() for prod key fallback, warn when API key missing for proxy config
* linting
* linting
* feat: add installation token auth to list_repos GitHub API call
* agents.md update
* linting
* fix: address PR review feedback — shell precedence bug in prompt, remove dead code
* linting
* Apply suggestion from @bracesproul
Co-authored-by: Brace Sproul <braceasproul@gmail.com>
* Apply suggestion from @bracesproul
Co-authored-by: Brace Sproul <braceasproul@gmail.com>
* fix: address PR review feedback — restore {working_dir} in prompt, remove clone code block
* fix:Extract check_or_recreate_sandbox utility from inline sandbox health check
* fix: address PR review feedback — async list_repos, restore template name, fix prompt colon
* fix: resolve merge conflicts with main, adopt deepagents v0.5.0a4 LangSmithSandbox
* linting
* yogesh/ope-21-stop-auto-cloning
* Update agent/tools/list_repos.py
Co-authored-by: Brace Sproul <braceasproul@gmail.com>
* Update agent/prompt.py
Co-authored-by: Brace Sproul <braceasproul@gmail.com>
* feat: address PR review — list_repos uses GitHub API only, PR trigger includes org/repo
* linting
* feat: address PR review feedback — list_repos pagination, simpler return, sandbox health check
* feat: support listing repos for personal user accounts via is_organization flag
---------
Co-authored-by: Brace Sproul <braceasproul@gmail.com>
59 lines
2.4 KiB
Python
59 lines
2.4 KiB
Python
import logging
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
from ..utils.github_app import get_github_app_installation_token
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def list_repos(
|
|
organization_name: str,
|
|
is_organization: bool = True,
|
|
page: int = 1,
|
|
per_page: int = 100,
|
|
sort: str = "updated",
|
|
name_filter: str | None = None,
|
|
) -> dict[str, Any]:
|
|
"""List GitHub repositories for an organization or user via the GitHub API.
|
|
|
|
Uses /orgs/{name}/repos for organizations and /users/{name}/repos for
|
|
personal user accounts, based on the is_organization flag.
|
|
|
|
Args:
|
|
organization_name: The GitHub organization or username to list repos for.
|
|
is_organization: If True, uses the /orgs/ endpoint. If False, uses the
|
|
/users/ endpoint for personal accounts. Default: True.
|
|
page: Page number to fetch (default: 1).
|
|
per_page: Number of repos per page, max 100 (default: 100).
|
|
sort: Sort field — "updated", "created", "pushed", or "full_name" (default: "updated").
|
|
name_filter: Optional substring to filter repo names by (case-insensitive).
|
|
|
|
If unsure which repo to use, ask the user for confirmation.
|
|
"""
|
|
try:
|
|
headers = {"Accept": "application/vnd.github+json"}
|
|
token = await get_github_app_installation_token()
|
|
if token:
|
|
headers["Authorization"] = f"Bearer {token}"
|
|
path_prefix = "orgs" if is_organization else "users"
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.get(
|
|
f"https://api.github.com/{path_prefix}/{organization_name}/repos",
|
|
headers=headers,
|
|
params={"per_page": min(per_page, 100), "sort": sort, "page": page},
|
|
timeout=10,
|
|
)
|
|
if response.status_code == 200:
|
|
repos: list[str] = [r["name"] for r in response.json()]
|
|
if name_filter:
|
|
repos = [r for r in repos if name_filter.lower() in r.lower()]
|
|
|
|
has_next = 'rel="next"' in response.headers.get("link", "")
|
|
result: dict[str, Any] = {"repos": repos, "page": page, "has_next_page": has_next}
|
|
return result
|
|
return {"error": f"GitHub API returned status {response.status_code}"}
|
|
except Exception:
|
|
logger.warning("Failed to fetch repos for %s", organization_name)
|
|
return {"error": f"Failed to fetch repos for {organization_name}"}
|