原始 JSON 报告 机器可读
{
"data": {
"repo": {
"topics": [
"good-first-issue",
"java",
"static-analysis",
"static-code-analysis",
"openrewrite",
"openrewrite-recipes"
],
"is_fork": false,
"size_kb": 5108,
"has_wiki": false,
"homepage": null,
"languages": {
"Java": 3334875
},
"pushed_at": "2026-07-23T19:32:48Z",
"created_at": "2023-04-30T23:54:01Z",
"owner_type": "Organization",
"updated_at": "2026-07-23T19:32:53Z",
"description": "OpenRewrite recipes for identifying and fixing static analysis issues.",
"is_archived": false,
"is_disabled": false,
"license_spdx": null,
"default_branch": "main",
"license_spdx_raw": "NOASSERTION",
"primary_language": "Java",
"significant_languages": [
"Java"
]
},
"owner": {
"blog": "https://docs.openrewrite.org",
"name": "OpenRewrite",
"type": "Organization",
"login": "openrewrite",
"company": null,
"location": "San Francisco, CA",
"followers": 984,
"avatar_url": "https://avatars.githubusercontent.com/u/61478321?v=4",
"created_at": "2020-02-25T21:27:36Z",
"is_verified": null,
"public_repos": 75,
"account_age_days": 2341
},
"license": {
"state": "custom",
"spdx_id": null,
"raw_spdx": "NOASSERTION",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v2.39.0",
"kind": "minor",
"published_at": "2026-07-14T05:34:02Z"
},
{
"tag": "v2.38.0",
"kind": "minor",
"published_at": "2026-07-01T06:00:05Z"
},
{
"tag": "v2.37.0",
"kind": "minor",
"published_at": "2026-06-17T09:01:31Z"
},
{
"tag": "v2.36.0",
"kind": "minor",
"published_at": "2026-06-03T13:47:42Z"
},
{
"tag": "v2.35.0",
"kind": "minor",
"published_at": "2026-05-21T10:35:26Z"
},
{
"tag": "v2.34.1",
"kind": "patch",
"published_at": "2026-05-07T01:21:31Z"
},
{
"tag": "v2.34.0",
"kind": "minor",
"published_at": "2026-04-27T09:38:22Z"
},
{
"tag": "v2.33.1",
"kind": "patch",
"published_at": "2026-04-23T10:05:24Z"
},
{
"tag": "v2.33.0",
"kind": "minor",
"published_at": "2026-04-21T07:52:41Z"
},
{
"tag": "v2.32.0",
"kind": "minor",
"published_at": "2026-04-08T12:57:29Z"
},
{
"tag": "v2.31.0",
"kind": "minor",
"published_at": "2026-03-25T09:46:47Z"
},
{
"tag": "v2.30.1",
"kind": "patch",
"published_at": "2026-03-19T15:55:58Z"
},
{
"tag": "v2.30.0",
"kind": "minor",
"published_at": "2026-03-12T14:29:03Z"
},
{
"tag": "v2.29.0",
"kind": "minor",
"published_at": "2026-03-04T17:03:53Z"
},
{
"tag": "v2.28.0",
"kind": "minor",
"published_at": "2026-02-25T12:46:09Z"
},
{
"tag": "v2.27.0",
"kind": "minor",
"published_at": "2026-02-11T09:05:07Z"
},
{
"tag": "v2.26.0",
"kind": "minor",
"published_at": "2026-01-20T19:25:15Z"
},
{
"tag": "v2.25.0",
"kind": "minor",
"published_at": "2026-01-07T16:01:56Z"
},
{
"tag": "v2.24.0",
"kind": "minor",
"published_at": "2025-12-16T16:40:14Z"
},
{
"tag": "v2.23.0",
"kind": "minor",
"published_at": "2025-12-05T11:02:22Z"
},
{
"tag": "v2.22.0",
"kind": "minor",
"published_at": "2025-11-20T11:46:55Z"
},
{
"tag": "v2.21.0",
"kind": "minor",
"published_at": "2025-11-04T15:00:03Z"
},
{
"tag": "v2.20.0",
"kind": "minor",
"published_at": "2025-10-22T12:03:34Z"
},
{
"tag": "v2.19.0",
"kind": "minor",
"published_at": "2025-10-10T17:18:06Z"
},
{
"tag": "v2.18.0",
"kind": "minor",
"published_at": "2025-09-24T12:37:03Z"
},
{
"tag": "v2.17.0",
"kind": "minor",
"published_at": "2025-09-10T10:50:57Z"
},
{
"tag": "v2.16.0",
"kind": "minor",
"published_at": "2025-08-27T16:18:09Z"
},
{
"tag": "v2.15.0",
"kind": "minor",
"published_at": "2025-08-12T21:08:15Z"
},
{
"tag": "v2.14.0",
"kind": "minor",
"published_at": "2025-07-23T21:44:08Z"
},
{
"tag": "v2.13.0",
"kind": "minor",
"published_at": "2025-07-23T10:47:33Z"
},
{
"tag": "v2.12.0",
"kind": "minor",
"published_at": "2025-07-09T15:16:16Z"
},
{
"tag": "v2.11.0",
"kind": "minor",
"published_at": "2025-06-25T11:26:25Z"
},
{
"tag": "v2.10.0",
"kind": "minor",
"published_at": "2025-05-28T15:32:59Z"
},
{
"tag": "v2.9.0",
"kind": "minor",
"published_at": "2025-05-07T17:18:47Z"
},
{
"tag": "v2.8.0",
"kind": "minor",
"published_at": "2025-04-24T17:43:56Z"
},
{
"tag": "v2.7.1",
"kind": "patch",
"published_at": "2025-04-10T15:15:15Z"
},
{
"tag": "v2.7.0",
"kind": "minor",
"published_at": "2025-04-09T18:53:52Z"
},
{
"tag": "v2.6.0",
"kind": "minor",
"published_at": "2025-04-07T10:20:32Z"
},
{
"tag": "v2.5.1",
"kind": "patch",
"published_at": "2025-03-27T19:12:36Z"
},
{
"tag": "v2.5.0",
"kind": "minor",
"published_at": "2025-03-26T10:51:19Z"
},
{
"tag": "v2.4.0",
"kind": "minor",
"published_at": "2025-03-11T19:42:05Z"
},
{
"tag": "v2.3.0",
"kind": "minor",
"published_at": "2025-02-20T21:13:03Z"
},
{
"tag": "v2.2.0",
"kind": "minor",
"published_at": "2025-02-07T16:57:10Z"
},
{
"tag": "v2.1.0",
"kind": "minor",
"published_at": "2025-01-24T17:30:23Z"
},
{
"tag": "v2.0.2",
"kind": "patch",
"published_at": "2025-01-17T17:24:18Z"
},
{
"tag": "v2.0.1",
"kind": "patch",
"published_at": "2025-01-11T15:09:11Z"
},
{
"tag": "v2.0.0",
"kind": "major",
"published_at": "2025-01-10T17:09:56Z"
},
{
"tag": "v1.22.0",
"kind": "minor",
"published_at": "2024-12-18T15:14:20Z"
},
{
"tag": "v1.21.1",
"kind": "patch",
"published_at": "2024-11-28T18:55:34Z"
},
{
"tag": "v1.21.0",
"kind": "minor",
"published_at": "2024-11-27T16:16:52Z"
},
{
"tag": "v1.20.0",
"kind": "minor",
"published_at": "2024-11-13T16:12:32Z"
},
{
"tag": "v1.19.0",
"kind": "minor",
"published_at": "2024-10-23T15:04:27Z"
},
{
"tag": "v1.18.0",
"kind": "minor",
"published_at": "2024-10-09T18:16:41Z"
},
{
"tag": "v1.17.0",
"kind": "minor",
"published_at": "2024-09-24T19:06:45Z"
},
{
"tag": "v1.16.0",
"kind": "minor",
"published_at": "2024-09-11T17:22:09Z"
},
{
"tag": "v1.15.0",
"kind": "minor",
"published_at": "2024-08-28T14:16:51Z"
},
{
"tag": "v1.14.0",
"kind": "minor",
"published_at": "2024-08-12T19:47:32Z"
},
{
"tag": "v1.13.0",
"kind": "minor",
"published_at": "2024-07-31T11:54:56Z"
},
{
"tag": "v1.12.0",
"kind": "minor",
"published_at": "2024-07-15T09:14:18Z"
},
{
"tag": "v1.11.0",
"kind": "minor",
"published_at": "2024-07-03T16:51:43Z"
},
{
"tag": "v1.10.1",
"kind": "patch",
"published_at": "2024-06-19T18:05:17Z"
},
{
"tag": "v1.10.0",
"kind": "minor",
"published_at": "2024-06-19T09:04:23Z"
},
{
"tag": "v1.9.0",
"kind": "minor",
"published_at": "2024-06-07T22:36:01Z"
},
{
"tag": "v1.8.1",
"kind": "patch",
"published_at": "2024-05-22T21:47:41Z"
},
{
"tag": "v1.8.0",
"kind": "minor",
"published_at": "2024-05-22T16:03:40Z"
},
{
"tag": "v1.7.0",
"kind": "minor",
"published_at": "2024-05-18T05:20:04Z"
},
{
"tag": "v1.6.0",
"kind": "minor",
"published_at": "2024-05-08T13:50:25Z"
},
{
"tag": "v1.5.0",
"kind": "minor",
"published_at": "2024-04-24T15:23:21Z"
},
{
"tag": "v1.4.2",
"kind": "patch",
"published_at": "2024-03-19T18:48:18Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2024-03-19T13:12:21Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2024-03-12T22:04:15Z"
},
{
"tag": "v1.3.1",
"kind": "patch",
"published_at": "2024-02-20T20:19:26Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2024-02-06T18:34:52Z"
},
{
"tag": "v1.2.2",
"kind": "patch",
"published_at": "2024-01-23T17:11:31Z"
},
{
"tag": "v1.2.1",
"kind": "patch",
"published_at": "2024-01-16T16:01:31Z"
},
{
"tag": "v1.2.0",
"kind": "minor",
"published_at": "2024-01-09T14:37:38Z"
},
{
"tag": "v1.1.4",
"kind": "patch",
"published_at": "2023-12-21T13:53:07Z"
},
{
"tag": "v1.1.3",
"kind": "patch",
"published_at": "2023-12-08T10:26:38Z"
},
{
"tag": "v1.1.2",
"kind": "patch",
"published_at": "2023-12-04T20:05:02Z"
},
{
"tag": "v1.1.1",
"kind": "patch",
"published_at": "2023-11-25T10:26:12Z"
},
{
"tag": "v1.1.0",
"kind": "minor",
"published_at": "2023-11-11T01:37:59Z"
},
{
"tag": "v1.0.9",
"kind": "patch",
"published_at": "2023-10-27T23:56:19Z"
},
{
"tag": "v1.0.8",
"kind": "patch",
"published_at": "2023-10-03T03:02:46Z"
},
{
"tag": "v1.0.7",
"kind": "patch",
"published_at": "2023-09-12T15:50:05Z"
},
{
"tag": "v1.0.6",
"kind": "patch",
"published_at": "2023-08-24T21:22:35Z"
},
{
"tag": "v1.0.5",
"kind": "patch",
"published_at": "2023-08-09T16:59:21Z"
},
{
"tag": "v1.0.4",
"kind": "patch",
"published_at": "2023-07-26T20:45:34Z"
},
{
"tag": "v1.0.3",
"kind": "patch",
"published_at": "2023-07-04T09:11:06Z"
},
{
"tag": "v1.0.2",
"kind": "patch",
"published_at": "2023-06-28T12:49:47Z"
},
{
"tag": "v1.0.1",
"kind": "patch",
"published_at": "2023-06-14T03:15:35Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2023-06-02T02:39:33Z"
}
],
"recent_commits": [
{
"oid": "5545efa3f71cabfb1feeacb55c26ae55538488f5",
"body": "In Kotlin a newline terminates an expression, so a leading binary operator is\nparsed as a unary operator on a new statement. With the default `WrapOption.NL`\nstyle, `OperatorWrap` moved a binary operator to the start of the next line,\nturning\n\n val s = \"aaa\" + \"b\" +\n \"c\"\n\ninto the uncompil\n[…]\nces.\n\nRestrict the visitor to `J.CompilationUnit` so it only reformats Java and leaves\nKotlin (and other non-Java `JavaSourceFile`s) untouched.\n\nCo-authored-by: Claude Opus 4.8 <noreply@anthropic.com>",
"is_bot": false,
"headline": "Do not wrap operators onto a new line in Kotlin sources (#936)",
"author_name": "Vladimir Sitnikov",
"author_login": "vlsi",
"committed_at": "2026-07-23T19:32:48Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "8a88b480f019d45a9e39f873d51da343e6e9ccbf",
"body": "* Add recipe for finding exceptions which are thrown from catch blocks that do not reference the caught exception\n\n* Add recipe for finding exceptions which are thrown from catch blocks that do not reference the caught exception\n\n* Update recipes.csv",
"is_bot": false,
"headline": "exception-without-cause (#950)",
"author_name": "Sam Snyder",
"author_login": "sambsnyd",
"committed_at": "2026-07-23T10:15:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9188c1359bfc56a87ba0679193b190b286c87225",
"body": "…949)",
"is_bot": false,
"headline": "Add recipes for migrating off a variety of legacy collection types (#…",
"author_name": "Sam Snyder",
"author_login": "sambsnyd",
"committed_at": "2026-07-23T08:11:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bcf245c14aaadff8b55811600364f452cf5db3cd",
"body": null,
"is_bot": false,
"headline": "Add recipe for finding public methods missing javadoc (#948)",
"author_name": "Sam Snyder",
"author_login": "sambsnyd",
"committed_at": "2026-07-23T03:22:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8e4b8c838d327c007050695c55f51470f18adfce",
"body": null,
"is_bot": false,
"headline": "Set Develocity `projectId` to \"openrewrite\" (#947)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-22T15:12:20Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "13da5141b7690ce04b8f5a0767641f23cb2b67e0",
"body": "Co-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "Move Develocity to community.develocity.cloud",
"author_name": "tim@moderne.io",
"author_login": "timtebeek",
"committed_at": "2026-07-22T12:14:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2095f87cfb10bee9076fb42946dc5ff5d2826236",
"body": null,
"is_bot": false,
"headline": "Consistently order test annotations",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-22T09:43:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1b1514253c3991792548fde5f69354d78a2df1a9",
"body": "…ment position on instance methods too (#946)\n\nThe argument-position branch only guarded static methods (via\nshouldRetainOnStaticMethod) against removing a witness whose type\nvariables aren't inferable from the call's own arguments. Instance\nmethods used as arguments skipped that guard entirely, so \n[…]\nesolved.\n\nGeneralize the check to apply regardless of static/instance, matching\nthe reasoning already used for the sibling select-position case.\n\nCo-authored-by: Neil Mushell <neil.mushell@airbnb.com>",
"is_bot": false,
"headline": "UnnecessaryExplicitTypeArguments: retain load-bearing witness in argu…",
"author_name": "neil-mushell",
"author_login": "neil-mushell",
"committed_at": "2026-07-21T15:01:01Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bc8d038cfd4d533758674d57876ce7a1561baf18",
"body": "…rs (#943)\n\n* FixStringFormatExpressions: do not strip args for unresolved placeholders\n\nWhen a String#format/formatted call's format string has zero real `%`\nconversion specifiers, the recipe treated every trailing argument as\ndead code and deleted it. That's wrong when the string contains `{}`\ntok\n[…]\n\n* Retry CI (flaky TypeScript RPC failure unrelated to this change)\n\n* Minimize comments\n\n---------\n\nCo-authored-by: Neil Mushell <neil.mushell@airbnb.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "FixStringFormatExpressions: don't strip args with no matched specifie…",
"author_name": "neil-mushell",
"author_login": "neil-mushell",
"committed_at": "2026-07-17T12:43:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9a1dd5ed8de653f919cc6aca343c47f1d6fbc00d",
"body": "…rence (#942)\n\nWhen a lambda calls an unqualified method belonging to an enclosing\n(outer) class from within an inner class, the recipe emitted `this::m`,\nwhich does not compile since `this` refers to the inner instance. Emit\n`Outer.this::m` in that case.\n\nFixes #941",
"is_bot": false,
"headline": "Qualify `this` for outer-class methods in ReplaceLambdaWithMethodRefe…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-15T09:06:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f3e03f6d367da5305f4f30ea10d8368c0ebaf52c",
"body": "`UnnecessaryThrows` stripped `throws` from a package-private method whose\nown body never throws, breaking a subclass override (in another file) that\ndoes throw the exception, since the LST has no downward override links to\ndetect it.\n\nExtend the \"may be overridden\" guard from `protected` to also cov\n[…]\nge-private methods, and add same-compilation-unit override detection\nso exceptions still declared by a same-file override are retained. Update\nthe recipe description to note the cross-file limitation.",
"is_bot": false,
"headline": "Retain UnnecessaryThrows on overridable methods (#939) (#940)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-14T13:11:06Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e51c700117e6d1bbb4c8a6e32d5f590e457b8e12",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.java.recipes.ExamplesExtractor?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "Extract documentation examples from tests",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-07-14T05:04:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7cb9e591c9810dc99625105bd1bf543f9487cda3",
"body": "…late (#937)",
"is_bot": false,
"headline": "Consolidate UseStringCaseInsensitiveOrder into a single Refaster temp…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-13T08:12:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6108d5fd97f08b527f646f7b19a2ace4c6f445b8",
"body": "Co-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "timtebeek@gmail.com",
"author_login": "timtebeek",
"committed_at": "2026-07-13T07:43:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a303997a0a3b097f2898a588521564e785047df3",
"body": "* Python: add Python tests for selected 7 recipes\n\n* Install the Python engine into a local dir for tests\n\nRegister a LauncherSessionListener that configures the shared rewrite-python\nRPC engine with pipPackagesPath=.rewrite-python (gitignored), so CI installs\nthe exact jar-matching openrewrite package from PyPI instead of requiring it\npreinstalled on the interpreter. REWRITE_PYTHON_PATH overrides the interpreter\nfor testing against locally-built (.dev0) rewrite-python.",
"is_bot": false,
"headline": "Python: add Python tests for selected 7 recipes (#929)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-07-08T13:42:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4aff89879c7e91288110e195a91c3ceb50ae65f1",
"body": "* Keep (Object) cast on array argument at varargs position\n\nAn (Object) cast on an array-typed argument at the varargs position is\nnot redundant: it marks the array as a single varargs element rather\nthan being spread, and silences Error Prone's\nPrimitiveArrayPassedToVarargsMethod. Removing it changes call semantics.\n\nFixes #934\n\n* Merge varargs cast guards into a single check\n\n* Minimize comment",
"is_bot": false,
"headline": "Keep (Object) cast on array argument at varargs position (#935)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-06T13:17:48Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "35794f97b00fc56472ae6c4bef49e4c34420bb0a",
"body": null,
"is_bot": false,
"headline": "Another UseDiamondOperator varargs fix",
"author_name": "Sam Snyder",
"author_login": "sambsnyd",
"committed_at": "2026-07-03T20:57:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "03e2bccadff0ebb66b46495407c3d31e1067ec13",
"body": "…s (#933)\n\nThe 'best practices' commit changed FromLambda.before() to a method\nreference, making it a duplicate of FromMethodReference and breaking\nmatching of the actual lambda form (a, b) -> a.compareToIgnoreCase(b).",
"is_bot": false,
"headline": "Fix UseStringCaseInsensitiveOrder FromLambda template to match lambda…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-07-03T09:09:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1b83d00ac60e689f29cc4dacad43c166ee41046e",
"body": "Co-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "tim@moderne.io",
"author_login": "timtebeek",
"committed_at": "2026-07-03T08:56:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6ed9dfda99335f2763d947d9081bdd1bb70b53d0",
"body": "…1+ (#930)\n\nUseTryWithResources always emitted a named resource variable, even when\nthe resource is never referenced in the try body. Under -Xlint:all -Werror\nthat unused variable fails the build.\n\nWhen the resource is unused in the try body and the target Java version is\n>= 21, emit the unnamed variable _ (JEP 443/456) instead.\n\nFixes #927",
"is_bot": false,
"headline": "Use unnamed variable for unused try-with-resources resource on Java 2…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-30T16:56:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "be7f5943e9a48262a09a5f23e3a69de7a760b005",
"body": "* Add RemoveUnreachableMultiCatchAlternative\n\nRemoves `catch` alternatives that are already covered by an earlier\n`catch` clause in the same `try`. When a multi-catch reduces to a\nsingle alternative it collapses to a regular `catch`; when all\nalternatives are shadowed the entire `catch` clause is dr\n[…]\nemoveImport for shadowed types that are removed, and add a\ntest covering specific catches retained before a trailing catch-all\nException block.\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Add RemoveUnreachableMultiCatchAlternative (#926)",
"author_name": "Steve Elliott",
"author_login": "steve-aom-elliott",
"committed_at": "2026-06-30T12:07:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "4adaeaccd0b50777e8d77c41f8e9ce550b3fdc59",
"body": "…(#928)\n\n* Test case for Groovy and Kotlin\n\n* Test cases for JS\n\n* typescript() in JS tests\n\n* RemoveUnneededBlock to keep padding if possible\n\n* RemoveUnconditionalValueOverwrite to support JS maps\n\n* Fix RemoveDuplicateConditions test case for JS",
"is_bot": false,
"headline": "Tests for Kotlin, Groovy, TS for cross-language code quality recipes …",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-06-30T10:59:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0fb105c4ba732e691d0a45ac082f3d1fe6eccd8d",
"body": "… target type (#925)\n\nThe lambda/member-reference guard only matched when the cast operand was\nthe direct expression. When the operand is wrapped in parentheses (e.g.\n`(Function<Integer, String>) (i -> ...)`), the operand is a\nJ.ControlParentheses/J.Parentheses, so the guard missed it and the cast\nwas removed. For a `var` local the cast is the sole source of the target\ntype, so removal breaks compilation.\n\nUnwrap parentheses before checking for a lambda or method reference.\n\nFixes #924",
"is_bot": false,
"headline": "Fix RemoveRedundantTypeCast removing cast that gives a var lambda its…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-29T11:56:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8674121d72babaa6330c55b41e957b28925eeabb",
"body": "* Add 7 new cross-language code quality recipes\n\nNew recipes implementing SonarQube RSPEC rules with auto-remediation:\n- S1066 CollapsibleIfStatements: merge nested ifs with &&\n- S1656 RemoveSelfAssignment: remove x = x dead assignments\n- S3923 AllBranchesIdentical: collapse if/else where all branch\n[…]\ninitiative covering Java, Go, C#,\nJavaScript, and Python with the same rules in each language.\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>\nCo-authored-by: Steve Elliott <steve@moderne.io>",
"is_bot": false,
"headline": "Add 7 cross-language code quality recipes (#853)",
"author_name": "Jonathan Schnéider",
"author_login": "jkschneider",
"committed_at": "2026-06-26T13:52:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "51c0f0ef9f61a756332ac726bbacbd637d5cfc7a",
"body": "Replaces case-insensitive string comparator lambdas and method\nreferences with the JDK constant String.CASE_INSENSITIVE_ORDER:\n\n- (a, b) -> a.compareToIgnoreCase(b) -> String.CASE_INSENSITIVE_ORDER\n- String::compareToIgnoreCase -> String.CASE_INSENSITIVE_ORDER\n\nBoth transformations are scop\n[…]\n().compareTo(...)) are\ndeliberately not matched, as the rewrite would change semantics.\n\nAlso regenerates recipes.csv (the existing file was already out of\nsync with recipeCsvGenerate output on main).",
"is_bot": false,
"headline": "Add UseStringCaseInsensitiveOrder (#923)",
"author_name": "Steve Elliott",
"author_login": "steve-aom-elliott",
"committed_at": "2026-06-25T11:00:34Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "66ff7d7411c57644aff020ff7c8fcb4c73d6969b",
"body": "Use this link to re-run the recipe: https://app.moderne.io/builder/yESIGzVB0?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "Recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-23T07:37:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ed491a508ab3707ff216bb33d5c409c3d2e40407",
"body": "…ction arguments (#898)\n\n* Fix RemoveUnusedPrivateMethods removing methods called with raw collections\n\nFix RemoveUnusedPrivateMethods removing methods called with raw collections\n Match used methods with relaxed parameter types so raw call sites\n (e.g. Map.keySet()/values()) are not treated as un\n[…]\neUtils.isOfTypeIgnoringGenerics added in openrewrite/rewrite#8035.\n\n---------\n\nCo-authored-by: Muhammad Habiibullah <muhammad.habiibullah@dansmultipro.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Fix RemoveUnusedPrivateMethods deleting methods called with raw colle…",
"author_name": "Muhammad Habiibullah",
"author_login": "habiibullahm",
"committed_at": "2026-06-18T09:40:30Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "333720f8c03114efa828e185be7460c29d42a45e",
"body": "…itch (#922)\n\n`MinimumSwitchCases` threw an `IndexOutOfBoundsException` when visiting a\n`switch` whose `case` arms use Java 21 type-pattern matching (e.g.\n`case Foo.Bar b ->`). Such case labels are not `Expression` instances, so\n`J.Case.getPattern()` calls `get(0)` on an empty list and crashes.\n\nThese switches cannot be converted to `==`/`equals` comparisons anyway, so\n`doRewrite` now bails out when any case label is not a simple expression.\n\nFixes openrewrite/rewrite#8039",
"is_bot": false,
"headline": "Fix `MinimumSwitchCases` crash on Java 21 sealed-interface pattern sw…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-17T10:43:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "83e4fd588b743a7e72d4dbce1927188b0b25718b",
"body": "…(#921)\n\nThe recipe only checked for close() calls in catch blocks, but any\nreference to the resource from a catch clause becomes out of scope once\nthe declaration moves into the try-with-resources header. A resource's\nscope is the try block only (JLS 14.20.3), so the resulting code failed\nto compile.\n\nCloses #920",
"is_bot": false,
"headline": "Fix UseTryWithResources moving resource out of scope for catch block …",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-17T10:42:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3d2b173582bfa494a821db59cd4aac932447bb5a",
"body": "…… (#868)\n\n* Fix false positive in `AnnotateNullableParameters` when parameter dereferenced before null check\n\n* Simplify `NullCheckAndDereferenceVisitor` in `AnnotateNullableParameters`\n\nReplace cursor-message state with plain instance fields keyed by\n`JavaType.Variable` so scope-shadowed identifie\n[…]\nnt lexical dereference tracking and add guard-clause test in AnnotateNullableParameters\n\n---------\n\nCo-authored-by: stefanod <stefano.dallapalma@adyen.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Fix false positive in `AnnotateNullableParameters` when parameter der…",
"author_name": "Stefano Dalla Palma",
"author_login": "stefanodallapalma",
"committed_at": "2026-06-16T20:28:08Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "6d76624d354fae455f635a9dcdbf728e51f5d1bb",
"body": "…ing on a varargs method (#919)",
"is_bot": false,
"headline": "Fix UseDiamondOperator throwing array index out of bounds when operat…",
"author_name": "Sam Snyder",
"author_login": "sambsnyd",
"committed_at": "2026-06-16T00:38:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "dfc6176386b69bed093340028cccbfe49fe998e4",
"body": "* Explain InstanceOfDoubleUnboxinIssue in InstanceOfPatternMatchTest.java\n\n* InstanceOfPatternMatch: preserve double casting\n\n---------\n\nCo-authored-by: Harald Aamot <harald.aamot@sap.com>",
"is_bot": false,
"headline": "`InstanceOfPatternMatch` not to remove double primitive cast (#918)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-06-15T06:42:55Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "49d1bdcc342179b7e6420f3582d4e22269fc238e",
"body": "…yword (#913)\n\nWhen a type cast directly follows a keyword without intervening\nwhitespace (e.g. `throw(Foo)e`), replacing the cast with the new pattern\nvariable identifier fused the tokens into `throwexception`, producing\nuncompilable code. Insert a single space in that case for `throw`,\n`return` and `yield`.\n\nFixes openrewrite/rewrite-apache#135",
"is_bot": false,
"headline": "Preserve space when InstanceOfPatternMatch replaces a cast after a ke…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-12T11:06:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "23503ce7ff7443c7a41b3c7360b0b5f63ffa6ff0",
"body": "…dantTypeCast` (#915)\n\nFixes #914",
"is_bot": false,
"headline": "Preserve raw supertype cast on parameterized argument in `RemoveRedun…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-06-12T10:08:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "64e3203d705fd02f078318e230fab7447d61e04a",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.AddToGitignore?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D#defaults=W3sidmFsdWUiOiIuY29udGV4dC8iLCJuYW1lIjoiZW50cmllcyJ9XQ==\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "git-ignore .context/",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-06-09T11:31:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "01d4a78ff634c52eedd320449b665ebe9dc272af",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.gradle.UpdateGradleWrapper?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZS9PcGVuUmV3cml0ZQ%3D%3D#defaults=W3sidmFsdWUiOiI5LjUuMSIsIm5hbWUiOiJ2ZXJzaW9uIn0seyJ2YWx1ZSI6ImJpbiIsIm5hbWUiOiJkaXN0cmlidXRpb24ifSx7InZhbHVlIjoiYmFmYzE0MWI2MTlhZDYzNTBmZDk3NWZjOTAzMTU2ZGQ1YzE1MTk5OGNjOGIwNThlOGMxMDQ0YWI1ZjdiMDMxZiIsIm5hbWUiOiJkaXN0cmlidXRpb25DaGVja3N1bSJ9XQ==\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "Update Gradle wrapper 9.5.1",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-28T19:53:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "421318a90ebb5bd798ce18154e2d9e3f319222f7",
"body": "…plicitTypeArguments` (#911)\n\n`UnnecessaryExplicitTypeArguments` removed an explicit type witness from a\ngeneric method invocation even when that invocation was the select (receiver)\nof another method invocation. In that position there is no target type to drive\ninference, so the witness is load-bea\n[…]\ne witness is retained unless the type variables\nare inferable from the call's own arguments; the existing argument-position and\nstatic-method behavior is preserved by reusing the same inference check.",
"is_bot": false,
"headline": "Retain load-bearing type witness in select position in `UnnecessaryEx…",
"author_name": "Knut Wannheden",
"author_login": "knutwannheden",
"committed_at": "2026-05-28T18:49:48Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c4880820742ec1635e75e6d1d4fa3cdc2f67c4ee",
"body": null,
"is_bot": false,
"headline": "Regenerate recipes.csv (#910)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-28T18:36:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "829a5a526a488ab81416d56a8127a703277dbdc0",
"body": "…mbdaWithMethodReference` (#909)\n\nPreviously the recipe used the method's declaring type to construct\nthe class name, which produced uncompilable references like\n`Base::getValue` (with an inaccessible import) when the declaring\nclass was package-private and the receiver was a public subclass.",
"is_bot": false,
"headline": "Use receiver type for unbound instance method reference in `ReplaceLa…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-28T10:28:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5ab23a2e5c814612ded17b162d7d14638b6ef3b8",
"body": "The recipe's `CommentVisitor` is a `JavaIsoVisitor` that crashes in\n`TreeVisitorAdapter` when adapted to Python `Py.CompilationUnit`\nsources. Add a `PythonFileChecker` and use it as a precondition to\nexclude Python files while keeping Java, Kotlin, and Groovy support.",
"is_bot": false,
"headline": "Skip Python sources in `CombineSemanticallyEqualCatchBlocks` (#908)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-28T10:24:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e4bcb093e1d3b067816f17208ed0ea839f304ef2",
"body": "…Cast` (#905)\n\nA raw cast like `(B) b` where `b` is `B<T>` is an intentional unchecked\nconversion; removing it changes overload and type-inference behavior\nwhen the receiver is itself parameterized (e.g. `I<? extends T>`).",
"is_bot": false,
"headline": "Preserve raw cast on parameterized expression in `RemoveRedundantType…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-27T08:20:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "62e6a08b356ed8d212c2572bacd17a5f34300de8",
"body": "…eCast` (#904)\n\nThe overload guard only ran when `castType != expressionType`, so an\n`(Object) value` cast on an `Object` argument fell through and was removed,\nmaking `log(String, Object...)` vs `log(String, Throwable)` calls ambiguous.",
"is_bot": false,
"headline": "Preserve cast on argument to overloaded method in `RemoveRedundantTyp…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-26T09:17:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3ef523d451773b1caf7b19b69bc75a6134de3ec0",
"body": "…(#903)\n\n* Guard `instanceof` to `Class::isInstance` conversion on lambda arity\n\n`ReplaceLambdaWithMethodReference` was converting any single-`instanceof`\nlambda body to `X.class::isInstance` regardless of the lambda's arity or\nwhich identifier was being tested. A `BiPredicate<String, Throwable>` li\n[…]\ny on the resolved `JavaType.Variable`. Switching\nboth to `SemanticallyEqual.areEqual` aligns all three sibling\nbranches on a single, robust check and removes the string match\nfrom the TypeCast branch.",
"is_bot": false,
"headline": "Guard `instanceof` to `Class::isInstance` conversion on lambda arity …",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-26T09:13:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "03d153e5ce9be36413ef289b705d716f86431686",
"body": "…` (#896)\n\n* Replace `var` with interface type in `UseLambdaForFunctionalInterface`\n\nA lambda is a poly expression and needs an explicit target type from\nthe declaration (JLS 14.4.1, 15.27.1), but `var` borrows its type from\nthe right-hand side. Converting `var x = new Foo() {...}` to a lambda\nwhile\n[…]\n that `maybeAddCast` and the\nnew `visitVariableDeclarations` share into a `resolveDiamond` helper, and\ninline the single-use `isVarType` predicate.\n\n* Return directly instead of reassigning the result",
"is_bot": false,
"headline": "Replace `var` with interface type in `UseLambdaForFunctionalInterface…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-18T21:10:20Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "8e930b091e48eafefb4e327b9346f96996a9d54d",
"body": "… (#893)\n\n* Strip diamond operator from cast in `UseLambdaForFunctionalInterface`\n\nThe diamond operator is only valid after `new` (JLS 15.9), not in a cast\nexpression (JLS 15.16). When converting `new Foo<>() {...}` to a lambda\nthat required a cast, the recipe produced invalid `(Foo<>) ...`.\n\n* Rebu\n[…]\nund when\ninferring a diamond's type arguments. Reduce the helper to the only\nreachable path (`FullyQualified`) and add a multi-arg test.\n\n* Drop unused `Space` param and cache `fq.getTypeParameters()`",
"is_bot": false,
"headline": "Strip diamond operator from cast in `UseLambdaForFunctionalInterface`…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-18T09:30:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "857aab2b9fe977020797c826f99a7d74b01dbefb",
"body": "`JavaType.Class#getAnnotations()` returns `List<FullyQualified>`, whose\nelements can be `JavaType.ShallowClass` rather than `JavaType.Annotation`.\nCheck the runtime type before casting to avoid a `ClassCastException`\nwhen the `@Target` meta-annotation is only available as a shallow class.",
"is_bot": false,
"headline": "Guard cast to `JavaType.Annotation` in `ReorderAnnotations` (#894)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-18T09:19:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d99ed6f0936dcf8445570ea2e08e8beee87d198a",
"body": "…#891)\n\n* Preserve cast on generic method invocation in overloaded outer call\n\nWhen a cast wraps a generic method invocation whose declared return is a\ntype variable (e.g. `(Object) cursor.getValue()` where `<T> T getValue()`),\nthe cast pins the inferred return type so an overloaded outer call like\n\n[…]\nbranch\nand the existing Lambda-body branch. Also hoist the cheap\n`hasMethodOverloading` check above the loop so non-overloaded parent\ncalls short-circuit without scanning the declaring type's methods.",
"is_bot": false,
"headline": "Preserve cast on generic method invocation in overloaded outer call (…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-16T11:28:39Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d79cdd4d3fcefd1b18f8f85fa03f5663239f663f",
"body": "…(#890)\n\n`RemoveRedundantTypeCast` was stripping `(Integer) null` from\n`property.set((Integer) null)` on a `Property<Integer>`, breaking\ncompilation because `Property<T>` declares both `set(T)` and\n`set(Provider<? extends T>)`. The `hasMethodOverloading` guard missed\nthis case: when the receiver is \n[…]\nrized, `getDeclaringType()`\nreturns a `JavaType.Parameterized`, which the `JavaType.Class` filter\ndiscarded. Widen to `JavaType.FullyQualified` so methods on\nparameterized receivers are inspected too.",
"is_bot": false,
"headline": "Detect overloads on parameterized receiver in `hasMethodOverloading` …",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-16T11:14:56Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "5e79cd36a83bd77e86579577ea9fa9c15d2a0509",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-16T10:29:16Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7bea420eb0b7f4c0bc4f0bfe56025e920b5f800b",
"body": "…ryExplicitTypeArguments` (#889)\n\nWhen a static method declares a type parameter but takes no arguments\n(e.g. `<T> T any()`), the type parameter cannot be inferred from\ncall-site arguments. The existing `shouldRetainOnStaticMethod` guard\nrelied on `JavaType.Method.getDeclaredFormalTypeNames()`, which the\nparser does not always populate, so the guard would incorrectly allow\nremoval and break overload/inference in the enclosing call.",
"is_bot": false,
"headline": "Retain explicit type arguments on no-arg static methods in `Unnecessa…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-15T17:09:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "436e8c246033ab48314942869d2f5a26f9895bf0",
"body": "… (#888)\n\nA cast like `(String) null` passed as the last argument to a varargs\nmethod (e.g. `Method.invoke(Object, Object...)`) is required to\ndisambiguate between passing `null` as the entire array and passing a\nsingle null element. Skip removal when the expression is a `null`\nliteral at the last position whose parameter is an array.",
"is_bot": false,
"headline": "Preserve `null` cast at varargs position in `RemoveRedundantTypeCast`…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-15T12:27:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0f017bd5d8bcfbfdb33ec4eaff6091eb99db09de",
"body": "…to parameterized types (#887)\n\nThe guard against converting `() -> new X()` to `X::new` when `X` has\nmultiple constructors only checked `JavaType.Class`, missing diamond\nexpressions like `new EntityIdForRepositoryVisitor<>()` whose type is\n`JavaType.Parameterized`. The resulting `::new` could become ambiguous\nbetween overloaded `Supplier`/`Function` targets.",
"is_bot": false,
"headline": "Extend multi-constructor guard in `ReplaceLambdaWithMethodReference` …",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-15T11:13:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3f61726652d1cc85265508a03c28cdf96bbae160",
"body": "A class with only private constructors can still be subclassed from within its own body via anonymous classes. Making such a class `final` produces uncompilable code.\n\nFixes #885",
"is_bot": false,
"headline": "Skip `FinalClass` when class has anonymous inner subclasses (#886)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-13T16:00:57Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "932cca99b37a0a32f1fd88878be83afee4e19e34",
"body": "…orToValueOf` (#883)\n\n`valueOf` may return cached instances, so the rewrite is not behavior-preserving\nfor code that compares boxed values via reference identity, uses\n`System.identityHashCode`, or synchronizes on the boxed value.\n\nRefs #880",
"is_bot": false,
"headline": "Document identity-semantics caveat on `PrimitiveWrapperClassConstruct…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-08T09:10:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7ba220a764deb417fef3c1b273665665f145b6f3",
"body": "…erence (#882)\n\nWhen the first statement is a variable declaration and the following\ncompound assignment's right-hand side references the variable being\ndeclared, folding produced an initializer that read the variable before\nit was assigned, e.g. `int result = state ^ result >>> 1;`.",
"is_bot": false,
"headline": "Skip `SimplifyConsecutiveAssignments` when initializer would self-ref…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-06T16:00:50Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d8acf8bb0ad7bd8521b36ee48096291680791f89",
"body": "…` crashes (#879)\n\nTwo minimized repros for the `ControlFlowIllegalStateException`s observed in\nflagship runs against `moderneinc/moderne-intellij-plugin` (Kotlin),\n`moderneinc/rewrite-sql`, and `openrewrite/rewrite-templating`:\n\n- Anonymous class body containing multiple methods whose bodies return\n[…]\nenrewrite/rewrite-analysis`. The\nKotlin test ends up replacing `Stack` with `Deque` because the function only\nreturns the boolean, not the stack — so we just assert that the recipe runs\nto completion.",
"is_bot": false,
"headline": "Add regression tests for `ReplaceStackWithDeque` against `ControlFlow…",
"author_name": "Knut Wannheden",
"author_login": "knutwannheden",
"committed_at": "2026-05-06T08:41:04Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "095656ff1597a05aa8fad91a5afcf5a3288c466f",
"body": "… (#875)\n\nThe recipe previously transformed `() -> field != null` into\n`Objects::nonNull` even when the lambda had no parameter or the null\ncheck referred to a captured field rather than the lambda parameter,\nproducing code that no longer compiled.",
"is_bot": false,
"headline": "Skip `Objects::nonNull`/`isNull` when lambda parameter does not match…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-05T22:34:23Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "209f642ee7f8df7c7e7000060dba7f740aebc18a",
"body": "* Preserve `(Object)` bridge cast for unchecked generic casts\n\nWhen a cast is wrapped by another cast and neither the outer cast type\nnor the inner expression type are assignable to one another, the inner\ncast is acting as a bridge for an unchecked generic conversion (e.g.\n`(List<String>) (Object) v\n[…]\n cast, primitive widen-then-narrow, controlling overload\nresolution — so just preserve. Also skip both `J.Parentheses` and\n`J.ControlParentheses` when walking up so parenthesized variants are\ncovered.",
"is_bot": false,
"headline": "Preserve `(Object)` bridge cast for unchecked generic casts (#876)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-05T16:30:55Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d2bf70305b2e6ec251d2323374ac4c68ce7d1369",
"body": "Without the cast, calls like `<T extends SourceFile> T withSourcePath(Path)`\ninside a lambda lose `T` to its bound during outer inference (e.g.\n`Optional.map(...).ifPresent(generated::add)`), causing compilation errors.\n\nFixes #871",
"is_bot": false,
"headline": "Preserve casts pinning generic-method return type in lambdas (#872)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-04T09:10:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9f0285237c56af092bfa0fa69a98aa8c8e021bda",
"body": null,
"is_bot": false,
"headline": "Use rewrite-java-21 for test runtime (#870)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-05-01T13:31:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "30a60ba05420d299cc94cd4fcf334c8101094404",
"body": "* OpenRewrite recipe best practices\n\nUse this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>\n\n* Use rewrite-java-25 test ru\n[…]\nintroduced `_ ->` broke `compileTestJava`. Revert those two lambda\nparameters back to `cu ->` and bump the test runtime parser to\nrewrite-java-25.\n\n---------\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices (#869)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-30T13:47:37Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "98d350e9a56c024a6fc7700fbe09bddadc956328",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-29T09:59:10Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d3e09e9fee25b62cf4d082539091c24db954910e",
"body": "…ClassConstructor` (#867)\n\nEnables meta-annotation matching so classes annotated with `@TestConfiguration`,\n`@SpringBootApplication`, and any user-defined stereotype layered on top of\n`@Configuration` are also skipped.",
"is_bot": false,
"headline": "Skip meta-annotated `@Configuration` in `FinalClass` and `HideUtility…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-28T11:39:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ab8ff8d81a64366ec8c8f796cc82ab4e4f72d709",
"body": "Refuse to merge a `close()` into try-with-resources when non-close\nstatements precede it in the finally block. Try-with-resources runs the\nauto-close before the finally, so those statements would otherwise move\nfrom before to after the close, changing semantics.",
"is_bot": false,
"headline": "Preserve statement order in `UseTryWithResources` (#866)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-28T10:53:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "90e4a600e68fb164750c3f4e031db8e884d37108",
"body": "…… (#865)\n\n* bugfix: false positive in AnnotateNullableParameters when parameter is dereferenced before null check\n\n* Check all arguments for null-checked parameters\n\nAddresses review feedback: custom null-checkers may accept the parameter in a position other than first (e.g., `assertNotNull(message, param)`).\n\n---------\n\nCo-authored-by: stefanod <stefano.dallapalma@adyen.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "bugfix: false positive in AnnotateNullableParameters when parameter …",
"author_name": "Stefano Dalla Palma",
"author_login": "stefanodallapalma",
"committed_at": "2026-04-23T19:22:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "b315bbcda4429a590a4ec4a9677706446da88f0f",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.java.recipes.ExamplesExtractor?organizationId=QUxML09wZW4gU291cmNlL09wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "Extract documentation examples from tests",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-04-21T07:05:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ba38b4c9ad206562efc3d18fb0457ba379cd560",
"body": "…ent (#864)\n\nCovers the dataflow crash fixed in openrewrite/rewrite-analysis#95,\nwhere the recipe threw `Unable to create DataFlowNode` when a `Stack`\nvariable shared a method with a call that passed `this` as an argument.",
"is_bot": false,
"headline": "Add regression test for `ReplaceStackWithDeque` crash on `this` argum…",
"author_name": "Knut Wannheden",
"author_login": "knutwannheden",
"committed_at": "2026-04-21T06:48:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "78afc2590d0bfb63657e7f023eb0569b29ee8af2",
"body": "…a lambda initializer (#862)\n\nSkip private fields whose only assignment is in the constructor body when they\nare read inside a lambda or anonymous class in an instance field initializer or\ninstance initializer block. Since initializers run before the constructor body,\nfinalizing such fields breaks javac's definite assignment analysis.\n\nFixes #861",
"is_bot": false,
"headline": "Fix FinalizePrivateFields breaking compilation when field is read in …",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-17T13:04:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3b2d84764c295a44ef84656fa925e302194aca86",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-17T11:01:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2a0baac34f3445652b24b4dea6e428d8cc6719eb",
"body": "…es close() (#863)\n\nWhen a try-catch contains a nested try-with-resources, the outer catch may\nhandle exceptions thrown by the resource's close() method. The visitor now\ncollects those exceptions so the outer catch is preserved.\n\nFixes #677",
"is_bot": false,
"headline": "Fix UnnecessaryCatch removing IOException for nested try-with-resourc…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-17T09:05:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "47094c2f1f455cd26fcbddb5cc823010b5fd20bf",
"body": "* Handle chained addition in PreferIncrementOperator\n\nCloses #696\n\nWalk the left spine of binary +/- expressions to find the assigned\nvariable as the leftmost operand, enabling transformations like\n`x = x + a + b + 1` → `x += a + b + 1`.\n\n* Regenerate recipes.csv\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Handle chained addition in PreferIncrementOperator (#816)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-04-17T09:01:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e097fabe401e6fc226cd76721d2007e6c3f34ab1",
"body": null,
"is_bot": false,
"headline": "Add tests confirming #20 is fixed (#860)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-04-16T09:39:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3710118f705c1a74925dfc989b48edf014dbfdb9",
"body": null,
"is_bot": false,
"headline": "Test for if-else, fix do-while NeedBraces (#859)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-04-16T09:12:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c6ebfd47840eb53d792ebe6f153676be1942363b",
"body": "* Add S1185 recipe: Remove methods that only call super\n\nImplements RSPEC-S1185 to detect and remove methods that override a parent\nmethod but only delegate to super with the same arguments. Includes 12\ncomprehensive test cases covering positive and negative scenarios.\n\n* Simplify argumentsMatchPara\n[…]\n @Transactional retention test\n\nRemove removeMethodWithOnlyOverrideAnnotation which duplicated existing\ncoverage. Add test verifying methods with semantic annotations like\n@Transactional are retained.",
"is_bot": false,
"headline": "Add S1185 recipe: Remove methods that only call super (#837)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-15T14:22:45Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e9d90e732ac1c227013b0657f375cd41d9776983",
"body": "* Add S2209/S3252 recipe: Static members should be accessed via class name\n\nImplements OpenRewrite recipe to replace static field/method access through instance references with access via the declaring class name. Transforms instance.staticField to ClassName.staticField and instance.staticMethod() t\n[…]\nted class handling with the existing utility,\nwhich correctly handles type attribution, parameterized types, and\nlocal classes.\n\n* Add inner class and anonymous class tests for StaticAccessViaInstance",
"is_bot": false,
"headline": "Add S2209/S3252 recipe: Static members via class name (#836)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-13T22:27:25Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "ee4199a5dde3f97d669629e4be417c6381efdd93",
"body": "* Add RemoveUnusedLabels recipe (RSPEC-S1065)\n\nRemove labels that are not referenced by any break or continue statement. The labeled statement is preserved, with the label removed.\n\nIncludes 6 test cases covering unused labels on loops and blocks, labels referenced by break/continue, and partial rem\n[…]\nenarios.\n\n* Update recipes.csv with RemoveUnusedLabels entry\n\n* Use idiomatic reduce() pattern for subtree scanning\n\n* Move @Getter to class level; invert if condition\n\n* Update copyright year to 2026",
"is_bot": false,
"headline": "Add RemoveUnusedLabels recipe (RSPEC-S1065) (#835)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-13T15:53:41Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "df3a60bce33e4ea8e29adb1e91a582e6fa393f1b",
"body": "* Add SillyEqualsCheck recipe (RSPEC-S2159)\n\nImplements SonarQube rule S2159: detects `.equals()` calls that always return false due to incompatible types. The recipe transforms:\n- `x.equals(null)` → `x == null` (with negation handling)\n- `arr1.equals(arr2)` → `Arrays.equals(arr1, arr2)` for arrays\n\n[…]\ncursor walk through J.Parentheses nodes. This\ncannot throw on unlisted AST contexts.\n\n* Remove redundant @Getter annotations implied by @Value\n\n* Use J.Literal.isLiteralValue(arg, null) for null check",
"is_bot": false,
"headline": "Add SillyEqualsCheck recipe (RSPEC-S2159) (#834)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-13T15:53:28Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "e59af63412317c010d396cc39ec51192bb31c3c2",
"body": "…(#858)\n\n* Fix UnnecessaryExplicitTypeArguments within lambda return statements (#670)\n\n* Extract findMethodIfUnambiguous and getLambdaReturnType methods",
"is_bot": false,
"headline": "Fix UnnecessaryExplicitTypeArguments within lambda return statements …",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-13T10:29:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "58455164cd5ce54151529b5aaa50837dabfa9ee5",
"body": "… (#857)\n\n* Fix FinalizeLocalVariables crash on Kotlin/Groovy top-level variables (#702)\n\n* Merge Kotlin/Groovy tests into main FinalizeLocalVariablesTest",
"is_bot": false,
"headline": "Fix FinalizeLocalVariables crash on Kotlin/Groovy top-level variables…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-12T19:41:42Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8686b01d7198c984740ec012e675c0765e302516",
"body": "…#856)",
"is_bot": false,
"headline": "Fix RenameExceptionInEmptyCatch crash on Kotlin/Groovy files (#701) (…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-12T19:31:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cbc1692de925ef8138291005cb6b856820e0f0f3",
"body": "… scoping (#855)\n\n* Fix InstanceOfPatternMatch duplicate pattern variable names with flow scoping\n\nTrack introduced pattern variable names across statements within a method\nto avoid generating duplicates when Java's flow scoping keeps an earlier\npattern variable in scope (e.g., else branch with retu\n[…]\n\n* Add ROOT_VALUE guard and extract trackIntroducedName helper\n\nAdd Cursor.ROOT_VALUE to dropParentUntil predicate for safety, and\ndeduplicate the pattern variable tracking logic into a helper method.",
"is_bot": false,
"headline": "Fix InstanceOfPatternMatch duplicate pattern variable names with flow…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-12T13:07:33Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "77719d2d8834629dacdf89eaf66c0b8c6ed47c91",
"body": "* Add recipe to enforce space after // in single-line comments\n\n* fix review comments\n\n* Use ListUtils.map as suggested by reviewer\n\n* fix review comments: use @Getter fields, skip block comments, update copyright year\n\n* Invert instanceof check and combine with isMultiline guard\n\n* Skip noinspection and region/endregion IDE comments\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Add space after // in single-line comments (#854)",
"author_name": "Avimta Likhitkar",
"author_login": "avimta",
"committed_at": "2026-04-11T12:58:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e51f2b46bbadc70f8d65effc4085b7e8ae4939ec",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-10T08:00:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2f72e68392286f0d87db97ccdbdbed5cc714c8e4",
"body": "- FallThrough: don't add breaks inside nested switch expressions (#14)\n- MinimumSwitchCases: preserve comments from default case (#6)\n- MinimumSwitchCases: redeclare variables in else blocks (#687)\n- InlineVariable: add test confirming enum arrays are not inlined (#9)",
"is_bot": false,
"headline": "Fix switch-related recipe bugs (#6, #9, #14, #687) (#852)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-09T12:23:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "92a5960205d1d4e928292138f042db760598c466",
"body": "…on tests (#851)\n\n* Fix EmptyBlock, FinalClass, HideUtilityClassConstructor and add regression tests\n\n- EmptyBlock: stop adding unnecessary `continue;` to empty while/do-while loops (#570)\n- FinalClass: skip classes annotated with @Configuration (#729)\n- HideUtilityClassConstructor: skip @Configuration classes (#729)\n- Add regression tests for #7, #221 confirming they are already fixed\n\n* Remove unused loop visitor methods\n\nRemoved unused visitWhileLoop and visitDoWhileLoop methods.",
"is_bot": false,
"headline": "Fix EmptyBlock, FinalClass, HideUtilityClassConstructor; add regressi…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-09T12:19:45Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "421c07ef3de89b3f159fb5db16a675692da8408e",
"body": "* Enrich recipe descriptions with \"why\" rationale for RSPEC-tagged rules\n\nThe RSPEC tags on static analysis recipes used to link to SonarSource's\npublic rule documentation, but those URLs have been decommissioned.\nRather than adding broken links, this enriches each recipe's description\nfield with 1-\n[…]\n the\nrecipes self-documenting. Descriptions for 98 recipes were updated;\n9 were skipped because they already had thorough rationale.\n\n* Reformat description strings to wrap at ~120 characters per line",
"is_bot": false,
"headline": "Enrich recipe descriptions with rationale (#850)",
"author_name": "Jonathan Schnéider",
"author_login": "jkschneider",
"committed_at": "2026-04-08T23:22:27Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c02f72d04f59fed8619b8921a6caebfb84797fef",
"body": "…ons pointing to itself (#849)\n\n* Avoid invalid x=x variable declarations\n\n* A more involved case\n\n* Order of clauses shouldn't decide",
"is_bot": false,
"headline": "`InstanceOfPatternMatch` to avoid providing invalid variable definiti…",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-04-08T19:05:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1b97fad6812098e73f10e8be6d112d2fec5478bf",
"body": null,
"is_bot": false,
"headline": "Test for issue 276 (#848)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-04-08T18:33:37Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "901ba810cf2b9822d93975e2c712fba77567ac76",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-08T08:21:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "927f25ddd3c48144a67aebd3c286e514e7a4ab49",
"body": null,
"is_bot": false,
"headline": "Skip `InstanceOfPatternMatch` for try-with-resources casts (#847)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-04-07T11:57:51Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4ded8a7c8f826d5a6cb2050987127b86b2a39ef0",
"body": "…notation placement issues (#845)\n\n* fix annotations duplication and position\n\n* Align nullable detection with AnnotateNullableParameters\n\n- Replace NULLABLE_ANNOTATION_SIMPLE_NAMES set with case-insensitive\n contains(\"null\") check to handle custom annotations (e.g. @NullAllowed)\n- Replace NON_TYPE\n[…]\nbleParameters\n- Update tests to expect custom/unknown annotations as declaration-target\n\n---------\n\nCo-authored-by: stefanod <stefano.dallapalma@adyen.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Improve AnnotateNullableMethods to avoid duplicate annotations and an…",
"author_name": "Stefano Dalla Palma",
"author_login": "stefanodallapalma",
"committed_at": "2026-04-01T09:46:58Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "c6a7799a9818adcaeab2c09987a5186766171928",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.java.recipes.UseJavaTemplateStaticApply?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "Use `JavaTemplate.apply()` static method (#846)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-03-31T19:03:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "78f9ddce1bf80477da448252d70f5a7eb2cf8d66",
"body": "Replace stored JavaTemplate fields with inline builder chains across 8\nrecipes, eliminating unnecessary visitor state.",
"is_bot": false,
"headline": "Inline JavaTemplate fields at call sites (#844)",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-03-31T16:04:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3f3cd50a7c676b71855624e652347aca7ba992c5",
"body": "… annotation placement issues (#843)\n\n* fix duplicate nullable annotations\n\nfix annotation position\n\n* Replace known nullable annotations list with simple name matching\n\nInstead of maintaining a hardcoded list of 13 nullable annotation FQNs,\ndetect any annotation whose simple name contains \"null\" (c\n[…]\n duplication/conflicts.\n\n* Use .reduce for immediate return in hasNullRelatedAnnotation\n\n---------\n\nCo-authored-by: stefanod <stefano.dallapalma@adyen.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
"is_bot": false,
"headline": "Improve AnnotateNullableParameters to avoid duplicate annotations and…",
"author_name": "Stefano Dalla Palma",
"author_login": "stefanodallapalma",
"committed_at": "2026-03-31T11:58:44Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "0a3f00142638a87cb53e2b291147b437a3dfebd9",
"body": null,
"is_bot": false,
"headline": "Fix compilation after new args to Cs.CompilationUnit (#842)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-03-26T19:18:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0d114b7f08e4917d9f8d260328ac9e53e51b1954",
"body": null,
"is_bot": false,
"headline": "No longer expected to fail (#841)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-03-26T08:18:33Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "941c8431cf6e3f0d00a785a23bbc46baf81eb325",
"body": null,
"is_bot": false,
"headline": "Remove @Disabled tests (#840)",
"author_name": "Greg Oledzki",
"author_login": "greg-at-moderne",
"committed_at": "2026-03-25T14:40:54Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c82f961b43fa48611e1931bf499d9b6d3033c34d",
"body": "…n (#839)\n\n* SimplifyBooleanExpression: don't simplify nullable boolean comparisons in Kotlin\n\nThe `shouldSimplifyEqualsOn` override previously only checked for the\n`IsNullSafe` marker on method invocations (e.g. `x?.fun() == true`), but\nmissed plain nullable boolean comparisons like `nullableBoolea\n[…]\n comparisons.\n\nFixes #303\n\n* SimplifyBooleanExpression: delegate to super.shouldSimplifyEqualsOn for Java files\n\n* Apply suggestions from code review\n\nCo-authored-by: Tim te Beek <timtebeek@gmail.com>",
"is_bot": false,
"headline": "SimplifyBooleanExpression: skip nullable boolean comparisons in Kotli…",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-03-24T10:17:00Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "879b179ea0bb3ca760c2205ccf9ed93db7109fd9",
"body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
"is_bot": false,
"headline": "OpenRewrite recipe best practices",
"author_name": "Tim te Beek",
"author_login": "timtebeek",
"committed_at": "2026-03-23T08:56:00Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5d7e7b1abb82cbd6e65a7f2d68fd86f03673e1e3",
"body": "* Add ExplicitThis recipe to make 'this.' prefix explicit.\n\n* Simplify ExplicitThis recipe using existing utilities\n\n- Replace magic number 0x0008L with hasFlags(Flag.Static) and hasModifier()\n- Use JavaElementFactory.newThis() instead of manual identifier construction\n- Use TypeUtils.isOfType() for\n[…]\nlight polish\n\n* Add a test to check for shadowing of variables\n\n* Slight polish\n\n* Update docs\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>\nCo-authored-by: Knut Wannheden <knut@moderne.io>",
"is_bot": false,
"headline": "Add ExplicitThis recipe to make `this.` prefix explicit. (#791)",
"author_name": "Craig P. Motlin",
"author_login": "motlin",
"committed_at": "2026-03-21T22:16:47Z",
"body_truncated": true,
"is_coding_agent": false
}
],
"releases_count": 91,
"commits_last_year": 253,
"latest_release_at": "2026-07-14T05:34:02Z",
"latest_release_tag": "v2.39.0",
"releases_from_tags": false,
"days_since_last_push": 1,
"active_weeks_last_year": 47,
"days_since_latest_release": 11,
"mean_days_between_releases": 10.7
},
"community": {
"has_readme": true,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 75,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"ecosystem": {
"packages": []
},
"popularity": {
"forks": 102,
"stars": 58,
"watchers": 7,
"fork_history": {
"days": [
{
"date": "2023-05-03",
"count": 1
},
{
"date": "2023-05-06",
"count": 2
},
{
"date": "2023-05-09",
"count": 1
},
{
"date": "2023-05-17",
"count": 1
},
{
"date": "2023-05-21",
"count": 1
},
{
"date": "2023-05-26",
"count": 1
},
{
"date": "2023-05-27",
"count": 1
},
{
"date": "2023-06-06",
"count": 1
},
{
"date": "2023-06-13",
"count": 1
},
{
"date": "2023-06-19",
"count": 1
},
{
"date": "2023-06-29",
"count": 1
},
{
"date": "2023-06-30",
"count": 1
},
{
"date": "2023-08-10",
"count": 1
},
{
"date": "2023-09-27",
"count": 1
},
{
"date": "2023-10-02",
"count": 1
},
{
"date": "2023-10-03",
"count": 1
},
{
"date": "2023-10-13",
"count": 1
},
{
"date": "2023-10-14",
"count": 1
},
{
"date": "2023-10-16",
"count": 1
},
{
"date": "2023-11-02",
"count": 1
},
{
"date": "2023-11-16",
"count": 1
},
{
"date": "2023-12-30",
"count": 1
},
{
"date": "2023-12-31",
"count": 1
},
{
"date": "2024-01-10",
"count": 1
},
{
"date": "2024-01-15",
"count": 1
},
{
"date": "2024-01-17",
"count": 1
},
{
"date": "2024-01-20",
"count": 1
},
{
"date": "2024-01-21",
"count": 1
},
{
"date": "2024-01-22",
"count": 1
},
{
"date": "2024-01-28",
"count": 1
},
{
"date": "2024-02-17",
"count": 1
},
{
"date": "2024-03-10",
"count": 1
},
{
"date": "2024-03-18",
"count": 1
},
{
"date": "2024-05-11",
"count": 1
},
{
"date": "2024-05-13",
"count": 1
},
{
"date": "2024-05-19",
"count": 1
},
{
"date": "2024-06-13",
"count": 1
},
{
"date": "2024-06-29",
"count": 1
},
{
"date": "2024-07-04",
"count": 2
},
{
"date": "2024-08-20",
"count": 1
},
{
"date": "2024-10-01",
"count": 1
},
{
"date": "2024-10-02",
"count": 1
},
{
"date": "2024-10-12",
"count": 1
},
{
"date": "2024-10-14",
"count": 1
},
{
"date": "2024-10-18",
"count": 1
},
{
"date": "2024-10-30",
"count": 1
},
{
"date": "2024-11-17",
"count": 1
},
{
"date": "2024-11-25",
"count": 1
},
{
"date": "2024-12-03",
"count": 1
},
{
"date": "2024-12-21",
"count": 1
},
{
"date": "2024-12-23",
"count": 1
},
{
"date": "2025-01-13",
"count": 1
},
{
"date": "2025-01-24",
"count": 2
},
{
"date": "2025-02-07",
"count": 1
},
{
"date": "2025-03-25",
"count": 1
},
{
"date": "2025-03-29",
"count": 1
},
{
"date": "2025-04-08",
"count": 1
},
{
"date": "2025-04-27",
"count": 1
},
{
"date": "2025-05-04",
"count": 1
},
{
"date": "2025-05-05",
"count": 1
},
{
"date": "2025-05-07",
"count": 1
},
{
"date": "2025-05-15",
"count": 1
},
{
"date": "2025-05-19",
"count": 1
},
{
"date": "2025-05-26",
"count": 1
},
{
"date": "2025-05-28",
"count": 1
},
{
"date": "2025-05-29",
"count": 1
},
{
"date": "2025-06-03",
"count": 1
},
{
"date": "2025-06-08",
"count": 1
},
{
"date": "2025-06-16",
"count": 1
},
{
"date": "2025-06-18",
"count": 1
},
{
"date": "2025-06-19",
"count": 2
},
{
"date": "2025-07-07",
"count": 1
},
{
"date": "2025-07-10",
"count": 1
},
{
"date": "2025-07-17",
"count": 1
},
{
"date": "2025-07-19",
"count": 1
},
{
"date": "2025-07-20",
"count": 1
},
{
"date": "2025-07-25",
"count": 1
},
{
"date": "2025-08-04",
"count": 1
},
{
"date": "2025-08-11",
"count": 1
},
{
"date": "2025-08-28",
"count": 1
},
{
"date": "2025-10-26",
"count": 1
},
{
"date": "2025-11-02",
"count": 1
},
{
"date": "2025-11-09",
"count": 1
},
{
"date": "2025-11-20",
"count": 1
},
{
"date": "2025-11-26",
"count": 1
},
{
"date": "2026-01-04",
"count": 1
},
{
"date": "2026-03-23",
"count": 1
},
{
"date": "2026-04-10",
"count": 1
},
{
"date": "2026-04-16",
"count": 1
},
{
"date": "2026-05-20",
"count": 1
},
{
"date": "2026-06-12",
"count": 1
},
{
"date": "2026-07-01",
"count": 1
},
{
"date": "2026-07-10",
"count": 1
},
{
"date": "2026-07-16",
"count": 1
},
{
"date": "2026-07-17",
"count": 1
},
{
"date": "2026-07-19",
"count": 1
},
{
"date": "2026-07-21",
"count": 1
}
],
"complete": true,
"collected": 101,
"total_forks": 102
},
"star_history": null,
"open_issues_and_prs": 122
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [
"build.gradle.kts"
],
"largest_source_bytes": 88413,
"source_files_sampled": 403,
"oversized_source_files": 2,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 8599
},
"dependencies": {
"manifests": [
"build.gradle.kts"
],
"advisories": {
"error": "No resolved dependencies to assess",
"scope": "repository_graph",
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 0,
"direct_affected_count": 0
},
"ecosystems": [
"maven"
],
"dependencies": [],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [],
"collected": true,
"truncated": false,
"total_count": 0,
"direct_count": 0,
"indirect_count": 0
}
},
"maintainership": {
"issues": {
"open_prs": 6,
"merged_prs": 427,
"open_issues": 116,
"closed_ratio": 0.72,
"closed_issues": 298,
"closed_unmerged_prs": 81
},
"bus_factor": 4,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "timtebeek",
"commits": 362,
"avatar_url": "https://avatars.githubusercontent.com/u/1027334?v=4"
},
{
"type": "User",
"login": "knutwannheden",
"commits": 240,
"avatar_url": "https://avatars.githubusercontent.com/u/408765?v=4"
},
{
"type": "User",
"login": "jkschneider",
"commits": 213,
"avatar_url": "https://avatars.githubusercontent.com/u/1697736?v=4"
},
{
"type": "User",
"login": "pway99",
"commits": 138,
"avatar_url": "https://avatars.githubusercontent.com/u/22326988?v=4"
},
{
"type": "User",
"login": "sambsnyd",
"commits": 101,
"avatar_url": "https://avatars.githubusercontent.com/u/8549033?v=4"
},
{
"type": "User",
"login": "traceyyoshima",
"commits": 91,
"avatar_url": "https://avatars.githubusercontent.com/u/16889475?v=4"
},
{
"type": "User",
"login": "kunli2",
"commits": 89,
"avatar_url": "https://avatars.githubusercontent.com/u/122563761?v=4"
},
{
"type": "User",
"login": "aegershman",
"commits": 74,
"avatar_url": "https://avatars.githubusercontent.com/u/5619476?v=4"
},
{
"type": "User",
"login": "greg-at-moderne",
"commits": 55,
"avatar_url": "https://avatars.githubusercontent.com/u/192309513?v=4"
},
{
"type": "User",
"login": "tkvangorder",
"commits": 24,
"avatar_url": "https://avatars.githubusercontent.com/u/1878529?v=4"
}
],
"contributors_sampled": 98,
"top_contributor_share": 0.217
},
"quality_signals": {
"has_ci": true,
"has_tests": true,
"ci_workflows": [
"ci.yml",
"publish.yml",
"repository-backup.yml",
"stale.yml"
],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 9,
"reason": "binaries present in source code",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": 9,
"reason": "21 out of 23 merged PRs checked by a CI test -- score normalized to 9",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 2,
"reason": "Found 8/30 approved changesets -- score normalized to 2",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 22 contributing companies or organizations",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": 10,
"reason": "no dangerous workflow patterns detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 9,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 10,
"reason": "30 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": 0,
"reason": "dependency not pinned by hash detected -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "SAST tool is not run on all commits -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 0,
"reason": "security policy file not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": 0,
"reason": "detected GitHub workflow tokens with excessive permissions",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "5545efa3f71cabfb1feeacb55c26ae55538488f5",
"ran_at": "2026-07-25T17:21:03Z",
"aggregate_score": 5.2,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": true
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-24T18:22:28Z",
"oldest_open_prs": [
{
"number": 897,
"created_at": "2026-05-20T13:36:54Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 931,
"created_at": "2026-07-01T00:45:12Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 938,
"created_at": "2026-07-13T13:59:08Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 944,
"created_at": "2026-07-19T18:02:58Z",
"last_comment_at": "2026-07-19T18:03:25Z",
"last_comment_author": "kush2439p"
},
{
"number": 945,
"created_at": "2026-07-21T02:27:49Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 951,
"created_at": "2026-07-25T06:05:43Z",
"last_comment_at": "2026-07-25T08:25:54Z",
"last_comment_author": "habiibullahm"
}
],
"last_merged_pr_at": "2026-07-23T19:32:48Z",
"ci_last_conclusion": "SUCCESS",
"oldest_open_issues": [
{
"number": 67,
"created_at": "2021-04-21T19:55:36Z",
"last_comment_at": "2021-05-21T22:03:53Z",
"last_comment_author": "traceyyoshima"
},
{
"number": 66,
"created_at": "2021-05-10T16:10:24Z",
"last_comment_at": "2021-05-28T00:28:38Z",
"last_comment_author": "traceyyoshima"
},
{
"number": 387,
"created_at": "2021-05-20T21:37:06Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 65,
"created_at": "2021-07-20T04:18:41Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 64,
"created_at": "2021-07-21T17:04:39Z",
"last_comment_at": "2021-08-22T23:51:10Z",
"last_comment_author": "jkschneider"
},
{
"number": 63,
"created_at": "2021-07-21T17:07:21Z",
"last_comment_at": "2021-08-22T23:52:08Z",
"last_comment_author": "jkschneider"
},
{
"number": 62,
"created_at": "2021-07-21T17:08:50Z",
"last_comment_at": "2021-08-22T23:00:36Z",
"last_comment_author": "sambsnyd"
},
{
"number": 61,
"created_at": "2021-07-21T17:09:36Z",
"last_comment_at": "2021-08-22T23:51:32Z",
"last_comment_author": "jkschneider"
},
{
"number": 60,
"created_at": "2021-07-21T17:45:14Z",
"last_comment_at": "2021-08-23T17:45:02Z",
"last_comment_author": "jkschneider"
},
{
"number": 69,
"created_at": "2022-04-01T14:23:54Z",
"last_comment_at": "2022-04-02T03:02:52Z",
"last_comment_author": "tkvangorder"
},
{
"number": 59,
"created_at": "2022-04-02T14:42:04Z",
"last_comment_at": "2022-04-04T20:29:15Z",
"last_comment_author": "tkvangorder"
},
{
"number": 57,
"created_at": "2022-04-04T00:36:44Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 56,
"created_at": "2022-04-04T20:03:31Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 55,
"created_at": "2022-04-05T20:41:18Z",
"last_comment_at": "2022-04-06T17:26:23Z",
"last_comment_author": "traceyyoshima"
},
{
"number": 54,
"created_at": "2022-04-05T20:44:07Z",
"last_comment_at": "2022-04-14T05:25:17Z",
"last_comment_author": "traceyyoshima"
},
{
"number": 53,
"created_at": "2022-04-07T20:31:37Z",
"last_comment_at": "2022-04-14T05:23:18Z",
"last_comment_author": "traceyyoshima"
},
{
"number": 71,
"created_at": "2022-04-08T03:05:40Z",
"last_comment_at": "2022-04-12T03:15:01Z",
"last_comment_author": "yeikel"
},
{
"number": 72,
"created_at": "2022-04-11T01:00:51Z",
"last_comment_at": "2022-04-11T16:10:05Z",
"last_comment_author": "tkvangorder"
},
{
"number": 52,
"created_at": "2022-04-11T16:19:15Z",
"last_comment_at": null,
"last_comment_author": null
},
{
"number": 74,
"created_at": "2022-04-13T04:00:10Z",
"last_comment_at": null,
"last_comment_author": null
}
]
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/openrewrite/rewrite-static-analysis",
"host": "github.com",
"name": "rewrite-static-analysis",
"owner": "openrewrite"
},
"metrics": {
"overall": {
"key": "overall",
"band": "good",
"name": "Overall health",
"note": null,
"notes": [],
"value": 72,
"inputs": {
"security": 52,
"vitality": 98,
"community": 60,
"governance": 77,
"engineering": 63
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "excellent",
"name": "Vitality",
"value": 98,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "excellent",
"name": "Development activity",
"note": null,
"notes": [],
"value": 96,
"inputs": {
"commits_last_year": 253,
"human_commit_share": 1,
"days_since_last_push": 1,
"active_weeks_last_year": 47
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 1 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 1
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "47/52 weeks with commits",
"points": 32.5,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 47
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "253 commits in the last year",
"points": 18,
"status": "met",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 253
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "30 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 100,
"inputs": {
"releases_count": 91,
"latest_release_tag": "v2.39.0",
"releases_from_tags": false,
"days_since_latest_release": 11,
"mean_days_between_releases": 10.7
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "91 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 91
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 11 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 11
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~10.7 days",
"points": 27,
"status": "met",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 10.7
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 1,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 1 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 1
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "moderate",
"name": "Community & Adoption",
"value": 60,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "moderate",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"forks": 102,
"stars": 58,
"watchers": 7,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "58 stars",
"points": 28.5,
"status": "partial",
"details": [
{
"code": "stars",
"params": {
"count": 58
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "102 forks",
"points": 16.7,
"status": "partial",
"details": [
{
"code": "forks",
"params": {
"count": 102
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "7 watchers",
"points": 4.3,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 7
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "good",
"name": "Community health",
"note": null,
"notes": [],
"value": 71,
"inputs": {
"has_readme": true,
"has_license": true,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 22.5,
"status": "met",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "license file present, not a recognized license",
"points": 16.9,
"status": "partial",
"details": [
{
"code": "license_custom",
"params": {}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "good",
"name": "Sustainability & Governance",
"value": 77,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "good",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 84,
"inputs": {
"bus_factor": 4,
"contributors_sampled": 98,
"top_contributor_share": 0.217
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "4 contributor(s) cover half of all commits",
"points": 43.2,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 4
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 22% of commits",
"points": 17.6,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 22
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "98 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 98
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 22 contributing companies or organizations",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "moderate",
"name": "Issue & PR responsiveness",
"note": null,
"notes": [],
"value": 69,
"inputs": {
"merged_prs": 427,
"open_issues": 116,
"closed_issues": 298,
"issue_closed_ratio": 0.72,
"closed_unmerged_prs": 81
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "72% of issues closed",
"points": 33.7,
"status": "partial",
"details": [
{
"code": "issues_closed_share",
"params": {
"share": 72
}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "427/508 decided PRs merged",
"points": 32.2,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 427,
"decided": 508
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 8/30 approved changesets -- score normalized to 2",
"points": 3,
"status": "partial",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "good",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 76,
"inputs": {
"followers": 984,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "openrewrite",
"public_repos": 75,
"account_age_days": 2341
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "984 followers of openrewrite",
"points": 21.5,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 984,
"login": "openrewrite"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "75 public repos, account ~6 yr old",
"points": 25,
"status": "met",
"details": [
{
"code": "public_repos",
"params": {
"count": 75
}
},
{
"code": "account_age_years",
"params": {
"years": 6
}
}
],
"max_points": 25
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "moderate",
"name": "Engineering Quality",
"value": 63,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "good",
"name": "Engineering practices",
"note": null,
"notes": [],
"value": 72,
"inputs": {
"has_ci": true,
"has_tests": true,
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": "4 workflow(s)",
"points": 24,
"status": "met",
"details": [
{
"code": "ci_workflows",
"params": {
"count": 4
}
}
],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 6.4,
"status": "met",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "21 out of 23 merged PRs checked by a CI test -- score normalized to 9",
"points": 18,
"status": "partial",
"details": [],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "moderate",
"name": "Documentation",
"note": null,
"notes": [],
"value": 50,
"inputs": {
"topics": [
"good-first-issue",
"java",
"static-analysis",
"static-code-analysis",
"openrewrite",
"openrewrite-recipes"
],
"has_wiki": false,
"homepage": null,
"has_readme": true,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 30,
"status": "met",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": "6 topics",
"points": 10,
"status": "met",
"details": [
{
"code": "topics_count",
"params": {
"count": 6
}
}
],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "moderate",
"name": "Security",
"value": 52,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "moderate",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"packaging",
"signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 52,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 16,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 2,
"scorecard_aggregate": 5.2
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "binaries present in source code",
"points": 6.8,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "21 out of 23 merged PRs checked by a CI test -- score normalized to 9",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 8/30 approved changesets -- score normalized to 2",
"points": 1.5,
"status": "partial",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 22 contributing companies or organizations",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no dangerous workflow patterns detected",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.2,
"status": "partial",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "30 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "SAST tool is not run on all commits -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file not detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "detected GitHub workflow tokens with excessive permissions",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 16
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "good",
"name": "AI Readiness",
"value": 73,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "excellent",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 85,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.91,
"agent_instruction_files": [
"CLAUDE.md"
],
"agent_instruction_max_bytes": 8599
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "CLAUDE.md",
"points": 45,
"status": "met",
"details": [
{
"code": "file_list",
"params": {
"files": "CLAUDE.md"
}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "91 of 100 human commits state their intent (structured subject or explanatory body)",
"points": 40,
"status": "met",
"details": [
{
"code": "legible_history",
"params": {
"legible": 91,
"sampled": 100
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "moderate",
"name": "Verify loop (build / test / typecheck)",
"note": null,
"notes": [],
"value": 53,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": true,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.01,
"toolchain_manifests": [
"build.gradle.kts"
],
"dependency_bot_commit_share": 0
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": "build.gradle.kts (toolchain convention, no task runner)",
"points": 12.6,
"status": "partial",
"details": [
{
"code": "toolchain_convention",
"params": {
"files": "build.gradle.kts"
}
}
],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": "Java (statically typed)",
"points": 11,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Java"
}
}
],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "1 of the last 100 commits agent-authored or agent-credited",
"points": 2,
"status": "partial",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 1,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "dependency automation configured, none observed in the sampled commits",
"points": 5,
"status": "partial",
"details": [
{
"code": "dependency_bot_config_only",
"params": {}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "dependency not pinned by hash detected -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "excellent",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"primary_language": "Java",
"largest_source_bytes": 88413,
"source_files_sampled": 403,
"oversized_source_files": 2
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "Java (statically typed)",
"points": 45,
"status": "met",
"details": [
{
"code": "statically_typed_language",
"params": {
"language": "Java"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "2/403 source files over 60KB",
"points": 54.7,
"status": "partial",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 403,
"oversized": 2
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
],
"report_type": "repository",
"generated_at": "2026-07-25T17:21:28.139405Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/o/openrewrite/rewrite-static-analysis.svg",
"full_name": "openrewrite/rewrite-static-analysis",
"license_state": "custom",
"license_spdx": null
}