Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions codeflash/api/cfapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,18 @@ def make_cfapi_request(
return response


@lru_cache(maxsize=1)
def get_user_id_minimal(api_key: str) -> bool:
response = make_cfapi_request(
endpoint="/cli-get-user",
method="GET",
extra_headers={"cli_version": __version__},
api_key=api_key,
suppress_errors=True,
)
return response.status_code == 200


@lru_cache(maxsize=1)
def get_user_id(api_key: Optional[str] = None) -> Optional[str]: # noqa: PLR0911
"""Retrieve the user's userid by making a request to the /cfapi/cli-get-user endpoint.
Expand Down Expand Up @@ -297,6 +309,26 @@ def create_staging(
return make_cfapi_request(endpoint="/create-staging", method="POST", payload=payload)


def setup_github_actions(
owner: str, repo: str, base_branch: str, workflow_content: str, api_key: str | None = None
) -> Response:
"""Set up GitHub Actions workflow by creating a PR with the workflow file and optionally setting up the repository secret.

:param owner: Repository owner (username or organization)
:param repo: Repository name
:param base_branch: Base branch to create PR against (e.g., "main", "master")
:param workflow_content: Content of the GitHub Actions workflow file (YAML)
:param api_key: API key to store as repository secret (if provided, will attempt to set up secret automatically)
:return: Response object with pr_url, pr_number, secret_setup_success, and secret_setup_error on success
"""
payload = {"owner": owner, "repo": repo, "baseBranch": base_branch, "workflowContent": workflow_content}
# Include apiKey in payload if provided - this will be encrypted and stored as a repository secret
if api_key:
payload["apiKey"] = api_key

return make_cfapi_request(endpoint="/setup-github-actions", method="POST", payload=payload, api_key=api_key)


def is_github_app_installed_on_repo(owner: str, repo: str, *, suppress_errors: bool = False) -> bool:
"""Check if the Codeflash GitHub App is installed on the specified repository.

Expand Down
207 changes: 207 additions & 0 deletions codeflash/cli_cmds/assets/style.tcss
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/* Main stylesheet for CodeFlash TUI */

$codeflash-primary: #2563EB;
$codeflash-primary-light: #3B82F6;
$codeflash-primary-dark: #1D4ED8;
$codeflash-accent: #FFC143;
$codeflash-text-dark: #373A3D;
$codeflash-surface-light: #F8FAFC;
$codeflash-surface-dark: #1E293B;

Screen {
align: center middle;
}

.center_container {
width: 90;
height: auto;
padding: 2 4;
align: center middle;
content-align: center middle;
}

.logo {
color: $codeflash-accent;
text-align: center;
text-style: bold;
margin-bottom: 1;
}

.title {
text-align: center;
text-style: bold;
color: $codeflash-primary;
margin-bottom: 1;
}

.screen_title {
text-align: center;
text-style: bold;
color: $codeflash-primary-light;
margin-bottom: 1;
text-style: bold underline;
}

.description {
color: $text;
margin-bottom: 2;
text-align: center;
}

.label {
margin-bottom: 1;
color: $text;
text-style: bold;
}

Input {
margin-bottom: 2;
width: 100%;
}

.button_row {
width: 100%;
height: auto;
align: center middle;
}

Button {
margin: 0 1;
}

RadioSet {
margin-bottom: 2;
padding: 0;
border: none;
width: 100%;
align: center middle;
content-align: center middle;
layout: vertical;
}

RadioButton {
width: auto;
min-width: 0;
max-width: 30;
margin: 0;
align: center middle;
}

Select {
margin-bottom: 2;
width: 100%;
}

Checkbox {
margin-bottom: 2;
width: 100%;
align: center middle;
}

.hidden {
display: none;
}

.info_section {
color: $text;
margin-bottom: 1;
}

.action_section {
margin-top: 1;
margin-bottom: 1;
padding: 1 0;
align: center middle;
}

.action_section Button {
width: 100%;
content-align: center middle;
}

.action_section Checkbox {
width: 100%;
content-align: center middle;
}

Vertical {
width: 100%;
height: auto;
}

.status_text {
text-align: center;
margin: 1 0;
text-style: bold;
}

.subtitle {
text-align: center;
color: $text-muted;
margin-bottom: 2;
}

.config_section, .commands_section {
margin-bottom: 2;
padding: 1 2;
background: $codeflash-surface-dark;
}

.warning_section {
margin-bottom: 2;
padding: 1 2;
background: $surface;
}

.section_header {
text-style: bold;
color: $codeflash-accent;
margin-bottom: 1;
}

.section_content {
color: $text;
padding-left: 2;
}

.warning_text {
color: $warning;
text-style: bold;
width: 100%;
}

/* Directory tree selector styles */
.path-controls {
height: 3;
margin: 0 0 1 0;
width: 100%;
}

.path-controls Input {
width: 1fr;
margin: 0;
}

.path-controls Button {
width: auto;
min-width: 6;
margin: 0;
padding: 0 1;
}

DirectoryTree {
width: 100%;
height: 15;
margin-bottom: 2;
}

.centered_single_button {
width: 100%;
height: auto;
align: center middle;
margin-bottom: 2;
}

.centered_single_button Button {
width: auto;
}
Loading