Skip to content
Merged
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
59 changes: 45 additions & 14 deletions crates/mesh-llm-commands/src/setup/github_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::process::{Command, Stdio};
use std::thread;
use std::time::{Duration, Instant};

const GITHUB_REPOSITORY: &str = "Mesh-LLM/mesh-llm";
const GH_COMMAND_TIMEOUT: Duration = Duration::from_secs(10);
const GH_POLL_INTERVAL: Duration = Duration::from_millis(25);

Expand All @@ -20,20 +19,21 @@ impl GhCommand {
const fn args(self) -> &'static [&'static str] {
match self {
Self::CheckAvailability => &["--version"],
Self::CheckAuthentication => {
&["auth", "status", "--active", "--hostname", "github.com"]
}
Self::CheckAuthentication => &["api", "--hostname", "github.com", "/user", "--silent"],
Self::CheckViewerHasStarred => &[
"repo",
"view",
GITHUB_REPOSITORY,
"--json",
"viewerHasStarred",
"api",
"--hostname",
"github.com",
"graphql",
"-f",
"query=query { repository(owner: \"Mesh-LLM\", name: \"mesh-llm\") { viewerHasStarred } }",
"--jq",
".viewerHasStarred",
".data.repository.viewerHasStarred",
],
Self::StarRepository => &[
"api",
"--hostname",
"github.com",
"--method",
"PUT",
"/user/starred/Mesh-LLM/mesh-llm",
Expand All @@ -45,11 +45,11 @@ impl GhCommand {
pub(crate) const fn display_name(self) -> &'static str {
match self {
Self::CheckAvailability => "gh --version",
Self::CheckAuthentication => "gh auth status --active --hostname github.com",
Self::CheckViewerHasStarred => {
"gh repo view Mesh-LLM/mesh-llm --json viewerHasStarred --jq .viewerHasStarred"
Self::CheckAuthentication => "gh api --hostname github.com /user --silent",
Self::CheckViewerHasStarred => "gh api --hostname github.com graphql <star query>",
Self::StarRepository => {
"gh api --hostname github.com --method PUT /user/starred/Mesh-LLM/mesh-llm --silent"
}
Self::StarRepository => "gh api --method PUT /user/starred/Mesh-LLM/mesh-llm --silent",
}
}
}
Expand Down Expand Up @@ -155,3 +155,34 @@ impl GhCommandRunner for ProcessGhCommandRunner {
}
}
}

#[cfg(test)]
mod tests {
use super::GhCommand;

#[test]
fn github_api_commands_are_pinned_to_dot_com() {
for command in [
GhCommand::CheckAuthentication,
GhCommand::CheckViewerHasStarred,
GhCommand::StarRepository,
] {
assert!(
command
.args()
.windows(2)
.any(|args| args == ["--hostname", "github.com"]),
"{} must explicitly target github.com",
command.display_name()
);
}
}

#[test]
fn authentication_probe_checks_the_selected_api_credential() {
assert_eq!(
GhCommand::CheckAuthentication.args(),
&["api", "--hostname", "github.com", "/user", "--silent"]
);
}
}
16 changes: 10 additions & 6 deletions crates/mesh-llm-commands/src/setup/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub(crate) fn print_setup_summary(plan: &SetupPlan, actions: &CliSetupActions<'_
eprintln!("- Runtime: {}", runtime_summary(plan, actions));
eprintln!("- Service: {}", service_summary(plan, actions));
eprintln!(
"- GitHub: {}",
"- GitHub star: {}",
super::github::github_summary(plan, &actions.github_outcome)
);
return;
Expand All @@ -55,7 +55,7 @@ pub(crate) fn print_setup_summary(plan: &SetupPlan, actions: &CliSetupActions<'_
eprintln!(" Runtime {}", runtime_brief(plan, actions));
eprintln!(" Service {}", service_brief(plan, actions));
if let Some(github) = github_brief(actions) {
eprintln!(" GitHub {github}");
eprintln!(" GitHub star {github}");
}
}

Expand Down Expand Up @@ -170,8 +170,12 @@ fn github_brief(actions: &CliSetupActions<'_>) -> Option<String> {
| super::github::SetupGitHubOutcome::EligibilityCheckFailed(_) => {
Some(style_warn("not starred"))
}
super::github::SetupGitHubOutcome::CliUnavailable => Some(style_muted("gh unavailable")),
super::github::SetupGitHubOutcome::NotAuthenticated => Some(style_muted("gh signed out")),
super::github::SetupGitHubOutcome::CliUnavailable => {
Some(style_muted("skipped; gh unavailable"))
}
super::github::SetupGitHubOutcome::NotAuthenticated => {
Some(style_muted("skipped; gh not authenticated"))
}
Comment on lines +173 to +178

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Align the default summary with the specification.

github_brief prints skipped; gh unavailable and skipped; gh not authenticated in the non-verbose summary. docs/specs/mesh-setup-installer.md says exact GitHub skip reasons belong behind --verbose and does not list skipped outcomes in the default summary.

Either use a generic skipped value here, or update the specification to permit these exact reasons in default output.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/mesh-llm-commands/src/setup/summary.rs` around lines 173 - 178, Update
the github_brief handling of SetupGitHubOutcome::CliUnavailable and
SetupGitHubOutcome::NotAuthenticated to return a generic muted “skipped”
summary, keeping the specific skip reasons available only through verbose output
and preserving the specification’s default-summary behavior.

super::github::SetupGitHubOutcome::NotEvaluated => Some(style_muted("not recorded")),
_ => None,
}
Expand Down Expand Up @@ -225,7 +229,7 @@ mod tests {

assert_eq!(
github_brief(&actions).map(|brief| strip_ansi_styles(&brief)),
Some("gh unavailable".to_string())
Some("skipped; gh unavailable".to_string())
);
}

Expand All @@ -235,7 +239,7 @@ mod tests {

assert_eq!(
github_brief(&actions).map(|brief| strip_ansi_styles(&brief)),
Some("gh signed out".to_string())
Some("skipped; gh not authenticated".to_string())
);
}
}
2 changes: 1 addition & 1 deletion docs/specs/mesh-setup-installer.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ After successful core setup, an interactive setup may offer to star
Eligibility:

- `gh` is on PATH
- `gh auth status --active --hostname github.com` succeeds
- `gh api --hostname github.com /user --silent` succeeds using the account selected by `gh`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- target lines ---'
sed -n '105,122p' docs/specs/mesh-setup-installer.md
printf '%s\n' '--- related gh wording ---'
rg -n -C 2 'GH_TOKEN|GITHUB_TOKEN|selected by `gh`|credential resolved|gh api.*github.com' docs .github README.md 2>/dev/null || true
printf '%s\n' '--- tracked credential-like files ---'
git ls-files | rg '(^|/)(\.env(\.|$)|.*(credential|token|secret|key).*)' || true

Repository: Mesh-LLM/mesh-llm

Length of output: 7055


🌐 Web query:

GitHub CLI gh help environment GH_TOKEN GITHUB_TOKEN precedence github.com stored authentication

💡 Result:

When using the GitHub CLI (gh), authentication tokens provided via environment variables take precedence over credentials stored in the local system configuration [1][2]. For commands targeting github.com or subdomains of ghe.com, the CLI checks for environment variables in the following order of precedence: 1. GH_TOKEN [1][2] 2. GITHUB_TOKEN [1][2] If neither of these variables is set, the CLI falls back to using stored credentials from the system's authentication configuration [1][2]. For commands targeting a GitHub Enterprise Server (GHES) instance, the CLI checks: 1. GH_ENTERPRISE_TOKEN [2][3] 2. GITHUB_ENTERPRISE_TOKEN [2][3] If these are not set, it will subsequently fall back to checking GH_TOKEN and GITHUB_TOKEN (in that order), and finally, it will use stored credentials if available [2][4]. Key points regarding this behavior: - Explicit Precedence: The GH-prefixed variables (e.g., GH_TOKEN) always take precedence over their GITHUB-prefixed counterparts (e.g., GITHUB_TOKEN) [5]. - Automation: Setting an environment variable avoids interactive authentication prompts and ensures the specified token is used for the command's duration [1][6]. - Stored Credentials: Stored credentials are managed via gh auth login and reside in the system's secure credential store (or a plain-text fallback file) [6][7]. Environment variables override these stored values, making them ideal for headless or CI/CD environments [6][8].

Citations:


Describe the credential source precisely.

gh api uses GH_TOKEN or GITHUB_TOKEN before stored credentials for github.com. Replace “the account selected by gh” with “the credential resolved by gh for github.com.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/specs/mesh-setup-installer.md` at line 115, Update the credential-source
statement in the documentation to say that the command succeeds using the
credential resolved by gh for github.com, replacing the inaccurate reference to
the account selected by gh.

- the authenticated viewer has not already starred the repo
- a visible interactive prompt is shown

Expand Down
Loading