Skip to content

Commit ada9935

Browse files
authored
Merge branch 'main' into alex/HDX-2150-external-api-containers-tabs
2 parents 574ee8e + 28b372b commit ada9935

27 files changed

Lines changed: 1307 additions & 40 deletions

.changeset/beige-parents-lick.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@hyperdx/app': patch
3+
'@hyperdx/common-utils': patch
4+
---
5+
6+
fix: prevent false "data source not set" error on markdown dashboard tiles

.changeset/lucky-adults-jump.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperdx/app": patch
3+
---
4+
5+
fix: numbers from filters bar was always showing 0 instead of the count
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hyperdx/api': patch
3+
---
4+
5+
Add groupByColumnsOnLeft to MCP dashboard table tile schema

.github/workflows/claude-code-review.yml

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ jobs:
102102
Note: If the team wants a more thorough review, they can comment on the PR requesting one.
103103
104104
CRITICAL OUTPUT REQUIREMENTS:
105-
1. Return a JSON object with a single "review" field containing your full markdown review.
105+
1. Return a JSON object with a single "review" field whose VALUE
106+
is a plain markdown STRING. Do NOT put another JSON object
107+
inside the "review" string -- doing so posts raw JSON in the
108+
comment instead of rendered markdown. The `review` value must
109+
be markdown text only, not a stringified JSON envelope.
106110
2. The review markdown must start with EXACTLY these two lines:
107111
<!-- claude-code-review -->
108112
## PR Review
@@ -125,12 +129,37 @@ jobs:
125129
body-includes: '<!-- claude-code-review -->'
126130
direction: last
127131

132+
# fromJSON() in a `with:` expression has been observed to leave the
133+
# structured_output JSON string unparsed, posting the raw envelope as
134+
# the comment body. Extract via jq.
135+
#
136+
# Defensive double-unwrap: the model has been observed to return
137+
# `{"review": "{\"review\": \"<markdown>\"}"}` -- wrapping its own JSON
138+
# output a second time so the comment body posts as raw JSON. Detect
139+
# that case (the inner string parses as an object with a `review` key)
140+
# and unwrap once more so we post markdown, not JSON. Mirrors the same
141+
# fix applied to deep-review.yml.
142+
- name: Extract review from structured output
143+
id: extract-review
144+
env:
145+
STRUCTURED_OUTPUT:
146+
${{ steps.claude-review.outputs.structured_output }}
147+
run: |
148+
REVIEW="$(printf '%s' "$STRUCTURED_OUTPUT" | jq -r '.review')"
149+
if printf '%s' "$REVIEW" | jq -e 'type == "object" and has("review")' >/dev/null 2>&1; then
150+
REVIEW="$(printf '%s' "$REVIEW" | jq -r '.review')"
151+
fi
152+
{
153+
echo 'review<<CLAUDE_REVIEW_EOF'
154+
printf '%s' "$REVIEW"
155+
echo
156+
echo 'CLAUDE_REVIEW_EOF'
157+
} >> "$GITHUB_OUTPUT"
158+
128159
- name: Post or update Claude review
129160
uses: peter-evans/create-or-update-comment@v5
130161
with:
131162
comment-id: ${{ steps.find-claude-comment.outputs.comment-id }}
132163
issue-number: ${{ steps.pr.outputs.number }}
133-
body:
134-
${{ fromJSON(steps.claude-review.outputs.structured_output).review
135-
}}
164+
body: ${{ steps.extract-review.outputs.review }}
136165
edit-mode: replace

.github/workflows/deep-resolve.yml

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
name: Deep Review Resolver
2+
3+
# Triggered by a collaborator commenting `/just-fix-it` on a PR. Reads the
4+
# latest <!-- deep-review --> sticky comment posted by deep-review.yml,
5+
# hands the findings to Claude with edit + git tools, and pushes a single
6+
# fix commit to the PR head branch.
7+
#
8+
# Limitations:
9+
# - Same-repo PRs only. Fork PRs cannot be pushed to from CI with the
10+
# default GITHUB_TOKEN; the workflow exits early on forks.
11+
# - Collaborator-gated. The job `if` requires OWNER/MEMBER/COLLABORATOR
12+
# association on the triggering comment to prevent random drive-by use.
13+
# - Single-shot. Re-trigger by commenting `/just-fix-it` again after the
14+
# follow-up deep-review run posts an updated finding list.
15+
16+
on:
17+
issue_comment:
18+
types: [created]
19+
20+
concurrency:
21+
group: deep-resolve-${{ github.event.issue.number }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
resolve:
26+
if: |
27+
github.event.issue.pull_request != null &&
28+
startsWith(github.event.comment.body, '/just-fix-it') &&
29+
(github.event.comment.author_association == 'OWNER' ||
30+
github.event.comment.author_association == 'MEMBER' ||
31+
github.event.comment.author_association == 'COLLABORATOR')
32+
runs-on: ubuntu-latest
33+
permissions:
34+
contents: write
35+
pull-requests: write
36+
issues: write
37+
id-token: write
38+
actions: read
39+
40+
steps:
41+
- name: Acknowledge trigger
42+
uses: actions/github-script@v9
43+
with:
44+
script: |
45+
await github.rest.reactions.createForIssueComment({
46+
owner: context.repo.owner,
47+
repo: context.repo.repo,
48+
comment_id: context.payload.comment.id,
49+
content: 'eyes',
50+
});
51+
52+
- name: Resolve PR metadata
53+
id: pr
54+
uses: actions/github-script@v9
55+
with:
56+
script: |
57+
const { data: pr } = await github.rest.pulls.get({
58+
owner: context.repo.owner,
59+
repo: context.repo.repo,
60+
pull_number: context.payload.issue.number,
61+
});
62+
const isFork = pr.head.repo.full_name !== pr.base.repo.full_name;
63+
core.setOutput('number', String(pr.number));
64+
core.setOutput('head_repo', pr.head.repo.full_name);
65+
core.setOutput('head_ref', pr.head.ref);
66+
core.setOutput('is_fork', String(isFork));
67+
68+
- name: Reject fork PRs
69+
if: steps.pr.outputs.is_fork == 'true'
70+
uses: actions/github-script@v9
71+
with:
72+
script: |
73+
await github.rest.issues.createComment({
74+
owner: context.repo.owner,
75+
repo: context.repo.repo,
76+
issue_number: context.payload.issue.number,
77+
body: '<!-- deep-resolve -->\n⚠️ `/just-fix-it` is not supported on fork PRs — CI cannot push to a fork branch with the default token. Apply the review findings locally and push.',
78+
});
79+
core.setFailed('Fork PR — auto-fix unavailable');
80+
81+
- name: Fetch latest deep review comment
82+
id: review
83+
uses: actions/github-script@v9
84+
with:
85+
script: |
86+
const comments = await github.paginate(
87+
github.rest.issues.listComments,
88+
{
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
issue_number: context.payload.issue.number,
92+
per_page: 100,
93+
}
94+
);
95+
const review = [...comments].reverse().find(c =>
96+
c.body && c.body.includes('<!-- deep-review -->'));
97+
if (!review) {
98+
await github.rest.issues.createComment({
99+
owner: context.repo.owner,
100+
repo: context.repo.repo,
101+
issue_number: context.payload.issue.number,
102+
body: '<!-- deep-resolve -->\n⚠️ No deep review comment found on this PR. Wait for the review to post, then re-trigger with `/just-fix-it`.',
103+
});
104+
core.setFailed('No deep review comment found');
105+
return;
106+
}
107+
core.setOutput('body', review.body);
108+
109+
- name: Checkout PR head
110+
uses: actions/checkout@v6
111+
with:
112+
repository: ${{ steps.pr.outputs.head_repo }}
113+
ref: ${{ steps.pr.outputs.head_ref }}
114+
token: ${{ secrets.GITHUB_TOKEN }}
115+
fetch-depth: 0
116+
117+
- name: Set git author
118+
run: |
119+
git config user.name "github-actions[bot]"
120+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
121+
122+
- name: Setup Node
123+
uses: actions/setup-node@v4
124+
with:
125+
node-version: 22
126+
127+
- name: Enable corepack
128+
run: corepack enable
129+
130+
- name: Run Claude to apply fixes
131+
uses: anthropics/claude-code-action@v1
132+
with:
133+
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
134+
github_token: ${{ secrets.GITHUB_TOKEN }}
135+
prompt: |
136+
REPO: ${{ github.repository }}
137+
PR NUMBER: ${{ steps.pr.outputs.number }}
138+
BRANCH: ${{ steps.pr.outputs.head_ref }}
139+
140+
The deep multi-agent review posted findings on this PR. Apply
141+
fixes per the rules below. The PR head is already checked out
142+
with push credentials configured.
143+
144+
Review findings (verbatim):
145+
---
146+
${{ steps.review.outputs.body }}
147+
---
148+
149+
Rules:
150+
1. Apply ALL P0 and P1 findings.
151+
2. Apply P2 findings only if the fix is mechanical (rename,
152+
missing await, obvious typo, dead import). Skip ambiguous P2.
153+
3. Skip P3 entirely.
154+
4. If a finding is wrong (false positive) or out of scope for
155+
the PR, skip it and note why in your summary.
156+
5. Make the smallest change that addresses each finding. Do not
157+
refactor surrounding code, rename unrelated identifiers, or
158+
touch files not cited by a finding.
159+
160+
After edits:
161+
6. Run `yarn lint:fix` to auto-fix formatting. If it errors on
162+
files you didn't touch, leave those alone.
163+
7. Stage and commit in a single commit:
164+
git add -A
165+
git commit -m "fix: address deep review findings"
166+
Use that exact message. No Co-Authored-By trailers
167+
(project convention; see AGENTS.md).
168+
8. Push: `git push origin HEAD`
169+
9. Post a summary comment on PR ${{ steps.pr.outputs.number }}
170+
via `gh pr comment`. The comment body MUST start with
171+
`<!-- deep-resolve -->` on its own line so future runs
172+
can locate it. Then a brief markdown list:
173+
- **Fixed:** one line per finding addressed (file:line - what)
174+
- **Skipped:** one line per finding deliberately not fixed,
175+
with reason
176+
Keep the whole comment under 30 lines.
177+
178+
If you make no edits at all (every finding skipped), do not
179+
create an empty commit and do not push. Still post the summary
180+
comment so the author sees why.
181+
182+
claude_args: |
183+
--setting-sources user
184+
--allowedTools "Bash(git:*),Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr comment:*),Bash(yarn lint:fix),Bash(yarn:*),Edit,Write,MultiEdit,Read,Grep,Glob"
185+
186+
- name: React on failure
187+
if: failure()
188+
uses: actions/github-script@v9
189+
with:
190+
script: |
191+
await github.rest.reactions.createForIssueComment({
192+
owner: context.repo.owner,
193+
repo: context.repo.repo,
194+
comment_id: context.payload.comment.id,
195+
content: 'confused',
196+
});

0 commit comments

Comments
 (0)