Skip to content

chore: fix spelling & grammar#2651

Merged
graphieros merged 32 commits intonpmx-dev:mainfrom
jsoref:spelling
Apr 29, 2026
Merged

chore: fix spelling & grammar#2651
graphieros merged 32 commits intonpmx-dev:mainfrom
jsoref:spelling

Conversation

@jsoref
Copy link
Copy Markdown
Contributor

@jsoref jsoref commented Apr 29, 2026

🔗 Linked issue

🧭 Context

spelling errors harm many aspects

📚 Description

each fix is standalone and easy to understand

jsoref added 30 commits April 28, 2026 19:27
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 29, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Apr 29, 2026 10:47am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Apr 29, 2026 10:47am
npmx-lunaria Ignored Ignored Apr 29, 2026 10:47am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3a3c65e7-8c31-4b0d-8d5a-0cfac030c2be

📥 Commits

Reviewing files that changed from the base of the PR and between 92925c9 and ab93209.

📒 Files selected for processing (1)
  • server/utils/atproto/utils/likes.ts
✅ Files skipped from review due to trivial changes (1)
  • server/utils/atproto/utils/likes.ts

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Corrected spelling, grammar and punctuation across documentation, inline comments and user-facing strings — including CI workflow, CLI messages, UI component text, schema descriptions and developer docs — improving consistency and clarity without changing behaviour or functionality.

Walkthrough

Corrects spelling, punctuation and wording in comments, JSDoc, strings and documentation across the repository; no runtime logic, APIs, control flow, or schema structures were changed.

Changes

Cohort / File(s) Summary
CI & tooling
​.github/workflows/ci.yml, .storybook/.public/mockServiceWorker.js
Fixed typo in workflow concurrency comment (gitub.event.numbergithub.event.number) and minor punctuation in MSW handler comment.
Documentation & guides
CONTRIBUTING.md
Standardised wording to “prepopulated”; punctuation/wording fixes in docs.
CLI
cli/src/mock-server.ts, cli/src/npm-client.ts
Replaced “pre-populated” with “prepopulated” in help/log messages; fixed JSDoc grammar.
Vue components (templates & scripts)
app/components/Header/MobileMenu.client.vue, app/components/User/Avatar.vue, app/components/Chart/SplitSparkline.vue, app/components/Noodle/index.ts, app/components/Package/TrendsChart.vue, app/components/Package/VersionDistribution.vue, app/components/PaginationControls.vue, app/pages/package/[[org]]/[name].vue, app/pages/search.vue
Corrected key name typo (seperatorseparator) and numerous comment/JSDoc spelling and wording fixes; no behaviour changes.
Composables & utilities (app)
app/composables/useChartWatermark.ts, app/composables/useRepoMeta.ts, app/utils/chart-data-prediction.ts, app/utils/charts.ts, app/utils/publish-security.ts, app/utils/run-command.ts
Minor documentation and comment corrections (capitalisation, punctuation, typos).
Lexicons / schemas
lexicons/app/bsky/actor/defs.json, lexicons/app/bsky/richtext/facet.json, lexicons/com/atproto/identity/resolveHandle.json
Edited description strings for punctuation/capitalisation; schema structure unchanged.
Lunaria & styles
lunaria/components.ts, lunaria/styles.ts
Fixed inline comment typos in component and CSS comments.
Server API & utils
server/api/auth/atproto.get.ts, server/api/auth/session.delete.ts, server/api/contributors.get.ts, server/api/registry/org/[org]/packages.get.ts, server/utils/atproto/utils/likes.ts, server/utils/atproto/utils/profile.ts, server/utils/cache/local.ts, shared/utils/constants.ts
Corrected numerous JSDoc/inline comment typos, punctuation and wording; removed/adjusted blank line in one function; no logic or API signature changes.

Possibly related PRs

Suggested reviewers

  • serhalp
  • danielroe
  • alexdln
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: fix spelling & grammar' directly and clearly summarizes the main change: correcting spelling and grammar errors across the codebase.
Description check ✅ Passed The description is related to the changeset, explaining the context (spelling errors harm many aspects) and noting that each fix is standalone and easy to understand.
Linked Issues check ✅ Passed The pull request meets the objective of issue #2650 by correcting identified spelling and grammar errors across 28 files, with fixes including typos, misspellings, and punctuation corrections.
Out of Scope Changes check ✅ Passed All changes are narrowly scoped to spelling and grammar corrections only, with no modifications to code logic, control flow, functionality, or public APIs.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@github-actions
Copy link
Copy Markdown

Hello! Thank you for opening your first PR to npmx, @jsoref! 🚀

Here’s what will happen next:

  1. Our GitHub bots will run to check your changes.
    If they spot any issues you will see some error messages on this PR.
    Don’t hesitate to ask any questions if you’re not sure what these mean!

  2. In a few minutes, you’ll be able to see a preview of your changes on Vercel

  3. One or more of our maintainers will take a look and may ask you to make changes.
    We try to be responsive, but don’t worry if this takes a few days.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 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!

Copy link
Copy Markdown
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

Caution

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

⚠️ Outside diff range comments (3)
app/components/PaginationControls.vue (1)

15-18: ⚠️ Potential issue | 🟠 Major

Make pageSizeSelectValue a writable computed ref to properly support v-model.

pageSizeSelectValue is read-only, but you're binding it to v-model="pageSizeSelectValue" on <SelectField>. Since SelectField uses defineModel, it will emit update:modelValue when the selection changes. Vue will attempt to write to the computed ref and warn about mutating a readonly computed property.

The current code works only because @change manually handles the update; this is fragile and inconsistent with Vue's v-model pattern. The computed ref needs a setter:

Proposed fix
-const pageSizeSelectValue = computed(() => String(pageSize.value))
+const pageSizeSelectValue = computed<string>({
+  get: () => String(pageSize.value),
+  set: (value) => {
+    const newSize = Number(value) as PageSize
+    if (!Number.isFinite(newSize)) return
+    pageSize.value = newSize
+    currentPage.value = 1
+  },
+})

Once updated, the v-model binding will work correctly, and you can remove the @change handler (or keep it temporarily if preferred).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/PaginationControls.vue` around lines 15 - 18,
pageSizeSelectValue is currently a read-only computed used with v-model on
SelectField (which uses defineModel), so make pageSizeSelectValue a writable
computed ref: keep the getter as String(pageSize.value) and add a setter that
parses the incoming model value (e.g., Number(value) or parseInt) and assigns it
to pageSize.value; this lets v-model update pageSize correctly when SelectField
emits update:modelValue and you can remove the manual `@change` handler. Ensure
you update the computed definition named pageSizeSelectValue and keep
interactions with pageSize.value consistent.
server/api/contributors.get.ts (2)

15-17: ⚠️ Potential issue | 🟡 Minor

Fix misleading fallback comment (roles vs. “maintainers”).

The fallback comment says: “Only stewards are shown as maintainers; everyone else is a contributor.” But the fallback object at this file’s call site populates teams.steward (and sets teams.maintainer empty). That means those users will be classified as steward, not maintainer. Consider updating the comment to match the actual role behaviour.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/contributors.get.ts` around lines 15 - 17, The comment for the
fallback is misleading: update the comment around the FALLBACK_STEWARDS constant
to reflect that the set is used to populate teams.steward (not teams.maintainer)
and that those users will be classified as "steward", teams.maintainer will be
left empty, and everyone else is treated as "contributor"; reference the symbol
FALLBACK_STEWARDS and the call-site behavior that fills
teams.steward/teams.maintainer so the wording matches the actual role mapping.

117-196: ⚠️ Potential issue | 🟠 Major

Cache key must vary by token availability to prevent serving stale sponsor URLs.

defineCachedEventHandler caches for 1 hour with getKey: () => 'contributors' (constant key), but the response changes based on githubToken presence:

  • When githubToken is missing → sponsorable is an empty Set and sponsors_url is always null
  • When githubToken exists → fetchSponsorable(...) populates sponsors_url

If a request without the token populates the cache first, subsequent requests with token will incorrectly receive null sponsors until the cache expires.

Make the cache key include token availability:

Proposed fix
   {
     maxAge: 3600, // Cache for 1 hour
     name: 'github-contributors',
-    getKey: () => 'contributors',
+    getKey: () => {
+      const githubToken = useRuntimeConfig().github.orgToken
+      return githubToken ? 'contributors:with-token' : 'contributors:without-token'
+    },
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/contributors.get.ts` around lines 117 - 196, The cache key is
constant so responses differ by githubToken presence (affecting
sponsorable/sponsors_url) can be served stale; update the
defineCachedEventHandler getKey to include token availability (e.g., incorporate
whether useRuntimeConfig().github.orgToken is truthy) so requests with and
without a token use different cache entries—locate defineCachedEventHandler and
its getKey, reference githubToken, fetchSponsorable and sponsorable when forming
the key (e.g., return a key string that includes a boolean or short suffix based
on githubToken truthiness).
🧹 Nitpick comments (13)
server/api/registry/org/[org]/packages.get.ts (1)

4-4: Clarify the regex comment to match what NPM_ORG_NAME_RE actually allows.

Line 4’s comment is hard to read and seems potentially garbled; consider rewriting it so it clearly matches the regex rules:

  • must start with [\w~-] (no leading dot),
  • subsequent chars allow . as well as [\w~-].
Proposed comment tweak (no logic changes)
-// Validation pattern for npm org names - url-sage symbol and not start with a dot (incl. ~test24214. or -ex~-)
+// Validation pattern for npm org names:
+// - first char: alnum/underscore (`\w`), hyphen (`-`), or tilde (`~`)
+// - remaining chars may also include dots (`.`)
+// - org name must not start with a dot
 const NPM_ORG_NAME_RE = /^[\w~-][\w.~-]*$/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/registry/org/`[org]/packages.get.ts at line 4, The comment above
the NPM_ORG_NAME_RE regex is unclear; update the comment for clarity to state
that NPM_ORG_NAME_RE requires the name to start with one of [A-Za-z0-9_\-~] (no
leading dot) and allows subsequent characters to be either a dot or any of
[A-Za-z0-9_\-~], matching the actual regex behavior—reference the
NPM_ORG_NAME_RE constant and update its inline comment to that clearer wording
without changing the regex itself.
app/utils/run-command.ts (1)

46-48: Optional refactor: deduplicate baseName derivation.

baseName computation for scoped package names is repeated later in getRunCommandParts (around Line 90-93). Consider extracting a small helper (e.g., getPackageBaseName(packageName)) and reusing it to keep behaviour consistent and reduce future drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/run-command.ts` around lines 46 - 48, Extract the repeated logic
that computes the unscoped package name into a small helper (e.g.,
getPackageBaseName) and replace both occurrences where baseName is derived (the
assignment in run-command.ts and the logic inside getRunCommandParts) to call
that helper; ensure the helper handles scoped names starting with '@' by
returning the part after the slash and returns the original name otherwise so
behavior of primaryCommand, baseName checks, and getRunCommandParts remains
identical.
server/api/auth/session.delete.ts (1)

2-3: Minor comment grammar: “Even tho” → “Even though”, and tighten wording.

Line 2 reads “Even tho … should be done in order”, which is slightly ungrammatical/awkward. Consider updating it to something like “Even though …, it should still be done in order” to match the intent more clearly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/auth/session.delete.ts` around lines 2 - 3, The comment in
session.delete.ts contains awkward grammar ("Even tho … should be done in
order"); update that inline comment to use proper spelling and tightened
phrasing—e.g., change "Even tho the signOut also clears part of the server cache
should be done in order to let the OAuth package do any other clean up it may
need" to a clearer sentence such as "Even though signOut also clears part of the
server cache, this should still be done to allow the OAuth package to perform
any additional cleanup." Locate and replace the existing comment text in the
file (the comment surrounding signOut/server cache/OAuth cleanup) with the new
phrasing.
server/utils/cache/local.ts (1)

15-20: Non-blocking: clarify ttl semantics for 0 (undefined vs immediate expiry).

isCacheEntryStale currently uses if (!entry.ttl) return false, which treats ttl = 0 as “no TTL” rather than “expires immediately”. If 0 is meant to mean immediate expiry, consider switching the guard to check for null/undefined explicitly.

Optional suggested change
 function isCacheEntryStale(entry: LocalCachedEntry): boolean {
-  if (!entry.ttl) return false
+  if (entry.ttl == null) return false
   const now = Date.now()
   const expiresAt = entry.cachedAt + entry.ttl * 1000
   return now > expiresAt
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/utils/cache/local.ts` around lines 15 - 20, The function
isCacheEntryStale treats ttl=0 as “no TTL” due to the falsy check; change the
guard in isCacheEntryStale to only treat null/undefined as missing (e.g., check
entry.ttl == null) so that ttl=0 means immediate expiry, and update any
LocalCachedEntry/inline comment to document that ttl=0 implies immediate
expiration.
app/utils/chart-data-prediction.ts (1)

96-102: Optional doc precision: clarify fallback when linearProject() can’t compute a projection.

Right now the JSDoc frames the decision mainly in terms of “enough lookback points” vs “otherwise”. In the implementation, proportional scale-up can also happen when lookback.length >= predictionPoints but linearProject(lookback) returns null (e.g. degenerate det === 0 or n < 2). Consider adding a short phrase like “or when projection fails” to make the documentation fully match the control-flow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/chart-data-prediction.ts` around lines 96 - 102, The JSDoc for the
estimator is misleading about when proportional scale-up is used; update the
comment for the function that estimates the full-period value to say
proportional scale-up is used not only when lookback.length < predictionPoints
but also "or when projection fails" (i.e., when linearProject(lookback) returns
null or cannot compute due to degenerate det/n < 2), referencing
predictionPoints, lookback, and linearProject() so the docs match the control
flow.
app/utils/charts.ts (1)

341-352: Minor doc inconsistency: “%” vs ratio for coefficient of variation

The implementation computes coefficientOfVariation as standardDeviation / mean (unitless ratio), and the thresholds in the table (0.1, 0.25) match ratios—not percent values. The JSDoc line “expressed in %” may confuse readers.

✏️ Suggested doc-only wording change
-     * - expressed in %
+     * - expressed as a ratio (standard deviation / mean)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/charts.ts` around lines 341 - 352, The JSDoc for
coefficientOfVariation in app/utils/charts.ts incorrectly says "expressed in %"
while the code computes coefficientOfVariation as standardDeviation / mean (a
unitless ratio); update the comment for the symbol coefficientOfVariation (and
the surrounding JSDoc block) to state it is a unitless ratio (or "ratio (e.g.,
0.1 = 10%)") and clarify the threshold table accordingly (e.g., keep thresholds
as ratios 0.1 and 0.25 or show both ratio and percent) so the comment matches
the implementation.
app/utils/publish-security.ts (1)

107-110: Clarify that trustedTrustLevel may come from any-major.

The new comment says “any-major for detection only”, but the returned object includes trustedTrustLevel: strongestOlder.resolvedTrustLevel, which will be any-major when strongestOlderSameMajor is null (even though trustedVersion / trustedPublishedAt remain same-major-only via recommendation).

Consider updating the comment to explicitly distinguish:

  • same-major for trustedVersion recommendation
  • any-major fallback for trustedTrustLevel used in detection
📝 Proposed comment tweak
-  // Use same-major for recommendation if available; otherwise, any-major for detection only
+  // Use same-major for the recommended trusted version if available; otherwise:
+  // - fall back to any-major for downgrade detection
+  // - `trustedVersion`/`trustedPublishedAt` remain recommendation-only (same-major)
+  // - `trustedTrustLevel` may reflect any-major fallback
   const strongestOlder = strongestOlderSameMajor ?? strongestOlderAny
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/publish-security.ts` around lines 107 - 110, Update the inline
comment above the selection that sets strongestOlder (using
strongestOlderSameMajor ?? strongestOlderAny) to explicitly state that
trustedVersion and trustedPublishedAt are derived only from the same-major
candidate (strongestOlderSameMajor) for the recommendation, while
trustedTrustLevel may come from the any-major fallback (strongestOlderAny) and
is therefore used for detection only; reference the symbols
strongestOlderSameMajor, strongestOlderAny, strongestOlder, trustedTrustLevel,
trustedVersion, trustedPublishedAt and recommendation in the comment so readers
understand the distinct sources for recommendation vs detection.
app/components/Chart/SplitSparkline.vue (1)

105-106: Minor risk: guard against empty palette to avoid i % palette.length issues.

fallbackColor uses palette[i % palette.length]. If palette.length could ever be 0, this would evaluate to NaN and the fallback chain could degrade unexpectedly. Please confirm getPalette('') always returns a non-empty palette; if not, add a small defensive guard.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/Chart/SplitSparkline.vue` around lines 105 - 106, The
fallbackColor calculation in SplitSparkline.vue can divide by zero when palette
is empty; update the logic around fallbackColor (used to compute seriesColor) to
defensively handle an empty palette returned by getPalette('') by checking
palette.length > 0 before using palette[i % palette.length], and fall back to a
safe default color (e.g., a constant DEFAULT_COLOR or palette[0] if non-empty)
when palette is empty; ensure the change references the existing symbols
fallbackColor and seriesColor so the unit.color ?? fallbackColor behavior
remains intact.
server/utils/atproto/utils/likes.ts (3)

109-115: Tighten JSDoc punctuation/wording for getLikes.

Line 110: “Tries a local cache first, if not found uses constellation” reads slightly awkwardly and is missing commas. Consider adding punctuation for clarity (e.g., “... first; if not found, uses ...”). Comment-only change.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/utils/atproto/utils/likes.ts` around lines 109 - 115, The JSDoc for
the getLikes function is awkwardly punctuated; update the comment above async
getLikes(packageName: string, usersDid?: string | undefined):
Promise<PackageLikes> to improve clarity and punctuation (for example: "Gets the
likes for an npm package on npmx. Tries a local cache first; if not found, uses
constellation.") so the description reads smoothly and includes the necessary
commas/semicolon.

170-176: Improve readability of the likeAPackageAndReturnLikes JSDoc sentence.

Lines 171-172 contain a long/awkward construction (“It is assumed it has been checked … that if … and …”). It can be simplified to be grammatically clearer while keeping the meaning. This helps future maintainers understand the precondition faster. Comment-only.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/utils/atproto/utils/likes.ts` around lines 170 - 176, Rewrite the
JSDoc for likeAPackageAndReturnLikes to a clearer, shorter precondition
sentence; replace the long construction with something like: "Assumes the caller
has already verified that a user's like for a package was stored as a record in
the user's AT Protocol repository (atUri refers to that like record)." Keep it
in the JSDoc above likeAPackageAndReturnLikes so the precondition and meaning
remain intact.

53-68: Fix grammar in constructor comment (“since are already …”).

Line 57’s comment is ungrammatical: “since are already doing …”. Consider rewriting to a correct causal phrasing (e.g., “because we’re already doing …”). This is consistent with the PR’s spelling/grammar intent and improves readability without changing behaviour.

Suggested comment-only diff
   constructor(deps?: { constellation?: ConstellationLike; cache?: CacheAdapter }) {
     this.constellation =
       deps?.constellation ??
       new Constellation(
-        // Passes in a fetch wrapped as CachedFetch since are already doing some heavy caching here
+        // Passes in a fetch wrapped as CachedFetch because we're already doing some heavy caching here
         async <T = unknown>(
           url: string,
           options: Parameters<typeof $fetch>[1] = {},
           _ttl?: number,
         ): Promise<CachedFetchResult<T>> => {
           const data = (await $fetch<T>(url, options)) as T
           return { data, isStale: false, cachedAt: null }
         },
       )
     this.cache = deps?.cache ?? getCacheAdapter('generic')
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/utils/atproto/utils/likes.ts` around lines 53 - 68, In the constructor
where Constellation is instantiated (inside the constructor function that sets
this.constellation), update the inline comment currently reading “// Passes in a
fetch wrapped as CachedFetch since are already doing some heavy caching here” to
a grammatically correct causal phrasing such as “// Passes in a fetch wrapped as
CachedFetch because we’re already doing some heavy caching here” (or similar).
Locate the comment adjacent to the Constellation(...) and
CachedFetch/CachedFetchResult usage and replace only the comment text; do not
modify the surrounding code or function signatures.
server/api/contributors.get.ts (2)

70-74: Avoid GraphQL injection via unescaped logins.

In fetchSponsorable, the GraphQL query string is built by interpolating each login directly into:
user${i}: user(login: "${login}") { ... }

Even if GitHub logins are “normally safe”, it’s still better to escape quotes/backslashes (or validate against an allowed pattern) before embedding into a query string to prevent malformed queries and any theoretical injection edge cases.

At minimum, escape \ and " when constructing fragments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/contributors.get.ts` around lines 70 - 74, The GraphQL query
builds fragments by interpolating raw logins which can allow injection; update
the code in fetchSponsorable (the logins.map -> fragments construction) to
sanitize each login before interpolation by escaping backslashes and double
quotes (or validate against a strict login regex) and use that escapedLogin
inside `user${i}: user(login: "${escapedLogin}") { ... }`; optionally factor the
logic into a small helper named escapeGraphQLString to make it clear and
reusable and replace the current fragments/map usage with the escaped values.

121-128: Looks good: clearer token/fallback handling (minor isolation improvement optional).

LGTM on the new comment and the fallback construction: when githubToken is present you fetch team members; otherwise you return a deterministic TeamMembers shape.

Optional hardening: since FALLBACK_STEWARDS is a shared Set, you could defensively copy it to avoid any future accidental mutation coupling:

Optional diff
-      return { steward: FALLBACK_STEWARDS, maintainer: new Set<string>() }
+      return { steward: new Set(FALLBACK_STEWARDS), maintainer: new Set<string>() }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/contributors.get.ts` around lines 121 - 128, The fallback returns
the shared FALLBACK_STEWARDS Set directly which can lead to accidental
shared-mutation coupling; inside the async IIFE that assigns teams (the block
using githubToken and fetchTeamMembers) return a defensive copy instead of the
original by constructing a new Set from FALLBACK_STEWARDS (so the returned
TeamMembers uses new Set(FALLBACK_STEWARDS) for the steward field) to preserve
immutability and avoid future mutation side-effects.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/utils/atproto/utils/likes.ts`:
- Around line 198-201: Comment typo: change "incase" to "in case" in the comment
above the backlink cache code; locate the comment that precedes the
CACHE_USERS_BACK_LINK usage (variables/functions: CACHE_USERS_BACK_LINK,
usersDid, usersBackLinkKey, backLink, this.cache.set) and update the text to
read "in case" instead of "incase".

---

Outside diff comments:
In `@app/components/PaginationControls.vue`:
- Around line 15-18: pageSizeSelectValue is currently a read-only computed used
with v-model on SelectField (which uses defineModel), so make
pageSizeSelectValue a writable computed ref: keep the getter as
String(pageSize.value) and add a setter that parses the incoming model value
(e.g., Number(value) or parseInt) and assigns it to pageSize.value; this lets
v-model update pageSize correctly when SelectField emits update:modelValue and
you can remove the manual `@change` handler. Ensure you update the computed
definition named pageSizeSelectValue and keep interactions with pageSize.value
consistent.

In `@server/api/contributors.get.ts`:
- Around line 15-17: The comment for the fallback is misleading: update the
comment around the FALLBACK_STEWARDS constant to reflect that the set is used to
populate teams.steward (not teams.maintainer) and that those users will be
classified as "steward", teams.maintainer will be left empty, and everyone else
is treated as "contributor"; reference the symbol FALLBACK_STEWARDS and the
call-site behavior that fills teams.steward/teams.maintainer so the wording
matches the actual role mapping.
- Around line 117-196: The cache key is constant so responses differ by
githubToken presence (affecting sponsorable/sponsors_url) can be served stale;
update the defineCachedEventHandler getKey to include token availability (e.g.,
incorporate whether useRuntimeConfig().github.orgToken is truthy) so requests
with and without a token use different cache entries—locate
defineCachedEventHandler and its getKey, reference githubToken, fetchSponsorable
and sponsorable when forming the key (e.g., return a key string that includes a
boolean or short suffix based on githubToken truthiness).

---

Nitpick comments:
In `@app/components/Chart/SplitSparkline.vue`:
- Around line 105-106: The fallbackColor calculation in SplitSparkline.vue can
divide by zero when palette is empty; update the logic around fallbackColor
(used to compute seriesColor) to defensively handle an empty palette returned by
getPalette('') by checking palette.length > 0 before using palette[i %
palette.length], and fall back to a safe default color (e.g., a constant
DEFAULT_COLOR or palette[0] if non-empty) when palette is empty; ensure the
change references the existing symbols fallbackColor and seriesColor so the
unit.color ?? fallbackColor behavior remains intact.

In `@app/utils/chart-data-prediction.ts`:
- Around line 96-102: The JSDoc for the estimator is misleading about when
proportional scale-up is used; update the comment for the function that
estimates the full-period value to say proportional scale-up is used not only
when lookback.length < predictionPoints but also "or when projection fails"
(i.e., when linearProject(lookback) returns null or cannot compute due to
degenerate det/n < 2), referencing predictionPoints, lookback, and
linearProject() so the docs match the control flow.

In `@app/utils/charts.ts`:
- Around line 341-352: The JSDoc for coefficientOfVariation in
app/utils/charts.ts incorrectly says "expressed in %" while the code computes
coefficientOfVariation as standardDeviation / mean (a unitless ratio); update
the comment for the symbol coefficientOfVariation (and the surrounding JSDoc
block) to state it is a unitless ratio (or "ratio (e.g., 0.1 = 10%)") and
clarify the threshold table accordingly (e.g., keep thresholds as ratios 0.1 and
0.25 or show both ratio and percent) so the comment matches the implementation.

In `@app/utils/publish-security.ts`:
- Around line 107-110: Update the inline comment above the selection that sets
strongestOlder (using strongestOlderSameMajor ?? strongestOlderAny) to
explicitly state that trustedVersion and trustedPublishedAt are derived only
from the same-major candidate (strongestOlderSameMajor) for the recommendation,
while trustedTrustLevel may come from the any-major fallback (strongestOlderAny)
and is therefore used for detection only; reference the symbols
strongestOlderSameMajor, strongestOlderAny, strongestOlder, trustedTrustLevel,
trustedVersion, trustedPublishedAt and recommendation in the comment so readers
understand the distinct sources for recommendation vs detection.

In `@app/utils/run-command.ts`:
- Around line 46-48: Extract the repeated logic that computes the unscoped
package name into a small helper (e.g., getPackageBaseName) and replace both
occurrences where baseName is derived (the assignment in run-command.ts and the
logic inside getRunCommandParts) to call that helper; ensure the helper handles
scoped names starting with '@' by returning the part after the slash and returns
the original name otherwise so behavior of primaryCommand, baseName checks, and
getRunCommandParts remains identical.

In `@server/api/auth/session.delete.ts`:
- Around line 2-3: The comment in session.delete.ts contains awkward grammar
("Even tho … should be done in order"); update that inline comment to use proper
spelling and tightened phrasing—e.g., change "Even tho the signOut also clears
part of the server cache should be done in order to let the OAuth package do any
other clean up it may need" to a clearer sentence such as "Even though signOut
also clears part of the server cache, this should still be done to allow the
OAuth package to perform any additional cleanup." Locate and replace the
existing comment text in the file (the comment surrounding signOut/server
cache/OAuth cleanup) with the new phrasing.

In `@server/api/contributors.get.ts`:
- Around line 70-74: The GraphQL query builds fragments by interpolating raw
logins which can allow injection; update the code in fetchSponsorable (the
logins.map -> fragments construction) to sanitize each login before
interpolation by escaping backslashes and double quotes (or validate against a
strict login regex) and use that escapedLogin inside `user${i}: user(login:
"${escapedLogin}") { ... }`; optionally factor the logic into a small helper
named escapeGraphQLString to make it clear and reusable and replace the current
fragments/map usage with the escaped values.
- Around line 121-128: The fallback returns the shared FALLBACK_STEWARDS Set
directly which can lead to accidental shared-mutation coupling; inside the async
IIFE that assigns teams (the block using githubToken and fetchTeamMembers)
return a defensive copy instead of the original by constructing a new Set from
FALLBACK_STEWARDS (so the returned TeamMembers uses new Set(FALLBACK_STEWARDS)
for the steward field) to preserve immutability and avoid future mutation
side-effects.

In `@server/api/registry/org/`[org]/packages.get.ts:
- Line 4: The comment above the NPM_ORG_NAME_RE regex is unclear; update the
comment for clarity to state that NPM_ORG_NAME_RE requires the name to start
with one of [A-Za-z0-9_\-~] (no leading dot) and allows subsequent characters to
be either a dot or any of [A-Za-z0-9_\-~], matching the actual regex
behavior—reference the NPM_ORG_NAME_RE constant and update its inline comment to
that clearer wording without changing the regex itself.

In `@server/utils/atproto/utils/likes.ts`:
- Around line 109-115: The JSDoc for the getLikes function is awkwardly
punctuated; update the comment above async getLikes(packageName: string,
usersDid?: string | undefined): Promise<PackageLikes> to improve clarity and
punctuation (for example: "Gets the likes for an npm package on npmx. Tries a
local cache first; if not found, uses constellation.") so the description reads
smoothly and includes the necessary commas/semicolon.
- Around line 170-176: Rewrite the JSDoc for likeAPackageAndReturnLikes to a
clearer, shorter precondition sentence; replace the long construction with
something like: "Assumes the caller has already verified that a user's like for
a package was stored as a record in the user's AT Protocol repository (atUri
refers to that like record)." Keep it in the JSDoc above
likeAPackageAndReturnLikes so the precondition and meaning remain intact.
- Around line 53-68: In the constructor where Constellation is instantiated
(inside the constructor function that sets this.constellation), update the
inline comment currently reading “// Passes in a fetch wrapped as CachedFetch
since are already doing some heavy caching here” to a grammatically correct
causal phrasing such as “// Passes in a fetch wrapped as CachedFetch because
we’re already doing some heavy caching here” (or similar). Locate the comment
adjacent to the Constellation(...) and CachedFetch/CachedFetchResult usage and
replace only the comment text; do not modify the surrounding code or function
signatures.

In `@server/utils/cache/local.ts`:
- Around line 15-20: The function isCacheEntryStale treats ttl=0 as “no TTL” due
to the falsy check; change the guard in isCacheEntryStale to only treat
null/undefined as missing (e.g., check entry.ttl == null) so that ttl=0 means
immediate expiry, and update any LocalCachedEntry/inline comment to document
that ttl=0 implies immediate expiration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 78511fa1-7fa8-482c-99e2-c88ee958c3b0

📥 Commits

Reviewing files that changed from the base of the PR and between 17ea220 and 92925c9.

📒 Files selected for processing (33)
  • .github/workflows/ci.yml
  • .storybook/.public/mockServiceWorker.js
  • CONTRIBUTING.md
  • app/components/Chart/SplitSparkline.vue
  • app/components/Header/MobileMenu.client.vue
  • app/components/Noodle/index.ts
  • app/components/Package/TrendsChart.vue
  • app/components/Package/VersionDistribution.vue
  • app/components/PaginationControls.vue
  • app/components/User/Avatar.vue
  • app/composables/useChartWatermark.ts
  • app/composables/useRepoMeta.ts
  • app/pages/package/[[org]]/[name].vue
  • app/pages/search.vue
  • app/utils/chart-data-prediction.ts
  • app/utils/charts.ts
  • app/utils/publish-security.ts
  • app/utils/run-command.ts
  • cli/src/mock-server.ts
  • cli/src/npm-client.ts
  • lexicons/app/bsky/actor/defs.json
  • lexicons/app/bsky/richtext/facet.json
  • lexicons/com/atproto/identity/resolveHandle.json
  • lunaria/components.ts
  • lunaria/styles.ts
  • server/api/auth/atproto.get.ts
  • server/api/auth/session.delete.ts
  • server/api/contributors.get.ts
  • server/api/registry/org/[org]/packages.get.ts
  • server/utils/atproto/utils/likes.ts
  • server/utils/atproto/utils/profile.ts
  • server/utils/cache/local.ts
  • shared/utils/constants.ts

Comment thread server/utils/atproto/utils/likes.ts Outdated
// Date for the noodle
date?: string
// Date to for the noodle
// `Date to` for the noodle
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

While Date for the noodle reads properly in English, Date to for the noodle really doesn't. I'm suggesting adding ` to make it readable...

Comment thread cli/src/mock-server.ts
#!/usr/bin/env node
/**
* Mock connector CLI — starts a pre-populated mock server for developing
* Mock connector CLI — starts a prepopulated mock server for developing
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm making this suggestion because the CONTRIBUTING guide uses the en-US flavor for Prerequisites:

- [Prerequisites](#prerequisites)

(It's mostly an outlier in that regard -- the rest of the project feels like it's en-GB, but I'm favoring contributing since I was expected to read it.)

import { FetchError } from 'ofetch'

// Validation pattern for npm org names - url-sage symbold and not start with a dot (incl. ~test24214. or -ex~-)
// Validation pattern for npm org names - url-sage symbol and not start with a dot (incl. ~test24214. or -ex~-)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's possible that symbold is intentional, but there wasn't any obvious support for it...

Copy link
Copy Markdown
Contributor

@graphieros graphieros left a comment

Choose a reason for hiding this comment

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

Thank you!
Can you apply that remaining suggestion from CodeRabbit ?

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@graphieros graphieros left a comment

Choose a reason for hiding this comment

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

LGTM 🌿

@graphieros graphieros added this pull request to the merge queue Apr 29, 2026
Merged via the queue into npmx-dev:main with commit d7511ce Apr 29, 2026
22 checks passed
@github-actions
Copy link
Copy Markdown

Thanks for your first contribution, @jsoref! 🥳

We'd love to welcome you to the npmx community. Come and say hi on Discord! And once you've joined, visit npmx.wamellow.com to claim the contributor role.

Comment thread server/api/registry/org/[org]/packages.get.ts
@jsoref jsoref deleted the spelling branch April 29, 2026 13:26
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.

Spelling errors

3 participants