Skip to content

Conversation

@shuuji3
Copy link
Member

@shuuji3 shuuji3 commented Feb 11, 2026

An attempt to sort contributors list by the governance role (steward > core > maintainer > contributor).

screenshot of contributor list in about page, daniel and patak is first two icons

I cannot find a public member list of the maintainers so kept it empty for now.

One option to avoid hardcoding is to create GitHub Team for each governance role, and create members list in GitHub Actions with command like gh api /orgs/npmx-dev/teams/steward/members --jq 'map(.login).

/cc @patak-dev @userquin

(ref. original chat: https://bsky.app/profile/patak.dev/post/3mek245m7as26)

@vercel
Copy link

vercel bot commented Feb 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 13, 2026 0:31am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 13, 2026 0:31am
npmx-lunaria Ignored Ignored Feb 13, 2026 0:31am

Request Review

@codecov
Copy link

codecov bot commented Feb 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

The PR adds role-aware contributor handling and sponsor detection to server/api/contributors.get.ts: introduces a Role type, team-member fetching (with fallback), sponsorable lookup, role determination, and returns contributors ordered by role and contributions while exposing role on GitHubContributor during processing. app/pages/about.vue adds a Team/Governance section and separates governance members from community contributors. New i18n translations for team were added and nuxt.config runtimeConfig gained github.orgToken.

🚥 Pre-merge checks | ✅ 1 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (11 files):

⚔️ app/pages/about.vue (content)
⚔️ i18n/locales/de-DE.json (content)
⚔️ i18n/locales/en.json (content)
⚔️ i18n/schema.json (content)
⚔️ lunaria/files/de-DE.json (content)
⚔️ lunaria/files/en-GB.json (content)
⚔️ lunaria/files/en-US.json (content)
⚔️ lunaria/prepare-json-files.ts (content)
⚔️ nuxt.config.ts (content)
⚔️ scripts/compare-translations.ts (content)
⚔️ server/api/contributors.get.ts (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly relates to the changeset, describing the effort to sort contributors by governance role with supporting context about the implementation approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch feat/contributor-list-sort-by-role
  • Post resolved changes as copyable diffs in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

@patak-dev
Copy link
Contributor

patak-dev commented Feb 11, 2026

Note: I thought I was looking at an issue 🤦🏼
My mind couldn't wrap around you doing a PR so fast:

Thanks for creating the issue! I think this is a good idea, we should surface maintainers and is a good way for some of them to flow up in line with their real contributions. The commits aren't telling the whole picture for a lot of us now.

@patak-dev
Copy link
Contributor

It would be good to also show for governance folk their github, npm, etc too. Maybe at one point we find a way to do it for everyone once we have more people connecting their accounts together.

image

One interesting discussion, we decided to remove the sponsors button for stewards in the main page of the repo. It didn't feel right that we were the only ones having the exposure there. But maybe we could add them back for everybody (or as many of us as possible, maybe first governance, later when people connect to github we could do better). I think we need to start trying to start working to help with OSS funding. I don't think people will give us a lot of money through this, I care more about the symbol that we should show that money is needed for npmx to work. It will also get better once we can start adding sponsors (soon!).

@patak-dev
Copy link
Contributor

Now that I know this is a PR, I checked how it looks :D

So, we could merge this and iterated, but I would like we show the governance structure as a way to explain that npmx takes the foundation route seriously. So we should have Stewards first as a title, then Maintainers, then everyone else. Maybe with a short paragraph. And it could give us an option to do bigger cards for maintainers so we can show that they work in different companies and what other projects they participate in. Let's use this as a way to show that we are the result of uniting a lot of communities.

@shuuji3
Copy link
Member Author

shuuji3 commented Feb 11, 2026

It actually is a PR😄 Yes, this can be imrpoved iteratively. I also think about adding sections similar to https://github.com/npmx-dev/npmx.dev/blob/main/GOVERNANCE.md and we could add links to this docs later.

@shuuji3
Copy link
Member Author

shuuji3 commented Feb 11, 2026

Also, once npmx's profile page mature, we could link to the profile page https://npmx.dev/profile/[user-name], instead of directly link to https://github.com/[user-name]

@patak-dev
Copy link
Contributor

I'm thinking that for the first iteration, until we have a core team, the best is if we only have two sections:

Team

Governance

Daniel Me [ ...maintainers ] <-- all with the same card size, just the role is diff

Contributors

All other contributors, maybe including the above too as a way to show we are all part of the team

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/api/contributors.get.ts (1)

1-8: ⚠️ Potential issue | 🟡 Minor

Type mismatch between API response and interface

The GitHubContributor interface now requires a role field, but the GitHub API response at line 49 does not include this property. Casting directly to GitHubContributor[] is type-unsafe since the objects won't have role until line 72.

Consider defining a separate type for the raw API response:

🛡️ Proposed fix for type safety
+type GitHubAPIContributor = Omit<GitHubContributor, 'role'>
+
 export interface GitHubContributor {
   login: string
   id: number
   avatar_url: string
   html_url: string
   contributions: number
   role: Role
 }

Then at line 49:

-      const contributors = (await response.json()) as GitHubContributor[]
+      const contributors = (await response.json()) as GitHubAPIContributor[]

And update the allContributors array type accordingly.

Also applies to: 49-49

🧹 Nitpick comments (3)
app/pages/about.vue (3)

147-147: Consider extracting the governance filter to a computed property

The filter c => c.role !== 'contributor' is used in multiple places (lines 147, 156–161). Extracting this to a computed property would improve readability and ensure consistency.

♻️ Suggested refactor

In <script setup>:

const governanceMembers = computed(() => 
  contributors.value?.filter(c => c.role !== 'contributor') ?? []
)

Then in the template:

-          <div v-if="contributors?.some(c => c.role !== 'contributor')" class="mb-12">
+          <div v-if="governanceMembers.length" class="mb-12">
-                v-for="person in contributors.filter(c => c.role !== 'contributor')"
+                v-for="person in governanceMembers"

141-144: Consider using i18n keys for the "Team" heading

The hardcoded "Team" string at line 141 should use an i18n key for consistency with the rest of the page, which uses $t() for all user-facing text.


148-148: Consider using i18n key for "Governance" heading

Similar to the "Team" heading, "Governance" should use an i18n key for internationalisation consistency.

@shuuji3
Copy link
Member Author

shuuji3 commented Feb 11, 2026

I've created a simple mini cards (icon + name + role) for governance section as a starting point. Should I use this same card format for all contributors, or keep the current contributors cloud?

I'll collect the maintainers GitHub handles from Discord and hardcode them (tomorrow).

Also, could you provide the short paragraphs for each sections? I'm not sure what the best wordings.

Screenshot from 2026-02-12 01-14-50

@whitep4nth3r
Copy link
Contributor

@shuuji3 I don't think we need the paragraph descriptions right now. Feel free to remove!

@github-actions
Copy link

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
lunaria/files/en-GB.json Localization changed, will be marked as complete. 🔄️
lunaria/files/en-US.json Source changed, localizations will be marked as outdated.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
server/api/contributors.get.ts (1)

24-54: Implement pagination for team members fetch to match contributors pattern.

The fetchTeamMembers() function fetches teams with per_page=100 but without pagination. In contrast, the same file implements a pagination loop for the repository contributors fetch (lines 131–166). For consistency and to avoid silent data loss if either team grows beyond 100 members, apply the same pagination pattern here:

♻️ Suggested implementation
    for (const [role, slug] of Object.entries(teams) as [keyof TeamMembers, string][]) {
+     let page = 1
+     const perPage = 100
+     while (true) {
-      const response = await fetch(
-        `https://api.github.com/orgs/npmx-dev/teams/${slug}/members?per_page=100`,
+       const response = await fetch(
+         `https://api.github.com/orgs/npmx-dev/teams/${slug}/members?per_page=${perPage}&page=${page}`,
         {
           headers: {
             'Accept': 'application/vnd.github.v3+json',
             'Authorization': `Bearer ${token}`,
             'User-Agent': 'npmx',
           },
         },
       )
 
-      if (!response.ok) {
+       if (!response.ok) {
           console.warn(`Failed to fetch ${slug} team members: ${response.status}`)
           return null
-      }
+       }
 
-      const members = (await response.json()) as { login: string }[]
-      for (const member of members) {
-        result[role].add(member.login)
-      }
+       const members = (await response.json()) as { login: string }[]
+       for (const member of members) {
+         result[role].add(member.login)
+       }
+       if (members.length < perPage) break
+       page++
+     }
     }

Comment on lines +193 to +199
<NuxtLink
:to="person.html_url"
target="_blank"
class="decoration-none after:content-[''] after:absolute after:inset-0"
:aria-label="$t('about.contributors.view_profile', { name: person.login })"
>
@{{ person.login }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add rel="noopener noreferrer" for external profile links opened in a new tab.

On Line 193, target="_blank" without a safe rel exposes window.opener and enables tabnabbing.

🔒 Suggested fix
<NuxtLink
  :to="person.html_url"
  target="_blank"
+ rel="noopener noreferrer"
  class="decoration-none after:content-[''] after:absolute after:inset-0"
  :aria-label="$t('about.contributors.view_profile', { name: person.login })"
>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<NuxtLink
:to="person.html_url"
target="_blank"
class="decoration-none after:content-[''] after:absolute after:inset-0"
:aria-label="$t('about.contributors.view_profile', { name: person.login })"
>
@{{ person.login }}
<NuxtLink
:to="person.html_url"
target="_blank"
rel="noopener noreferrer"
class="decoration-none after:content-[''] after:absolute after:inset-0"
:aria-label="$t('about.contributors.view_profile', { name: person.login })"
>
@{{ person.login }}

@shuuji3
Copy link
Member Author

shuuji3 commented Feb 13, 2026

Thanks for the update, Daniel🙂 It looks perfect to me.

about page screenshot, maintainers card has sponsor button now

Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great! we'll merge and we can make it better later 🙏

@danielroe danielroe added this pull request to the merge queue Feb 13, 2026
Merged via the queue into npmx-dev:main with commit 307c21c Feb 13, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants