Skip to content

Commit 41b9ce3

Browse files
committed
Merge branch 'master' into feature/solid-devtools
2 parents f69dc77 + 5af1eed commit 41b9ce3

159 files changed

Lines changed: 4579 additions & 2106 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, ready_for_review, reopened]
6+
# Optional: Only run on specific file changes
7+
# paths:
8+
# - "src/**/*.ts"
9+
# - "src/**/*.tsx"
10+
# - "src/**/*.js"
11+
# - "src/**/*.jsx"
12+
13+
jobs:
14+
claude-review:
15+
if: >-
16+
contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)
17+
18+
runs-on: ubuntu-latest
19+
permissions:
20+
contents: read
21+
pull-requests: read
22+
issues: read
23+
id-token: write
24+
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v4
28+
with:
29+
fetch-depth: 1
30+
31+
- name: Run Claude Code Review
32+
id: claude-review
33+
uses: anthropics/claude-code-action@v1
34+
with:
35+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
36+
plugin_marketplaces: "https://github.com/anthropics/claude-code.git"
37+
plugins: "code-review@claude-code-plugins"
38+
prompt: "/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
39+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
40+
# or https://code.claude.com/docs/en/cli-reference for available options

.github/workflows/claude.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, assigned]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(
17+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
18+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
19+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) ||
20+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))
21+
)
22+
runs-on: ubuntu-latest
23+
permissions:
24+
contents: read
25+
pull-requests: read
26+
issues: read
27+
id-token: write
28+
actions: read # Required for Claude to read CI results on PRs
29+
steps:
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
with:
33+
fetch-depth: 1
34+
35+
- name: Run Claude Code
36+
id: claude
37+
uses: anthropics/claude-code-action@v1
38+
with:
39+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
40+
41+
# This is an optional setting that allows Claude to read CI results on PRs
42+
additional_permissions: |
43+
actions: read
44+
45+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
46+
# prompt: 'Update the pull request description to include a summary of changes.'
47+
48+
# Optional: Add claude_args to customize behavior and configuration
49+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
50+
# or https://code.claude.com/docs/en/cli-reference for available options
51+
# claude_args: '--allowed-tools Bash(gh pr:*)'

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,5 @@ frontend/static/webfonts-preview
131131

132132
.turbo
133133
frontend/.env.sentry-build-plugin
134+
.claude/worktrees
135+
1024MiB

backend/__tests__/__integration__/dal/preset.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe("PresetDal", () => {
6969
//WHEN / THEN
7070
await expect(() =>
7171
PresetDal.addPreset(uid, { name: "max", config: {} }),
72-
).rejects.toThrowError("Too many presets");
72+
).rejects.toThrow("Too many presets");
7373
});
7474
it("should add preset", async () => {
7575
//GIVEN
@@ -358,7 +358,7 @@ describe("PresetDal", () => {
358358
const uid = new ObjectId().toHexString();
359359
await expect(() =>
360360
PresetDal.removePreset(uid, new ObjectId().toHexString()),
361-
).rejects.toThrowError("Preset not found");
361+
).rejects.toThrow("Preset not found");
362362
});
363363
it("should remove", async () => {
364364
//GIVEN
@@ -421,7 +421,7 @@ describe("PresetDal", () => {
421421
//WHEN
422422
await expect(() =>
423423
PresetDal.removePreset(decoyUid, first),
424-
).rejects.toThrowError("Preset not found");
424+
).rejects.toThrow("Preset not found");
425425

426426
//THEN
427427
const read = await PresetDal.getPresets(uid);

backend/__tests__/__integration__/dal/user.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ describe("UserDal", () => {
11751175
it("should throw for unknown user", async () => {
11761176
await expect(async () =>
11771177
UserDAL.getPartialUser("1234", "stack", []),
1178-
).rejects.toThrowError("User not found\nStack: stack");
1178+
).rejects.toThrow("User not found\nStack: stack");
11791179
});
11801180

11811181
it("should get streak", async () => {
@@ -1228,7 +1228,7 @@ describe("UserDal", () => {
12281228
it("throws for nonexisting user", async () => {
12291229
await expect(async () =>
12301230
UserDAL.updateEmail("unknown", "test@example.com"),
1231-
).rejects.toThrowError("User not found\nStack: update email");
1231+
).rejects.toThrow("User not found\nStack: update email");
12321232
});
12331233
it("should update", async () => {
12341234
//given
@@ -1244,7 +1244,7 @@ describe("UserDal", () => {
12441244
});
12451245
describe("resetPb", () => {
12461246
it("throws for nonexisting user", async () => {
1247-
await expect(async () => UserDAL.resetPb("unknown")).rejects.toThrowError(
1247+
await expect(async () => UserDAL.resetPb("unknown")).rejects.toThrow(
12481248
"User not found\nStack: reset pb",
12491249
);
12501250
});
@@ -1272,7 +1272,7 @@ describe("UserDal", () => {
12721272
it("throws for nonexisting user", async () => {
12731273
await expect(async () =>
12741274
UserDAL.linkDiscord("unknown", "", ""),
1275-
).rejects.toThrowError("User not found\nStack: link discord");
1275+
).rejects.toThrow("User not found\nStack: link discord");
12761276
});
12771277
it("should update", async () => {
12781278
//given
@@ -1308,7 +1308,7 @@ describe("UserDal", () => {
13081308
it("throws for nonexisting user", async () => {
13091309
await expect(async () =>
13101310
UserDAL.unlinkDiscord("unknown"),
1311-
).rejects.toThrowError("User not found\nStack: unlink discord");
1311+
).rejects.toThrow("User not found\nStack: unlink discord");
13121312
});
13131313
it("should update", async () => {
13141314
//given

backend/__tests__/api/controllers/admin.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ describe("AdminController", () => {
323323
data: null,
324324
});
325325

326-
expect(addToInboxMock).toBeCalledTimes(2);
326+
expect(addToInboxMock).toHaveBeenCalledTimes(2);
327327
expect(deleteReportsMock).toHaveBeenCalledWith(["1", "2"]);
328328
});
329329
it("should fail wihtout mandatory properties", async () => {

backend/__tests__/api/controllers/user.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1814,7 +1814,7 @@ describe("user controller test", () => {
18141814
//THEN
18151815
expect(result.body.message).toEqual("The Discord account is blocked");
18161816

1817-
expect(blocklistContainsMock).toBeCalledWith({
1817+
expect(blocklistContainsMock).toHaveBeenCalledWith({
18181818
discordId: "discordUserId",
18191819
});
18201820
});

backend/__tests__/middlewares/auth.spec.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ describe("middlewares/auth", () => {
154154
{ headers: { authorization: "ApeKey aWQua2V5" } },
155155
{ acceptApeKeys: false },
156156
),
157-
).rejects.toThrowError("This endpoint does not accept ApeKeys");
157+
).rejects.toThrow("This endpoint does not accept ApeKeys");
158158

159159
//THEN
160160
});
@@ -170,7 +170,7 @@ describe("middlewares/auth", () => {
170170
{ headers: { authorization: "ApeKey aWQua2V5" } },
171171
{ acceptApeKeys: false },
172172
),
173-
).rejects.toThrowError("ApeKeys are not being accepted at this time");
173+
).rejects.toThrow("ApeKeys are not being accepted at this time");
174174

175175
//THEN
176176
});
@@ -253,7 +253,7 @@ describe("middlewares/auth", () => {
253253
);
254254
});
255255
it("should fail without authentication", async () => {
256-
await expect(() => authenticate({ headers: {} })).rejects.toThrowError(
256+
await expect(() => authenticate({ headers: {} })).rejects.toThrow(
257257
"Unauthorized\nStack: endpoint: /api/v1 no authorization header found",
258258
);
259259

@@ -269,7 +269,7 @@ describe("middlewares/auth", () => {
269269
it("should fail with empty authentication", async () => {
270270
await expect(() =>
271271
authenticate({ headers: { authorization: "" } }),
272-
).rejects.toThrowError(
272+
).rejects.toThrow(
273273
"Unauthorized\nStack: endpoint: /api/v1 no authorization header found",
274274
);
275275

@@ -285,7 +285,7 @@ describe("middlewares/auth", () => {
285285
it("should fail with missing authentication token", async () => {
286286
await expect(() =>
287287
authenticate({ headers: { authorization: "Bearer" } }),
288-
).rejects.toThrowError(
288+
).rejects.toThrow(
289289
"Missing authentication token\nStack: authenticateWithAuthHeader",
290290
);
291291

@@ -301,7 +301,7 @@ describe("middlewares/auth", () => {
301301
it("should fail with unknown authentication scheme", async () => {
302302
await expect(() =>
303303
authenticate({ headers: { authorization: "unknown format" } }),
304-
).rejects.toThrowError(
304+
).rejects.toThrow(
305305
'Unknown authentication scheme\nStack: The authentication scheme "unknown" is not implemented',
306306
);
307307

@@ -417,7 +417,7 @@ describe("middlewares/auth", () => {
417417
//THEN
418418
await expect(() =>
419419
authenticate({ headers: {} }, { isPublicOnDev: true }),
420-
).rejects.toThrowError("Unauthorized");
420+
).rejects.toThrow("Unauthorized");
421421
});
422422
it("should allow with apeKey on dev public endpoint in production", async () => {
423423
//WHEN
@@ -476,7 +476,7 @@ describe("middlewares/auth", () => {
476476
},
477477
{ isGithubWebhook: true },
478478
),
479-
).rejects.toThrowError("Github webhook signature invalid");
479+
).rejects.toThrow("Github webhook signature invalid");
480480

481481
//THEH
482482
expect(prometheusIncrementAuthMock).not.toHaveBeenCalled();
@@ -497,7 +497,7 @@ describe("middlewares/auth", () => {
497497
},
498498
{ isGithubWebhook: true },
499499
),
500-
).rejects.toThrowError("Missing Github signature header");
500+
).rejects.toThrow("Missing Github signature header");
501501

502502
//THEH
503503
expect(prometheusIncrementAuthMock).not.toHaveBeenCalled();
@@ -518,7 +518,7 @@ describe("middlewares/auth", () => {
518518
},
519519
{ isGithubWebhook: true },
520520
),
521-
).rejects.toThrowError("Missing Github Webhook Secret");
521+
).rejects.toThrow("Missing Github Webhook Secret");
522522

523523
//THEH
524524
expect(prometheusIncrementAuthMock).not.toHaveBeenCalled();
@@ -542,7 +542,7 @@ describe("middlewares/auth", () => {
542542
},
543543
{ isGithubWebhook: true },
544544
),
545-
).rejects.toThrowError(
545+
).rejects.toThrow(
546546
"Failed to authenticate Github webhook: could not validate",
547547
);
548548

backend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"object-hash": "3.0.0",
5050
"prom-client": "15.1.3",
5151
"rate-limiter-flexible": "5.0.3",
52-
"simple-git": "3.16.0",
52+
"simple-git": "3.32.3",
5353
"string-similarity": "4.0.4",
5454
"swagger-stats": "0.99.7",
5555
"ua-parser-js": "0.7.33",
@@ -87,7 +87,7 @@
8787
"testcontainers": "11.11.0",
8888
"tsx": "4.21.0",
8989
"typescript": "6.0.0-beta",
90-
"vitest": "4.0.15"
90+
"vitest": "4.1.0"
9191
},
9292
"engines": {
9393
"node": ">=24.0.0 <25"

frontend/.oxlintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"overrides": [
1313
{
14-
"files": ["src/**/*.ts"],
14+
"files": ["**/*.ts"],
1515
"rules": {
1616
//
1717
}

0 commit comments

Comments
 (0)