Skip to content

feat(cli): add event protocol and GitHub context adapter#23

Merged
Abdulmuiz44 merged 1 commit into
mainfrom
feat/codra-cli-event-protocol-github-context
Jun 2, 2026
Merged

feat(cli): add event protocol and GitHub context adapter#23
Abdulmuiz44 merged 1 commit into
mainfrom
feat/codra-cli-event-protocol-github-context

Conversation

@Abdulmuiz44
Copy link
Copy Markdown
Collaborator

  • Adds Codra CLI foundation with codra run --task .
  • Adds JSONL event protocol for agent runs.
  • Adds GitHub Actions context adapter for PR/issue metadata.
  • Adds local git fallback context.
  • Implements deterministic review-pr, explain-issue, and summarize-context task runners.
  • Does not call AI providers or require API keys.
  • Prepares Codra for future GitHub Action and interactive bot phases.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28d4d71c14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


fn build_pr_summary(pr: &crate::context::types::CodraPullRequestContext) -> Value {
let title = pr.title.as_deref().unwrap_or("(no title)");
let file_count = pr.changed_files.as_ref().map(|f| f.len()).unwrap_or(0);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Report missing PR stats as unknown

When this runs without GITHUB_TOKEN (documented as optional) or when API enrichment fails, pr.changed_files stays None, but this path reports Changed files: 0 (+0/-0) for an actual PR. That corrupts the review summary and can hide large/high-risk changes; treat missing enrichment as unknown or use counts available from the webhook/API response instead of defaulting to zero.

Useful? React with 👍 / 👎.

.push("GitHub API: failed to fetch pull request details".to_string());
}

let files_url = format!("{base}/pulls/{number}/files?per_page={MAX_CHANGED_FILES}");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Fetch all paginated PR files

For PRs touching more than 100 files, this request only reads page 1, so changedFiles, totals, and risk detection silently omit the rest of the diff. GitHub documents this endpoint as paginated with per_page max 100 and a page parameter (https://docs.github.com/en/rest/pulls/pulls#list-pull-requests-files), so the adapter should either follow pagination or clearly mark the result as truncated.

Useful? React with 👍 / 👎.

if p.len() <= MAX_PATCH_LEN {
p.to_string()
} else {
format!("{}… [truncated]", &p[..MAX_PATCH_LEN])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid byte slicing patch text

When a fetched patch or diff exceeds 32 KB and byte 32000 lands inside a non-ASCII UTF-8 character, this slice panics because Rust string indices must be character boundaries. That makes the whole CLI fail on otherwise valid PRs containing long Unicode diffs; truncate via char_indices or another boundary-safe method instead.

Useful? React with 👍 / 👎.

for marker in ["ghp_", "github_pat_", "Bearer ", "Authorization:"] {
if let Some(idx) = out.find(marker) {
let end = out[idx..]
.find(|c: char| c.is_whitespace() || c == '\n')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Redact credentials after auth markers

If a logged error contains a standard header like Authorization: Bearer ghs_..., this delimiter search stops at the space inside the marker itself, so only Bearer/Authorization: is replaced and the token remains in the warning or failure message. Since this helper is used before emitting errors, redact through the credential value (and cover GitHub ghs_ tokens) rather than stopping at the marker's first whitespace.

Useful? React with 👍 / 👎.

Comment on lines +129 to +131
"issue_comment" => {
if let Some(issue) = payload.get("issue") {
merge_issue(ctx, issue);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the triggering issue comment

For issue_comment workflows without GITHUB_TOKEN (which the README says is optional), the event payload already includes the comment that triggered the run, but this branch only copies the issue object and leaves issue.comments empty. As a result explain-issue reports zero comments and omits the user's actual request/comment body unless API enrichment succeeds; parse the payload's comment field into the context before relying on the comments API.

Useful? React with 👍 / 👎.

@Abdulmuiz44 Abdulmuiz44 merged commit 3b0eded into main Jun 2, 2026
1 check passed
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.

1 participant