Install
openclaw skills install propel-code-review-smoke-1773429953Run async diff-based code reviews using the Propel Review API, poll for completion, retrieve structured findings, and send comment feedback. Use when reviewi...
openclaw skills install propel-code-review-smoke-1773429953Use this guide to interact with the Propel Review API from an AI agent. Always target the production API unless told otherwise.
Run async, diff-based code reviews via the production API and retrieve comments.
Before rollout to a new workspace/repo, run this from the target repository root:
plugins/propel-code-review/skills/propel-code-review/scripts/smoke_test_permissions.sh
It validates:
Before making any API call, check whether PROPEL_API_KEY is set:
if [ -n "$PROPEL_API_KEY" ]; then echo "PROPEL_API_KEY is set"; else echo "PROPEL_API_KEY is not set"; fi
If the variable is empty, unset, or you just received a 401/403 from the Review
API, do not attempt any API calls with the current value. Follow these steps
to capture a fresh token — each step is a separate action:
Step 1 — Tell the user and open the browser. Send this message and run the Bash command in the same response (in parallel):
Message to user:
PROPEL_API_KEYis not set. Opening the token creation page: https://app.propelcode.ai/administration/settings?tab=review-api-tokens&token_name=Claude+Code&scopes=reviews:read,reviews:write The name and scopes are pre-filled. Click Create token, copy it, and paste it here.
Bash command:
URL="https://app.propelcode.ai/administration/settings?tab=review-api-tokens&token_name=Claude+Code&scopes=reviews:read,reviews:write"
if command -v xdg-open >/dev/null; then xdg-open "$URL"; else open "$URL"; fi
Step 2 — Wait for the user to paste the token. Do not proceed until the user
pastes a value starting with rev_. If the value doesn't start with rev_, tell
them it doesn't look valid and ask them to try again.
Step 3 — Once you have a valid token, persist it and load it into the session.
Run this in a single Bash call (replace <TOKEN> with the actual token):
case "$SHELL" in */zsh) SHELL_RC="$HOME/.zshrc" ;; */bash) SHELL_RC="$HOME/.bashrc" ;; *) SHELL_RC="" ;; esac; if [ -z "$SHELL_RC" ] && [ -f "$HOME/.zshrc" ]; then SHELL_RC="$HOME/.zshrc"; fi; if [ -z "$SHELL_RC" ] && [ -f "$HOME/.bashrc" ]; then SHELL_RC="$HOME/.bashrc"; fi; if [ -n "$SHELL_RC" ]; then printf '\n# Propel Review API token\nexport PROPEL_API_KEY="%s"\n' "<TOKEN>" >> "$SHELL_RC" && echo "Saved to $SHELL_RC"; else echo "No shell profile found"; fi; export PROPEL_API_KEY="<TOKEN>"
Tell the user where the key was saved (e.g. "Saved to ~/.zshrc").
Step 4 — Continue with the review workflow.
If you prefer to set the token yourself ahead of time:
export PROPEL_API_KEY="rev_..."
The token must be a Review API token (scoped to both reviews:write and reviews:read).
https://api.propelcode.ai
Use a bearer token in the Authorization header:
Authorization: Bearer $PROPEL_API_KEY
Do not assume any other Review APIs exist. Only use the async endpoints below.
POST /v1/reviews
Request body:
{
"diff": "string (required)",
"repository": "string (required)",
"base_commit": "string (required)",
"head_commit_sha": "string (optional)",
"branch": "string (optional)"
}
Constraints:
diff max size: 1,000,000 bytesrepository max length: 255base_commit max length: 255head_commit_sha max length: 255branch max length: 255Notes:
base_commit should be a commit that exists in the remote repo history
(typically the base commit of the branch you are reviewing).repository should be the canonical repo slug (for example, owner/repo)
derived from the git remote URL.Response (202):
{
"review_id": "uuid",
"status": "queued",
"repository": "owner/repo",
"base_commit": "sha",
"created_at": "...",
"updated_at": "..."
}
GET /v1/reviews/:review_id
Response (200):
{
"review_id": "uuid",
"status": "queued|running|completed|failed",
"poll_after_ms": 3000,
"comments": [
{
"comment_id": "string",
"file_path": "path",
"line": 123,
"message": "...",
"severity": "error|warning|info"
}
],
"error": {
"code": "generation_failed",
"message": "..."
}
}
POST /v1/reviews/:review_id/comments/feedback
Request body:
{
"comment_id": "string (required)",
"incorporated": true,
"notes": "string (optional)"
}
Response (200):
{
"review_id": "uuid",
"comment_id": "string",
"incorporated": true
}
Use the helper scripts in scripts/ instead of ad-hoc inline curl loops.
Paths below are relative to this skill directory:
scripts/create_review.sh wraps POST /v1/reviews.scripts/poll_review.sh wraps polling GET /v1/reviews/:review_id until
terminal status (completed or failed) or timeout.scripts/post_comment_feedback.sh wraps
POST /v1/reviews/:review_id/comments/feedback.If your client supports prefix-based trust/approval, approve these once before running this skill:
scripts/create_review.shscripts/poll_review.shscripts/post_comment_feedback.shgit diffgit rev-parsegit remote get-urlgh pr viewjqBASE_BRANCH=$(gh pr view --json baseRefName -q '.baseRefName' 2>/dev/null || git remote show origin | sed -n '/HEAD branch/s/.*: //p')git rev-parse "$BASE_BRANCH"git rev-parse HEADgit rev-parse --abbrev-ref HEADgit remote get-url origin | sed -E 's#(git@github.com:|https://github.com/)##; s/\\.git$//'git diff "$BASE_BRANCH" > /tmp/review_api.diffscripts/create_review.sh with diff, base commit, repository slug, head commit, and branch.401/403: token invalid/expired/missing scope. Stop and ask user to refresh token.404: repository is not connected to the Propel workspace (or slug is wrong). Stop and ask user to connect/fix repo slug.400/413: invalid request or diff too large. Stop and show actionable fix.5xx: transient API error. Retry with bounded backoff, then stop and report if still failing.scripts/poll_review.sh until status is completed or failed.
The script keeps the existing 15 minute timeout budget, and honors
poll_after_ms from the API when present.scripts/post_comment_feedback.sh for each comment with
comment_id, incorporated true/false, and brief notes explaining the
decision. Do not wait for user confirmation.BASE_BRANCH=$(gh pr view --json baseRefName -q '.baseRefName' 2>/dev/null || git remote show origin | sed -n '/HEAD branch/s/.*: //p')
BASE_COMMIT=$(git rev-parse "$BASE_BRANCH")
HEAD_COMMIT=$(git rev-parse HEAD)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
REPO_SLUG=$(git remote get-url origin | sed -E 's#(git@github.com:|https://github.com/)##; s/\\.git$//')
git diff "$BASE_BRANCH" > /tmp/review_api.diff
CREATE_RESPONSE=$(
scripts/create_review.sh \
--diff-file /tmp/review_api.diff \
--repo "$REPO_SLUG" \
--base-commit "$BASE_COMMIT" \
--head-commit-sha "$HEAD_COMMIT" \
--branch "$BRANCH"
)
REVIEW_ID=$(echo "$CREATE_RESPONSE" | jq -r '.review_id // empty')
if [ -z "$REVIEW_ID" ]; then
echo "$CREATE_RESPONSE"
exit 1
fi
scripts/poll_review.sh \
--review-id "$REVIEW_ID" \
--max-attempts 30 \
--sleep-seconds 30 \
--output-file /tmp/review_api.result.json
# The poller uses the 30x30s budget above, but will follow API-provided
# poll_after_ms hints when the server returns them.
cat /tmp/review_api.result.json
# Example feedback posts after deciding incorporate true/false per comment.
jq -c '.comments[]?' /tmp/review_api.result.json | while read -r comment; do
COMMENT_ID=$(echo "$comment" | jq -r '.comment_id // empty')
if [ -z "$COMMENT_ID" ]; then
continue
fi
scripts/post_comment_feedback.sh \
--review-id "$REVIEW_ID" \
--comment-id "$COMMENT_ID" \
--incorporated true \
--notes "Applied in this branch."
done
401/403 — re-run the pre-flight check above. The token may be missing,
expired, or missing scopes. Guide the user to generate a new one at:
https://app.propelcode.ai/administration/settings?tab=review-api-tokens&token_name=Claude+Code&scopes=reviews:read,reviews:write404 {"error":"Repository not found"} — the repository string does not match
a repo connected to the account. Treat this as an access/config problem, not a retryable failure.413 — the diff exceeded the 1,000,000 byte limit.If review creation returns 401, 403, or 404, do all of the following:
401/403: "refresh token and confirm reviews:read + reviews:write scopes".404: "connect this repository in Propel workspace, or correct owner/repo slug".https://api.propelcode.ai until told otherwise.scripts/create_review.sh, scripts/poll_review.sh, and
scripts/post_comment_feedback.sh instead of inline curl commands.comment_id from the review response (no user confirmation required).