Skills & Commands¶
Each command wraps the whole sequence — create or resume the session, upload the diff, call the tool, report the result — so you invoke one command and get a clean report.
Command names below are Claude Code's. The capabilities are the same in every client; only how you invoke them differs. See your client's page under Supported Coding Agents.
All of them share three properties:
- Single-shot. One call, report the output, done. No hidden retry loop.
- Pre-commit by default. The diff is your working tree against the baseline, including untracked files. The three review commands and
/cloudaeye:slop-scorecan also target one path or an open pull request — see What to review. - None of them edit your code. They report; you or the coding agent decide.
| Command | Purpose |
|---|---|
/cloudaeye:help |
List all available commands, or show how to use a specific command with its arguments, options, and examples. |
/cloudaeye:init |
Set up the current repository for CloudAEye review. Detects its provider, remote URL, and base branch, prompts for a monitor branch, and opens integration setup when needed. |
/cloudaeye:inspect |
Find bugs such as logic errors, missed edge cases, invalid inputs, concurrency problems, and broken code signatures. Returns an approval verdict and numbered findings with file locations and severity. |
/cloudaeye:security |
Find security issues across application code, LLMs, AI agents, and MCP tools, including secrets leaked in changed lines. Use for changes involving authentication, untrusted input, cryptography, prompts, or tool definitions. |
/cloudaeye:review |
Run all six report types in one comprehensive bug and security review. Use before opening a significant PR or when a large change needs more than the routine bug check. |
/cloudaeye:describe |
Turn the pending change into a Markdown description and a list of important changes for a PR body or commit message. Uses repository context to explain the impact across files. |
/cloudaeye:control-flow |
Draw sequence diagrams showing calls the change added, removed, redirected, or moved. Identifies affected callers in other connected repositories so you can see how the change alters execution flow. |
/cloudaeye:review-arch |
Show how a change affects the system architecture, repository layers, and dependencies through three diagrams. Reports architecture findings, cross-repository impact, and questions for a senior review. |
/cloudaeye:ask |
Answer questions about the pending change. Ask what else calls a function, how it behaved before, or where a similar pattern is used. |
/cloudaeye:check-task |
Verify whether the pending change fulfills a Jira ticket, GitHub issue, or written specification. Returns a DONE, PARTIAL, or NOT DONE verdict with details of missing work. |
/cloudaeye:check-pr |
Check an open PR's docstring and test coverage, README freshness, dependencies, title and description, duplicate code, and secrets. Runs the repository's configured checklist and posts the detailed report on the PR. |
/cloudaeye:implement |
Turn selected review findings into a fix plan. Identifies what to change, where to change it, and the affected callers, related defects, and tests. |
/cloudaeye:slop-score |
Assess how much manual review a change needs by checking nine code quality signals, including duplication, nonexistent APIs, dead code, missing tests, and overengineering. Returns a score out of 100 and its review band, with the findings behind them. |
/cloudaeye:risk-score |
Decide whether an open PR needs a human reviewer, why, and who to ask. Weighs the changed files' bug history, rework and ownership with the author's recent PRs and this PR's AI slop score, and posts the risk card on the PR when you agree. |
/cloudaeye:add-docs |
Generate docstrings for undocumented code in an open pull request and post them as review suggestions. Reports which suggestions were generated and which reached the PR. |
/cloudaeye:add-tests |
Generate unit tests for uncovered code in an open pull request, including new test files where needed. Posts the tests as review suggestions for you to review and run. |
/cloudaeye:explain |
Explain a Jira or GitHub issue using the code it touches. Describes the relevant components, their current behavior, and surrounding code so you can understand the work before implementing it. |
/cloudaeye:create-issue |
Turn selected findings from the last review into Jira tickets or GitHub issues, with an optional assignee and note. Returns ticket links and identifies findings already tracked in the same session. |
/cloudaeye:help¶
Lists the supported commands or explains how to use one command, using the documentation bundled with the installed plugin.
When to run: when you want to find the right command, check its options, or see an example before running it.
What you pass: an optional command name, such as inspect,
cloudaeye:inspect, or /cloudaeye:inspect. Omit it to list all commands.
There are no flags.
What it does: reads the installed plugin's README command table and, for command-specific help, the selected skill. It does not run the target command, fetch the website, or change files.
Output: the complete command table first, or a manual covering syntax, arguments, options, examples, output, and limitations. Unknown names or extra arguments return the supported command list.
Examples:
/cloudaeye:help
/cloudaeye:help inspect
/cloudaeye:help create-issue
/cloudaeye:help /cloudaeye:review
Help works without authentication, a Git repository, pending changes, or an MCP connection.
What to review¶
/cloudaeye:inspect, /cloudaeye:security, /cloudaeye:review and
/cloudaeye:slop-score take the same optional argument.
| Argument | Reviews |
|---|---|
| none | Every uncommitted change |
src/auth/ or src/auth/login.ts |
Only changes under that path |
#405 |
Open pull request 405 |
Digits mean a pull request; ./405 forces a path. A pull request must be open (drafts
count), merge into your integrated branch, not come from a fork, and change at most 50
files — anything else is refused with the reason.
Add --critical, --high, --medium or --low to any of the three review commands
for a severity floor: --high reports high and critical. The floor reaches the
scanner as well as the output, so it lowers cost rather than only shortening the list.
/cloudaeye:slop-score takes no floor — see why.
A scoped review speaks only for its scope — approve on src/auth/ means approved for
that path, and the report says so. Full detail in the User Guide.
/cloudaeye:inspect¶
The bug pass: logic errors, edge-case handling, input validation, error handling, concurrency safety, code signatures, naming consistency, code clarity, and syntax style — all from BUG_REPORT.
It runs no security checks. For the security surface, run /cloudaeye:security.
When to run: after finishing a coding task, before you commit. The policy snippet on the Claude Code page makes this part of "done".
What it does:
- Resets the per-invocation workspace and creates or resumes the session from your git identity.
- Uploads the diff. If it is empty, it reports "nothing to inspect" and stops.
- Calls the tool and reports the result.
Output: a verdict — approve or request_changes — and a numbered list of findings, each with file, line range, severity, category, and a message. If there are findings, Claude Code lists them and asks which you want fixed; it does not edit until you reply.
The numbers come from the server and are stable for that report — they are what you pass to /cloudaeye:implement.
Iterating: ask for specific fixes — by number, or via /cloudaeye:implement — and run it again. The server resolves the same session, so the review picks up where it left off — the agent notes which findings it addressed and which it left, so the second pass doesn't repeat the first.
/cloudaeye:security¶
The security surface, in full: SECURITY_REPORT (OWASP-style application security), LLM_SECURITY_REPORT, AIAGENT_SECURITY_REPORT, MCP_REPORT, and SECRET_REPORT — secrets leaked on the changed lines.
When to run: when the change touches authentication, untrusted input, secrets, crypto, deserialization, prompts, tool definitions, or agent orchestration — or any time you want the security read specifically.
Same flow, same output shape, and the same iteration behaviour as /cloudaeye:inspect. Only the scope differs.
/cloudaeye:review¶
Combines the bug checks from /cloudaeye:inspect with the full security coverage
of /cloudaeye:security in one review. Covers logic and correctness issues,
application vulnerabilities, LLM and agent security, MCP security, and leaked secrets.
When to run: before opening a significant PR, on a large change, or when you
want a comprehensive review of both correctness and security. For a routine bug
check, use /cloudaeye:inspect. For security alone, use /cloudaeye:security.
What you pass:
| Argument | What gets reviewed |
|---|---|
| nothing | The current working-tree change |
A file or directory, such as src/auth/ |
Only changes under that path |
A PR number, such as 405 or #405 |
That open pull request |
--critical, --high, --medium, or --low |
Combine with any mode to report that severity and higher |
Without a severity flag, no severity floor is requested. For example, --high
includes both high and critical findings. PR eligibility and path-selection rules
are described in What to review.
What it does: prepares the local diff, then reviews it across six report types.
LLM, agent, and MCP checks run where the code contains relevant evidence. This is a broader pass than either inspect or security alone and costs more and takes more time to complete.
Output: an approve or request_changes verdict, finding counts, and numbered
findings grouped by report type. Each finding includes its file, line, severity,
and an explanation of the issue.
A path scoped result identifies the reviewed scope and excluded changed files, approval applies only to that scope.
Iterating: use the finding numbers to select what to fix, or pass them to
/cloudaeye:implement [1,3] for a working-tree fix plan. Re run review after the
fixes.
Examples:
/cloudaeye:review
/cloudaeye:review src/auth/ --high
/cloudaeye:review #405 --critical
/cloudaeye:slop-score¶
Answers a different question from the three passes above: not is there a bug in this change but how much careful reading does this change need before it is merged. It scores nine signals of low-quality code over the diff, reports a score out of 100 and the band it falls in, and prints the findings behind it.
When to run: on a change you did not write line by line — one an agent generated, one you inherited, or one whose size does not look earned. It is also useful on a large change whose per-file review came back clean: "1,204 lines, 18 files, 6 behavioural edits" is a shape no per-file pass reports.
The nine signals¶
| Signal | What it looks for |
|---|---|
| Duplicate code | Logic copied within the change, or rewritten when the repository already had it |
| Hallucinated API | Calls, imports and environment variables that resolve nowhere |
| Dead code | Unused imports, unused parameters and private fields, unreachable branches, functions nothing calls |
| Missing tests | New public code no test names, assertions weakened, tests that restate the implementation |
| High complexity | Complexity and nesting this change added, not complexity it inherited |
| Generic naming | data, helper, process — names that carry no meaning |
| Boilerplate comments | Comments that restate the line beneath them |
| Overengineering | Wrappers that forward unchanged, abstractions with one caller |
| Style inconsistency | The change disagreeing with the conventions of the file it is editing |
Reported beside the score and contributing no points: the size of the change, how many changed functions carry a real behavioural edit, and documentation drift. Size is the denominator the other signals are measured against — a 1,200-line change is not slop, it is a 1,200-line change. Commit shape ("one enormous commit, generic message") needs a commit list a review session does not carry, so it is reported absent rather than clean.
Generated and vendored files — lockfiles, build output — are left out of all of it, and the card says so. They are the usual reason a "1,200 lines changed" headline overstates what a human has to read.
The score and its band¶
A score out of 100, higher meaning more to read carefully, and one of four bands:
Low likelihood of slop · Review recommended · High likelihood of low-quality code · Strong candidate for manual review before merge
The score is not calibrated yet, and the card says so. It is measured the same way on every change, so two changes compare fairly, but read it as a band with a position inside it rather than as a precise figure: what to do next depends on the band and on which signals drove it, not on whether a change scored 46 or 52.
The band describes review burden, never authorship. "Strong candidate for manual review" is a claim about a change. "This was AI-generated" is a claim about a person, and this command does not make it — it would be wrong about copy-pasted human work as often as it was right.
What to pass¶
/cloudaeye:slop-score every uncommitted change
/cloudaeye:slop-score src/auth/ only changes under that path
/cloudaeye:slop-score #405 open pull request 405
Same three modes and the same pull-request rules as the review commands — see What to review. A pull request's diff is fetched server-side, so there is nothing to upload and no working-tree diff is taken.
There is deliberately no severity flag. A floor drops findings before they are counted, so every signal's numerator would shrink while its denominator stayed put — the score would fall because less was reported, not because less was wrong.
What it costs¶
The scoring itself is arithmetic and costs nothing; what costs is the review underneath
it, which runs exactly the categories the score reads and none of the security checks.
Anything a previous /cloudaeye:review or /cloudaeye:inspect already worked out on
this same diff is reused rather than paid for again — so score-then-review and
review-then-score cost about the same, and scoring an unchanged change twice is nearly
free.
What comes back¶
Slop Score Card
Score 58 / 100 · Review recommended
Band lowered from "High likelihood of low-quality code" on review of the evidence: the duplicate blocks are three copies of one generated client stub
1,204 lines / 18 files changed; 6 of 41 changed functions carry a behavioural edit.
Not every signal could be measured; the rows below say which and why.
Duplicate code ██████░░░░ 3 findings
Hallucinated API ██░░░░░░░░ 1 finding, 4/6 detections
Dead code ████░░░░░░ 4 findings
Missing tests ████████░░ 5 findings
High complexity █░░░░░░░░░ 1 finding
Generic naming ░░░░░░░░░░ 0 findings
Boilerplate comments ███░░░░░░░ 2 findings
Overengineering —————————— no pre-edit snapshot was available
Style inconsistency ░░░░░░░░░░ 0 findings
Issues Found
High
2. Calls Invoice.recalculate_totals(), which is not defined anywhere
hallucinated_api · src/billing/invoice.py:88
Medium
5. Duplicates the tax rounding block from invoice.py
duplicate_code · src/billing/refund.py:12
7. New public function issue_partial_refund() has no test calling it
missing_tests · src/billing/refund.py:41
Low
1. Unused import: decimal.ROUND_UP
dead_code · src/billing/refund.py:3
Scores are not calibrated yet and may change as more merged pull requests are measured.
Four things on that card are worth knowing how to read:
- A row of dashes is not a clean row.
——————————means nothing looked at that signal, and the reason is printed beside it. It is left out of the score rather than counted as zero, and the header says that not every signal could be measured. 4/6 detectionsmeans the signal is scored on four of the six things it is defined to catch. It can only ever make a signal read lower than the change deserves.- A lowered or raised band names what it moved from and why. Without that line, the band is the arithmetic's own.
- The finding numbers are stable — they are what you type back at
/cloudaeye:implement.
What it is not¶
Low likelihood of slop is not an approval. These nine signals describe the shape
of a change, not its correctness — a change can be clean here and still be wrong. For bugs run
/cloudaeye:inspect; for the security surface,
/cloudaeye:security.
/cloudaeye:risk-score¶
Answers the question a reviewer asks before opening the diff: does this pull request need a careful human review, why, and who should do it. It weighs who wrote the change, what it touches, and what those files and that author have been through over the last few weeks, together with this pull request's own AI slop score. It returns a risk score out of 100 with its band, a recommendation, what needs attention, and who to ask.
When to run: on an open pull request, before you decide how carefully to review it, or to decide who should.
What it reads¶
| What it looks at | |
|---|---|
| The files | Bugs reported against them, how much of their recent code was already rewritten, whose code they are, and whose lines this pull request rewrites |
| The author | Their pull requests in the window: AI slop on them, bugs in lines they wrote, how much of their new code was soon rewritten, and setbacks (closed unmerged, reverted) |
| This pull request | Its AI slop score, and its test coverage when a CloudAEye PR checklist ran on this commit |
Every trend is one value a week across the window: the last 21 days by default, anything from 7 to 90. Each is printed with its direction and whether that direction is better or worse.
Where the bug history comes from¶
Bugs are the repository's GitHub issues and, when the CloudAEye Jira app is installed, the organisation's Jira bug tickets. Which files a bug was in is not something a tracker records, so CloudAEye works it out once per bug, from the pull request that fixed it or by searching the code, and leaves it on the issue or ticket as a short note: the repository, the files, and who wrote them. That happens in the background as bugs are filed, fixed and reopened, never during this command, which only reads those notes.
A bug with no note yet is counted on the card as not mapped and left out of the score. It is a gap in the evidence, never a clean history.
What to pass¶
/cloudaeye:risk-score #412 pull request 412, over the last 21 days
/cloudaeye:risk-score #412 30 the same, over the last 30 days
Pull requests only. Bugs, rework and the author's history live in the repository, and a working tree has none of them. The usual pull-request rules apply — see What to review.
What it writes¶
Nothing, unless you say so. After the card, Claude offers to post it on the pull request and does so only on a yes. It edits CloudAEye's earlier risk card there rather than adding a second, so a pull request carries one.
The posted card is also how CloudAEye remembers the pull request: its AI slop score and test coverage feed later cards about the same author. Posting it after each run is what builds that history.
What it costs¶
Reading the history is GitHub and Jira calls, typically tens of seconds. The only model spend is
the AI slop review of this pull request, and only when none exists for its current commit: a
/cloudaeye:slop-score already run on the commit, or a risk card already on the pull request
for it, is reused rather than paid for again.
What comes back¶
🛡️ Change risk
Author @dana
Overall risk score 🟠 46 / 100 · Medium
AI slop 🟡 41 / 100 · Review recommended · 5 findings: 3 missing tests · 2 duplicated blocks; no hallucinated APIs
Recommendation 🔍 Human review required: look at the AI slop findings for this commit (/cloudaeye:slop-score) before approving.
Suggested reviewer @priya, who wrote 31 of the lines this PR rewrites and 84% of src/billing/refund.py
What needs attention
🔴 AI slop in this PR: 41 / 100, Review recommended.
🟠 src/billing/refund.py keeps breaking. It had 2 bugs in the last 21 days (#388, #391). Getting worse.
🟡 This PR rewrites 31 lines by @priya.
Looks fine: their new code is stable · no reverts on these files.
The code, week by week (31 Aug–6 Sep → 7–13 Sep → 14–20 Sep)
🐞 Open bugs · src/billing/refund.py 0 → 1 → 2 ↑ worse 1 open, 2 in 21 days
🔁 New code already rewritten · refund.py 4% → 9% → 22% ↑ worse 22% · repository 11%
🧪 Changed functions with a test — not measured: no CloudAEye PR checklist with unit-test coverage at this commit
👤 Lines changed by others than the main author 20% → 35% → 41% ↑ worse @priya's share of refund.py 88% → 84%
@dana, week by week
🤖 AI slop on their PRs 22 → 30 → 41 ↑ worse this PR 41 / 100
🐞 Bugs in lines they wrote 0 → 0 → 1 ↑ worse 1 of 2 bugs in lines they wrote
📝 Their new code already rewritten — too little change to tell
🧪 Their functions with a test — not measured: the checklist gave no per-function coverage
📋 PR setbacks a week 0 → 0 → 0 → steady 3 merged · 0 closed unmerged · 0 reverted
Not measured: test coverage, because no CloudAEye PR checklist with unit-test coverage at this commit.
Scores are not calibrated yet and may change as more merged pull requests are measured. AI slop reviewed on this commit for this card.
How to read it:
- The verdict leads. Human review required or no extra review needed, the one next step,
and who to ask: whoever wrote the lines the change rewrites, then the changed files' main
authors. A name without
@is a git author with no linked GitHub account. - What needs attention is ranked, at most four lines, and each names a file, an issue or a pull request. A 🔴 line asks for a review on its own, whatever the score — which is how a Medium or even Low score can still come with human review required.
- Not measured is never clean. A tracker that could not be read, a coverage check that did not run, bugs not yet mapped to the code: each is named and left out of the score rather than counted as zero. With too little measured there is no band, and the recommendation asks for a review.
- AI slop that could not be measured means no automatic approval, for the same reason.
- The score is not calibrated yet, and the card says so. It is measured the same way on every pull request, so two of them compare fairly.
- The author rows are about pull requests, not a judgement of the person — counts and links.
What it is not¶
It finds no bugs in the change itself; for those run /cloudaeye:inspect
or /cloudaeye:review. No extra review needed says the change's history and
shape give no reason for a careful read. It does not say the code is correct.
/cloudaeye:control-flow¶
Draws what a change did to the order in which things get called — the flow the change touched, as a sequence diagram of how it stood before and how it stands after, with every call the change added, removed, redirected or moved marked on the picture. It opens with one sentence saying what the change did, and it ends, when the change reaches another connected repository, with who over there calls what was altered.
When to run: on a fix, before you open the PR. The mistake this exists to catch is the
one a diff hides best — a change that is correct line by line and put in the wrong place:
inside a loop it belonged outside, on one branch of an if when it belonged on both,
before a check instead of after it. That is usually caught in review by someone senior
reading carefully, or not caught at all. It is also the command to run when a reviewer asks
"what does this actually change about the flow?", and on any change that touches an API
another service calls.
What it draws¶
Every arrow is a call that exists. The messages and their order are read out of the repository's code graph, where every call site carries a line, not reconstructed from the patch — so the picture is a set of facts, and the one model call in the whole flow cannot add, remove or reorder a message. What that call contributes is judgement: which of the flows the change touched are worth drawing, what to name them, and the opening sentence.
The card, top to bottom:
- "This code change …" — one line, in one fixed shape on every card, saying what the change did to the flow. The model writes it from the marked calls; when it cannot, the server writes it from the counts, so it is never missing.
- The flow drawn, and why — an HTTP route handler, an entry point, or the highest caller of what changed.
- A facts table — how many calls before and after, how much of the change is not in the pictures, how many other flows were not drawn, and the cross-repository line.
- Before and After, as two diagrams, the same collaborators in the same columns so one can be tracked straight down the page. Two diagrams whenever the sequence moved; one when it did not, or when there was nothing to compare against — and the opening line says which, because those are opposite claims.
- On each arrow:
+added,-removed,~now calls something else, and!— the same call, still made, from a different place. A call moved into a loop runs once per iteration; one moved onto a branch stops running on the other. The card calls this out above the pictures when it finds one. It states the move and stops: whether the new place is wrong is a question about intent that nothing here can see. - A legend, built from what is on the card and nothing else.
A call the graph could not follow is drawn dashed, to the name it was called on
(WebChatbot -->> research_crew: kickoff()), rather than invented or dropped.
Cross-repository reach¶
When the change deletes or re-signs something another connected repository calls — a function it imports, or an endpoint it reaches over HTTP — the card ends with a section naming the caller, its file and line, and what changed for it. This is a claim about a different codebase, and the one kind of finding no per-file review could make.
Two joins. By symbol name, for any indexed language: a call in another repository to a name this change deleted or changed the signature of, confirmed by one model call so that a short name shared by coincidence is rejected. By HTTP endpoint: a route this change deleted or moved, matched against the URL another repository passes to its client. The route may be declared by annotation or registered by a call, and the client may pass its path directly, in an options object, or through a declared interface. Confirmed through the real mappers for:
| Language | Routes read from | Calls read from |
|---|---|---|
| Python | Flask, FastAPI, Django urls.py |
requests, httpx, aiohttp |
| JavaScript / TypeScript | Express, Fastify, NestJS | fetch, axios, RTK Query, Angular HttpClient |
| Java | Spring MVC, JAX-RS | RestTemplate, WebClient, OkHttp, Feign |
| Kotlin | Spring, Ktor | Retrofit, Ktor client |
| Go | net/http, Gin, Chi |
http.Get, http.NewRequest |
| C# | ASP.NET attribute routing | HttpClient |
| Ruby | Rails, Sinatra | Faraday, Net::HTTP |
The two sides are matched on the path, tolerant of a version or mount prefix one side
carries and the other does not (/v1/tenant/{id}/rules against /tenant/${id}/rules
sent through a client whose base URL supplies /v1). An exact match is reported high, a
prefix-tolerant one medium, and the table says which.
The footer says how many connected repositories were searched and how many were not: the scan covers a bounded number, and an empty result over part of a tenant is reported as that, never as a clean result over all of it.
What to pass¶
/cloudaeye:control-flow every uncommitted change
/cloudaeye:control-flow src/auth/ only changes under that path
/cloudaeye:control-flow #405 open pull request 405
Same three modes and the same pull-request rules as the review commands — see What to review. A pull-request run also returns a link to the pull request, and is the only kind that can post the card back to it: ask, and Claude confirms in one line before it does, because that writes where other people can see it.
What it costs¶
One model call per run, which chooses which flows to draw, names them and writes the opening line; the diagrams themselves are computed. Cross-repository search adds one confirm call and a graph read per connected repository. The context refresh every other command already performs is where the time goes; on a warm session this is a cache read.
What comes back¶
## Control flow
This code change adds research-task creation and private-document search to query
processing, plus vector-store initialization with document loading and splitting.
**`ROUTE /api/query`** — query research orchestration
| | |
|---|---|
| **Why this flow** | HTTP route handler |
| **Call sequence** | 7 -> 9 calls (`+3 -1`) |
| **Independent changes** | 9 of 21 changed functions, in 2 other flows — not in these diagrams |
| **Other flows** | 2 not drawn |
| **Cross-repository** | no affected consumers in 8 repositories · 12 not searched |
### Before
…a sequence diagram: app.py → WebChatbot, with `- create_research_task()` marked…
### After
…the same collaborators, with `+ create_web_research_task()`,
`+ create_document_research_task()` and `+ search_private_docs()` marked…
`+` added · `-` removed · dashed arrow = a call the map could not follow
Structure, not a trace: branches are shown, early exits are not.
The diagrams are standard mermaid and render on GitHub, in the artifact viewer, and in any markdown preview; Claude prints the fence as-is rather than redrawing it, because it is the same block that gets posted on the pull request.
Three things on that card are worth knowing how to read:
- "9 of 21 changed functions — not in these diagrams" is the number nothing else carries. Two arrows can be the whole change or a sixteenth of it, and the pictures alone cannot tell you which.
- "12 not searched" means the cross-repository scan did not cover every connected repository. The one that breaks may be among the twelve.
- A
!line above the pictures is the finding. Everything else on the card is description.
What it is not¶
Not a trace. alt shows branches, loop shows repeats, and neither shows early
returns or exceptions — the diagram is what the code is shaped like, not what it did at
runtime. Not a review: it makes no claim that the new order is right, only that it is
new. For whether the change is correct, run /cloudaeye:inspect.
/cloudaeye:review-arch¶
Reviews what a change did to the architecture — not whether the code is correct, but whether it fits: which layers and components it touches, every dependency it added with the ones that cross layers marked, what it reaches outside the process for the first time, and the questions a senior engineer would ask before merging it. It draws three pictures, widest first, so a reader who does not know the codebase can place the change before judging it.
When to run: before opening or merging a pull request that adds a dependency, a new module or an external system, or reaches across packages; when a reviewer asks "does this fit the design?"; and on any change you did not write line by line.
What it draws¶
The card, top to bottom:
- The verdict —
PASS,FINDINGSorFAIL— and the layers the change touched. - The system — your services and how they are wired, read from the files each
repository deploys with: Kubernetes manifests and ingress rules, Helm charts,
docker-compose, .NET Aspire hosts, and the URLs a build or a frontend's config calls.
It is drawn top to bottom the way a reference architecture is, a band per tier with its
title on the left: clients, the gateway, the services (grouped into domains where they
share a path), the platform services most others call, where state lives, and what is
called outside. The repository under review
is marked, and the path a request takes to reach it is drawn in blue. A
coverage:line says which repositories were not read, and why. - The repository — its layers stacked as a ladder, each naming its largest components; the databases, caches, queues and services it calls on the right; the services that call it on the left. Under the picture, a table of the layers and one of the features that cut across them.
- What the change did to the layers — every changed module under its layer and
component, and every dependency the change added (
+), removed (x) or added against the layer order (!), with[cache],[db],[queue]and the like marking a first call to a system outside the process. A picture of the same follows whenever a dependency crossed a layer: the layers as stacked blocks, each titled on the left with its rank, the changed components inside them, and each call labelled on its arrow — green added, red dashed against the layer order, amber leaving the process. - Findings, numbered, each with what it rests on.
- Across the tenant — which of your other repositories call this service, and whether anything this change deleted or re-signed is used by them.
- Worth a senior look — the questions — and a footer.
The system and repository pictures show the code before the change; only the last picture is the change. The layers and components come from the repository's architecture model, built from its code graph, and every edge is read out of that graph before and after the change — nothing is inferred from the diff text.
What it finds¶
| Finding | What it means |
|---|---|
| Layer direction | A dependency added against the layer order — a service module importing from the HTTP layer |
| Import cycle | Two modules that now depend on each other, where they did not before |
| New boundary | The first module in a layer — or in the whole repository — to call a database, cache, queue, HTTP service or model provider |
| Layer skipped | A controller reaching storage directly, where its peers go through the layer between |
| Undeclared dependency | A new external package no manifest declares and nothing else uses |
| New hub | A module this change pushed past the repository's norm for how many others depend on it |
| Convention | A file that departs from what its siblings doing the same job all do — a route without the auth check the other routes carry. Confirmed by a model call before it is reported |
| Breaks another repository | Something this change deleted or re-signed is called from another connected repository |
Every finding says what it rests on: a confidence and inferred for a direction finding on
layers the analysis worked out, proof for a cycle, confirmed for a convention the model
call agreed with, and measured for the rest. Only layers your repository declares can
fail a change — a finding on inferred layers is reported with its confidence beside it,
and never turns the verdict to FAIL.
The questions¶
Under Worth a senior look are the questions a reviewer would ask of this change, each raised by a measured fact rather than asked in general: a new cache on a request path (what happens when it is down?), an environment variable read that no deployment sets, a new public function on a module many others import, a persisted data model the change touched. A model call writes a short walk-through and answers what it can from the code; when it cannot, the questions are printed as questions.
What to pass¶
/cloudaeye:review-arch every uncommitted change
/cloudaeye:review-arch #412 open pull request 412
A pull request must be open, merge into your integrated branch, not come from a fork, and change at most 50 files. A pull-request run also returns a link, and is the only kind that can post the card back: ask — "post it on the PR" — and Claude confirms in one line before it does, because that writes where other people can see it. The posted comment is the same review drawn for GitHub: the pictures with brand icons and a legend under each, the findings and questions as tables, and the plain card in a collapsed section at the end.
What it costs¶
Two model calls a review — one confirms convention candidates, one writes the walk-through and answers the questions. The pictures, the edges and every other finding are computed. The first review of a repository also names its components and layers, once, in the background: that review names components by their directory and says so, and the next one has names. The system picture is read from your deployment files and cached for a day.
What comes back¶
From a small example repository with no deployment files, so the card opens at the change:
Architecture -- working tree Cache order reads
Verdict: FINDINGS (3) layers: delivery -> service -> storage
What the change did
delivery api / api/routes.py
api/routes.py --+--> service/services . services/cache.py
service services / services/cache.py (+ new)
services/cache.py --+--> [cache] new boundary
services / services/orders.py
services/orders.py --!--> delivery/api . api/routes.py UPWARD
closes a cycle with api/routes.py
+ added x removed ! violation [ ] boundary
### What the change did to the layers
…the layers as stacked blocks, the new cache component in the service layer, a green
arrow into it, a red dashed arrow back up to the routes, and the cache on a row of its
own, outside the process…
Findings
1. [high] service -> delivery: `services/orders.py` now depends on `api/routes.py` [1.00 · inferred]
No other service module reaches delivery. Both layers are inferred, not declared.
2. [high] import cycle: `services/orders.py` <-> `api/routes.py` [1.00 · proof]
It did not exist before this change.
3. [medium] first module in `service` to call cache: `services/cache.py` [measured]
No other module in the repository does — this is the first cache dependency it has.
Pattern check: 1 candidate, 0 confirmed.
Pre-existing violations in touched files: 0. Model: current.
The diagrams are standard mermaid and render on GitHub and in any markdown preview; Claude prints the card as-is rather than redrawing it.
Three things on a card are worth knowing how to read:
Pre-existing violations in touched files: N— the review grades the change, not the repository. A clean card over a large N is a clean change in a repository already in violation, which is a different statement from a clean repository.Model:—currentmeans the repository's stored architecture model was used;built from this session's graphmeans none was stored yet and the layers were worked out for this review;unlabelledmeans the components are named by their directory.- The number beside a direction finding —
[0.64 · inferred]is how sure the analysis is of the layers it inferred. A finding on inferred layers is a strong hint, not a rule broken.
What it is not¶
Not a bug review — it finds no bugs; run /cloudaeye:inspect for
those. Not a redesign: it reports what the change did to the layers as they are, and
every edge on the card is one the code graph read — a dependency you believe is missing is
something to say, not to draw. It never edits code. Its findings carry numbers, so
/cloudaeye:implement [1,3] plans fixes for them the way it does for
a review's.
/cloudaeye:implement¶
Turns findings from the last review into a fix plan. It plans; it never patches, never edits, and never marks a finding closed — only re-running the review can say a fix landed.
When to run: after a review, when you want the plan grounded in the whole repository rather than in the coding agent's context window. Asking Claude to fix a finding directly works too, and costs nothing.
What you pass:
| You type | Meaning |
|---|---|
[1,3] |
Those findings, by the number the review printed |
[2-4] |
A range |
| nothing | Every finding |
[1,3] use a context manager |
Those two, with a constraint bound to both plans |
fix the 2nd point |
Plain words also work |
A number that does not exist is an error naming the valid range, not a partial plan. If the request is ambiguous, nothing is planned and you are asked which you meant.
Output: per selected finding — the file, where in it, what to change, and the blast radius: other call sites with the same defect, callers whose contract changes, tests that assert on the old behaviour. That last part is the reason to use it over fixing directly.
Plans can come back marked stale (the code moved since the review — it may already be
fixed) or not_an_edit (no code change fixes it; a leaked credential needs rotating).
Not available on a pull-request review — the plans describe edits to a working tree. Check the branch out locally and review it there.
/cloudaeye:describe¶
Produces a description of the pending change: a # Change Description paragraph followed by an ## Important Changes bullet list, in plain markdown ready to paste. Trivial diffs short-circuit to a one-line summary.
When to run: before opening a PR, before writing a commit message, or any time you want a "what did I just change?" summary.
What it does: mints or resumes the session, uploads the diff — skipping the upload if another command already uploaded this exact diff this turn — refreshes the code-context graph when your repository is connected to CloudAEye, and calls the tool. The intent passed is your original task request, verbatim.
Output: the description, printed as-is. With the repository connected, it accounts for blast radius across files; otherwise it falls back to diff-only analysis.
/cloudaeye:check-task¶
Verifies whether the pending diff fulfils a stated task, and returns a per-requirement checklist so you can see what is done, partially done, and missing before you commit.
Task inputs — pass any of these as the argument, or the command will prompt:
- A GitHub issue URL —
https://github.com/<owner>/<repo>/issues/<n>. Re-fetched on every call, so new collaborator comments flow through automatically. Requires CloudAEye GitHub access. - Jira ticket IDs —
[BETA-5225, BETA-5223], or a bareBETA-5225. Resolved through your tenant's CloudAEye Jira app. Requires your tenant key plus the Jira app installed — see Custom Context. - Mixed reference lists —
[BETA-5225, #42]resolve too. - Freeform text — a spec excerpt or plain description, passed verbatim. Text that merely mentions tickets ("verify BETA-5225 is handled, keep retries intact") also works: a server-side triage model extracts the references and keeps the extra requirements.
The task is passed verbatim — the command does not summarize or paraphrase it, because the server extracts requirements from the exact text.
Output: a # Task Completion Check heading, an overall verdict — DONE / PARTIAL / NOT DONE — a per-requirement checklist ([x] done, [~] partial, [ ] not done), and any gaps. If the verdict is PARTIAL or NOT DONE, Claude Code asks whether to close the gaps before editing anything.
Reuse: the task is stored on the session. A later resume surfaces it as prior_task, so you are not re-prompted — the command offers to reuse it, confirming first. For a GitHub issue the stored value is the URL, so a re-check picks up new comments rather than a frozen snapshot.
Degradation: if a ticket cannot be resolved — missing token, malformed URL, missing tenant key — the tool returns a structured error rather than a bogus verdict. A task made only of ticket references surfaces the error; a task that also carries prose proceeds against the prose with a visible "reference(s) not checked" note. A verdict never silently implies an unfetched ticket was verified.
/cloudaeye:ask¶
A free-form question about the pending change, answered against the repository's code graph — callers, definitions, and usage traces, not just the diff text.
When to run: for questions Claude Code cannot answer from its own context window. Blast radius ("what else calls this?"), history ("what did this do before?"), repo-wide patterns ("is this handled anywhere else?"), or a second opinion on a specific line.
Your question is passed verbatim. The phrasing carries what you actually want to know, and a rewritten question gets a different answer.
Output: a plain-markdown answer. This is not a review — there is no verdict and no findings list, and it never edits code.
/cloudaeye:check-pr¶
The counterpart to a review, not a variant of one. /cloudaeye:inspect reads the changed
lines; this runs the checks that cannot be judged from a diff — they need the whole
repository, the base branch's file tree, or the pull request itself — and it finds no
bugs and no vulnerabilities. Those two halves do not substitute for each other.
When to run: on an open pull request before you ask for review, to catch the things a reviewer would otherwise spend their first comment on: the undocumented function, the untested branch, the README that still describes last month's flags, the dependency added to code but not to the manifest, the title that says "fix".
What it checks¶
Whichever of these the repository has enabled in the CloudAEye console. There is no argument to turn one on — the API it calls has no field for it — so what runs is a repository setting, and the command reports that setting honestly rather than running a review that can only come back empty.
| Check | What it needs that a diff does not have |
|---|---|
| Docstring coverage | Every changed function, against the repository's convention |
| Unit-test coverage | The call graph, to know which changed code no test reaches |
| README update | The README as it stands, to know whether the change made it stale |
| Dependency manifests | requirements.txt, package.json and the rest, to match new imports against |
| PR title and description | The pull request itself |
| Duplicate code | The whole repository's vector index |
| Secret scan | The pull request's full content |
With nothing enabled you get not_configured, and nothing was run or billed. That is
configuration to change, not a clean result — the command will not say the pull
request passed, because nothing examined it.
What to pass¶
/cloudaeye:check-pr #412
/cloudaeye:check-pr 412
An open pull request (drafts are fine) that merges into your integrated branch, is not from a fork, and changes at most 50 files. Run it from inside the repository the pull request belongs to. Nothing is uploaded from your machine.
What comes back¶
A verdict, one summary line, a row per check, and a link. The full report — every check's detail, the findings, the generated description — is posted on the pull request by the CloudAEye GitHub App. None of it is in the response, deliberately: the whole result ran to nearly five thousand tokens, three-quarters of it per-check markdown that would be re-sent on every later turn of your conversation, and it is more useful on the pull request than in Claude's context.
request_changes — 3 of 6 checks passed; docstring coverage 57.1%
| Check | Status | Detail |
|--------------------|---------|--------------------------|
| Docstring coverage | failed | 57.1% (4/7 documented) |
| Unit-test coverage | failed | 2 of 5 changed functions |
| PR description | passed | |
| PR title | passed | |
| README update | skipped | |
| Secret scan | passed | |
Findings: 6 · Secrets: 0
Full report: acme/orders-api#412
Four statuses, and they must not be flattened into two: passed ran and is satisfied;
failed ran and found something to do, and is what drives request_changes;
skipped is not enabled for this repository; error could not run — a gap in
coverage, and the one a reader will otherwise mistake for a pass. error does not block
and failed does; collapsing them would hide a real failure or invent one.
The number in the Detail column is the check's own — Claude prints it as given and leaves the cell blank when there is none. A figure in that column reads as measured, so nothing is computed on the client side.
The link is only as good as posted. The server asks the App to comment and reports
back whether it worked. ok means the detail is on the pull request; partial means some
of it; failed means none — the table is the whole result; unavailable means the App is
not installed on this repository. Claude reads that field and says which. It never
writes "the report is on the pull request" on the strength of having asked.
A large pull request can outlive one call. You get pending with a review_id, and
Claude resumes with it — never a second review, which is billed again and posts its own
comments.
What it is not¶
Not a bug pass and not a security pass. approve here means the hygiene checks this
repository enabled are satisfied, and says nothing about whether the change is correct.
For that, /cloudaeye:review on the same pull request.
/cloudaeye:add-docs¶
Writes docstrings for the code a pull request touches that has none, and posts each one on the pull request as a review suggestion — the kind with an apply button.
When to run: before a review, on a pull request whose changed functions are
undocumented; or after /cloudaeye:check-pr reports docstring coverage failing. It is
also the honest answer to "add docstrings" from a coding agent: the model that writes the
docstring is on the server, the click that applies it is yours, and no generated text
passes through Claude's context on the way.
What it does¶
CloudAEye reads the repository's code graph — not just the diff — for changed functions and classes without a docstring, writes one for each in the repository's own convention, and posts them as suggestions.
The generated text never comes back. This command once returned it to Claude to apply, and that was removed: a docstring written by a model on the server, read by a model on the client, and retyped by that model into an edit — two of three passes pure transport, with an unbounded payload. What you get instead is a count, a per-file table, and a link, and the suggestions are where you read them.
What to pass¶
/cloudaeye:add-docs #412
Same pull-request rules as /cloudaeye:check-pr. Claude confirms before running —
one line, CloudAEye will post docstring suggestions on acme/orders-api#412, visible to
everyone on the pull request — and waits for a clear yes. Naming the pull request in the
argument is asking for docstrings, not agreeing to post them.
What comes back¶
9 docstrings proposed across 3 files
| File | Suggestions | New |
|------------------------|-------------|-----|
| src/billing/refund.py | 4 | |
| src/billing/invoice.py | 3 | |
| src/billing/__init__.py| 2 | |
Suggestions: acme/orders-api#412 — 7 as one-click suggestions, 2 as comments
Generated and posted are different numbers, and the gap is structural. GitHub refuses
a review suggestion on a line outside the pull request's diff, while the generator
proposes for undocumented code in changed files. Measured on a real pull request: 15
generated, 11 posted — every suggestion in a wholly new file landed, and the four in a
file whose only hunk was elsewhere were refused. Those now go up as plain comments
instead: the text is there, the apply button is not, and the line says how many. posted
carries the honest count; Claude never rounds it up to the generated one.
Zero suggestions is an ordinary answer on a well-documented change. It is reported as "nothing was added", and a note is still left on the pull request so a run that generated nothing leaves a trace.
A large pull request can outlive one call. You get pending with a job_id, and Claude
resumes with it rather than starting a second run — which would post a second set of
suggestions. Nothing is on the pull request until a call sees the job finish; a run
left pending generates suggestions nobody ever sees.
/cloudaeye:add-tests¶
Writes unit tests for the changed code nothing covers, and posts them on the pull request as review suggestions — including whole new test files.
Everything about /cloudaeye:add-docs holds here: the confirmation before it runs, the
generated text staying on the pull request, generated versus posted, the resume rule.
Three things differ.
It finds gaps through the call graph, not by name: a changed function is uncovered
when no test file's node depends on it and no test-file caller reaches it. That is the
same definition /cloudaeye:slop-score's missing-tests signal
uses, so the two agree about what "untested" means.
It proposes whole files. A new_file row in the table is a test file that does not
exist yet. GitHub takes no inline suggestion on a path outside the diff, so those go up
as comments, the same way an out-of-diff docstring does.
Zero suggestions is not "the code is tested." It means nothing in the change was found that a new test would cover — which can be true of a well-tested change and of a change whose gaps the graph could not see. Claude reports the former wording and not the latter.
/cloudaeye:add-tests #412
6 tests proposed across 2 files
| File | Suggestions | New |
|----------------------------|-------------|-----|
| tests/billing/test_refund.py | 5 | yes |
| tests/billing/test_invoice.py| 1 | |
Suggestions: acme/orders-api#412 — 1 as a one-click suggestion, 5 as comments
/cloudaeye:explain¶
Explains a Jira or GitHub issue against the relevant repository's code.
When to run: before implementing an issue, when you need to understand the components it touches, their current behavior, and the surrounding code.
What you pass: jira <KEY-or-id>, github <issue-number>.
What it does: reads the issue and uses the relevant repository's code graph and vector context to produce an explanation.
Output: a summary identifying the issue and the repository analyzed, followed by the full explanation in Markdown. The explanation connects the issue to the relevant components, describes how they work today, and provides related code patterns and configuration to help you understand the work involved.
Examples: /cloudaeye:explain jira BETA-5225,
/cloudaeye:explain github 42
/cloudaeye:create-issue¶
Takes a finding a review already produced and opens a ticket for it — in Jira, or as a
GitHub issue — with the finding's file, line, severity and evidence in the body. The
inverse of /cloudaeye:check-task: that one reads a ticket and
asks whether the change satisfies it; this one makes a ticket out of what the review
found.
When to run: on a finding you are not going to fix in this change — the pre-existing
bug the review surfaced beside your edit, the medium-severity item the release cannot
wait for, the thing that belongs to another team. It is CloudAEye's @cloudaeye
/create_issue from the pull-request timeline, without the pull request, which is the
case that command cannot cover.
What to pass¶
/cloudaeye:create-issue [2] jira Jane Doe finding 2 → Jira, assigned to Jane Doe
/cloudaeye:create-issue [1,3] github octocat findings 1 and 3 → GitHub issues, assigned
/cloudaeye:create-issue [2-4] jira findings 2 to 4 → Jira, unassigned
The numbers are the review's. They are the same ones /cloudaeye:implement takes,
resolved server-side against the stored report, so the finding you read as 2 is the
finding that gets filed. Say "file the auth one" and Claude resolves it against the list
it printed — and asks if it is not certain, because a wrong number puts somebody's name
on a ticket about the wrong defect.
The provider is jira (the default) or github. The assignee is a Jira display name
or a GitHub username, optional, and never assumed — Claude does not put your own name
on it unless you say so. Anything you add — "let's fix this before the release" — goes at
the top of the ticket, above the finding, as the instruction the finding is evidence for.
There is no "file them all", deliberately. /cloudaeye:implement with no numbers
plans every finding, and a wrong guess there produces a plan you read and discard. Here
it would open a dozen tickets with people's names on them, so an empty selection is
refused. Say "file them all" and Claude confirms the count first — that is six tickets,
go ahead? — then passes the explicit list.
Claude confirms before filing. These are real tickets: they get an assignee, appear on a board, and somebody has to close them.
What comes back¶
Filed
2. Calls Invoice.recalculate_totals(), which is not defined anywhere
hallucinated_api · src/billing/invoice.py:88 → BETA-5311
Already filed
4. Unused import: decimal.ROUND_UP
dead_code · src/billing/refund.py:3 → BETA-5298, earlier this session
Re-running is safe. A finding already filed from this session is matched by content — its path and title — not by its number, because numbers are reassigned on every review. So a re-review that renumbers a finding does not file it twice, and the result names the existing ticket instead. The record lives beside the review, not in it, so it survives the next review overwriting the report. It errs toward a duplicate rather than a suppression: a duplicate ticket is visible and closable, a suppressed one for a real defect is neither.
A GitHub assignee who cannot be assigned on that repository is dropped, and the issue is
still filed — the result says both halves. issues are disabled on this repository is
a GitHub setting; no Jira integration is configuration. Neither is worth retrying as-is.
What it is not¶
Filing never closes a finding. A ticket records it; only re-running the review can
say the defect is gone. If you want it fixed now, that is
/cloudaeye:implement. And it never edits your working tree and
never opens a pull request — Jira works from a working-tree session as well as a
pull-request one, and GitHub files against the session's repository.
/cloudaeye:init¶
Initialize the current Git repository for CloudAEye review. Run it after authentication and once per repository before using the review commands.
The command detects the repository provider, remote URL and base branch. It then calls the repository initialization operation with the detected provider and remote URL.
The server requires a monitor branch, the command prompts for input.
If the provider(GitHub, Bitbucket, Gitlab) is not connected, it opens the provider integration page and waits until connection is done and repo is configured