Skip to content

Renamed activitypub app files and directories to kebab-case#25681

Merged
mike182uk merged 3 commits intomainfrom
mike-ber-3044-use-kebab-case-naming-convention-for-ap-files
Dec 10, 2025
Merged

Renamed activitypub app files and directories to kebab-case#25681
mike182uk merged 3 commits intomainfrom
mike-ber-3044-use-kebab-case-naming-convention-for-ap-files

Conversation

@mike182uk
Copy link
Member

ref https://linear.app/ghost/issue/BER-3044

As part of standardizing naming conventions across the codebase, renamed all PascalCase and camelCase files / directories in the activitypub app to kebab-case. This aligns with the RFC for consistent file naming and matches the convention used in shade and admin-x-settings

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 10, 2025

Walkthrough

This PR renames many files to kebab-case and updates ~60 import specifiers across the ActivityPub app to match. Numerous index/barrel files had default re-exports added or removed. Several usages of the Error component were replaced with AppError. The package version in apps/activitypub/package.json was bumped from 3.0.4 to 3.0.5. No component logic, state, or public API signatures were otherwise changed.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Areas to inspect closely:

  • Confirm all import path updates (absolute and relative) are consistent and no PascalCase paths remain.
  • Verify added/removed barrel re-exports do not break consumer imports or create unresolved imports.
  • Ensure filesystem casing matches kebab-case filenames (important on case-sensitive platforms).
  • Check ErrorAppError replacements for prop compatibility where used in JSX.
  • Sanity-check routes and entry points (routes.tsx, index.tsx, standalone.tsx) after renames.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Renamed activitypub app files and directories to kebab-case' clearly and concisely summarizes the main change across the entire changeset.
Description check ✅ Passed The PR description is directly related to the changeset, referencing the standardization effort (BER-3044) and explaining the rationale for renaming files from PascalCase/camelCase to kebab-case.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mike-ber-3044-use-kebab-case-naming-convention-for-ap-files

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8d6fa5 and 314cb5a.

📒 Files selected for processing (8)
  • apps/activitypub/.eslintrc.cjs (1 hunks)
  • apps/activitypub/src/routes.tsx (3 hunks)
  • apps/activitypub/src/views/feed/feed.tsx (2 hunks)
  • apps/activitypub/src/views/inbox/inbox.tsx (2 hunks)
  • apps/activitypub/src/views/notifications/notifications.tsx (2 hunks)
  • apps/activitypub/src/views/preferences/preferences.tsx (1 hunks)
  • apps/activitypub/src/views/profile/profile.tsx (2 hunks)
  • apps/activitypub/test/.eslintrc.cjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/routes.tsx
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/{src,test}/**/*.{ts,tsx,js} : Follow ESLint and `tailwindcss/*` plugin rules when writing styles

Applied to files:

  • apps/activitypub/test/.eslintrc.cjs
  • apps/activitypub/.eslintrc.cjs
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case

Applied to files:

  • apps/activitypub/test/.eslintrc.cjs
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/.eslintrc.cjs
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Test suite names should follow the format 'Ghost Admin - Feature' or 'Ghost Public - Feature'

Applied to files:

  • apps/activitypub/test/.eslintrc.cjs
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Test names should be lowercase and follow the format 'what is tested - expected outcome'

Applied to files:

  • apps/activitypub/test/.eslintrc.cjs
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/layout/**/*.{ts,tsx} : Reusable layout containers (Page, Heading, Header, ViewHeader, ErrorPage) should be placed in `src/components/layout/*`

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the Ghost ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/features/**/*.{ts,tsx} : Higher-level, opinionated components (e.g., PostShareModal, SourceTabs) should be placed in `src/components/features/*`

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/index.ts : Place new UI components under `src/components/ui` and export them from `src/index.ts`

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
📚 Learning: 2025-08-11T19:39:00.428Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 24651
File: ghost/core/test/utils/urlUtils.js:53-57
Timestamp: 2025-08-11T19:39:00.428Z
Learning: In Ghost's test utilities, when fixing specific issues like async behavior, it's preferred to maintain existing error handling patterns (even if suboptimal) to keep PRs focused on their primary objective. Error handling improvements can be addressed in separate, dedicated PRs.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use the `@` alias for internal imports (e.g., `@/lib/utils`)

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-08-01T12:44:07.467Z
Learnt from: niranjan-uma-shankar
Repo: TryGhost/Ghost PR: 24557
File: apps/admin-x-settings/src/components/settings/general/TimeZone.tsx:7-7
Timestamp: 2025-08-01T12:44:07.467Z
Learning: In Ghost development, PRs may depend on unpublished changes from SDK packages. When this occurs, TypeScript compilation errors for missing exports are expected and documented in the PR description until the dependency packages are published and updated. This is normal workflow for cross-repository feature development.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Prefer compound subcomponents (e.g., `Header.Title`, `Header.Meta`, `Header.Actions`) for multi-region components instead of many props

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Ember admin uses `AdminXComponent` to dynamically import React apps with Suspense and error boundaries

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Use React with Vite for Admin app development (admin-x-settings, admin-x-activitypub, posts, stats)

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names

Applied to files:

  • apps/activitypub/.eslintrc.cjs
  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use CVA (Class Variance Authority) for component variants when useful instead of heavy prop configuration

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ActivityPub tests
  • GitHub Check: Unit tests (Node 22.18.0)
  • GitHub Check: Build & Push Docker Image
🔇 Additional comments (6)
apps/activitypub/src/views/inbox/inbox.tsx (2)

1-4: Imports now correctly use kebab-case paths and AppError alias

AppError aliasing avoids shadowing the global Error, and the updated inbox-list/topic-filter kebab-case paths are consistent with the PR’s naming convention changes. No further changes needed here.


19-21: AppError usage preserves existing error behavior

Rendering <AppError> with errorCode and statusCode maintains the previous behavior while fixing the naming/linting issue. This aligns with the centralized error handling pattern from the hooks.

apps/activitypub/.eslintrc.cjs (1)

23-25: Kebab‑case enforcement looks good; double‑check impact on __*__ style names

This ghost/filenames/match-regex rule cleanly enforces lowercase/digits/dots/hyphens via ^[a-z0-9.-]+$, which matches the PR’s move to kebab‑case filenames in the ActivityPub app.

One thing to verify: this pattern forbids underscores, so any current or future use of __tests__, __mocks__, __fixtures__, etc. under apps/activitypub would start failing lint. If that’s intentional, all good; if not, you may want to widen the regex (for example to allow _) or scope the rule more narrowly to source files only.

apps/activitypub/test/.eslintrc.cjs (1)

5-9: Consistent filename rule for tests; ensure it matches your test/fixture naming patterns

Mirroring the kebab‑case filename rule into the test ESLint config keeps ActivityPub tests aligned with the app’s file naming convention, which is good.

As in the main config, ^[a-z0-9.-]+$ forbids underscores. If your test layout ever uses Jest‑style __tests__, __mocks__, or similar underscored directories, they’ll now violate this rule. Please confirm that’s acceptable for this app, or consider relaxing the pattern just for the test tree if you expect those conventions.

apps/activitypub/src/views/profile/profile.tsx (2)

1-5: LGTM! Import paths updated to kebab-case.

The import path updates align with the PR objectives to standardize file naming to kebab-case. The rename from Error to AppError appropriately resolves the global name shadowing concern identified in the previous review.


149-149: LGTM! Consistent usage of renamed component.

The usage of AppError is consistent with the import change and maintains the existing error handling behavior.


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

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

@mike182uk mike182uk force-pushed the mike-ber-3044-use-kebab-case-naming-convention-for-ap-files branch from 8b77462 to 06062cf Compare December 10, 2025 09:34
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: 3

♻️ Duplicate comments (2)
apps/activitypub/src/views/preferences/preferences.tsx (1)

1-1: Consider renaming the imported Error component to avoid shadowing.

The component name Error shadows the global JavaScript Error constructor. Consider renaming the import to ErrorPage or ErrorComponent for better clarity.

Apply this diff:

-import Error from '@components/layout/error';
+import ErrorPage from '@components/layout/error';

Then update line 13:

-        return <Error errorCode={accountError.code} statusCode={accountError.statusCode} />;
+        return <ErrorPage errorCode={accountError.code} statusCode={accountError.statusCode} />;
apps/activitypub/src/views/inbox/inbox.tsx (1)

1-1: Consider renaming the imported Error component to avoid shadowing.

The component name Error shadows the global JavaScript Error constructor. Consider renaming the import to ErrorPage or ErrorComponent.

Apply this diff:

-import Error from '@components/layout/error';
+import ErrorPage from '@components/layout/error';

Then update line 20:

-        return <Error errorCode={error.code} statusCode={error.statusCode}/>;
+        return <ErrorPage errorCode={error.code} statusCode={error.statusCode}/>;
🧹 Nitpick comments (2)
apps/activitypub/src/views/feed/feed.tsx (1)

1-1: Consider renaming the imported Error component to avoid shadowing.

The component name Error shadows the global JavaScript Error constructor. While this is a pre-existing issue (not introduced by this PR), consider renaming the import to something like ErrorPage or ErrorComponent to improve clarity and avoid potential confusion.

Apply this diff to rename the import:

-import Error from '@components/layout/error';
+import ErrorPage from '@components/layout/error';

Then update the usage on lines 19:

-        return <Error errorCode={error.code} statusCode={error.statusCode}/>;
+        return <ErrorPage errorCode={error.code} statusCode={error.statusCode}/>;

Based on learnings, this follows the pattern where the component identifier (ErrorPage) would be PascalCase while the file remains in kebab-case (error).

apps/activitypub/src/views/profile/profile.tsx (1)

1-5: Rename imported Error to avoid shadowing the global Error constructor

The import path changes to kebab-case look correct, but importing the component as Error shadows the global Error and is flagged by Biome. Consider renaming the import to make intent clearer and satisfy linting:

-import Error from '@components/layout/error';
+import ErrorPage from '@components/layout/error';
...
-        return <Error errorCode={accountError.code} statusCode={accountError.statusCode} />;
+        return <ErrorPage errorCode={accountError.code} statusCode={accountError.statusCode} />;

This keeps behavior the same while avoiding confusion around the global Error symbol. Based on static analysis hints.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28f2384 and 8b77462.

📒 Files selected for processing (62)
  • apps/activitypub/src/components/feed/feed-item-stats.tsx (1 hunks)
  • apps/activitypub/src/components/feed/feed-item.tsx (1 hunks)
  • apps/activitypub/src/components/global/ap-reply-box.tsx (1 hunks)
  • apps/activitypub/src/components/global/image-lightbox.tsx (1 hunks)
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx (1 hunks)
  • apps/activitypub/src/components/global/suggested-profiles.tsx (1 hunks)
  • apps/activitypub/src/components/layout/Error/index.ts (0 hunks)
  • apps/activitypub/src/components/layout/Header/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/Onboarding/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/Sidebar/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/error/error.tsx (1 hunks)
  • apps/activitypub/src/components/layout/error/index.ts (1 hunks)
  • apps/activitypub/src/components/layout/header/header.tsx (1 hunks)
  • apps/activitypub/src/components/layout/header/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/layout.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx (2 hunks)
  • apps/activitypub/src/components/layout/sidebar/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx (1 hunks)
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx (1 hunks)
  • apps/activitypub/src/components/modals/new-note-modal.tsx (1 hunks)
  • apps/activitypub/src/components/modals/search.tsx (1 hunks)
  • apps/activitypub/src/index.tsx (1 hunks)
  • apps/activitypub/src/routes.tsx (1 hunks)
  • apps/activitypub/src/standalone.tsx (1 hunks)
  • apps/activitypub/src/views/Explore/index.tsx (0 hunks)
  • apps/activitypub/src/views/Inbox/index.tsx (0 hunks)
  • apps/activitypub/src/views/Notifications/index.tsx (0 hunks)
  • apps/activitypub/src/views/Preferences/index.tsx (0 hunks)
  • apps/activitypub/src/views/Profile/index.tsx (0 hunks)
  • apps/activitypub/src/views/explore/explore.tsx (1 hunks)
  • apps/activitypub/src/views/explore/index.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/feed-input.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/feed-list.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx (1 hunks)
  • apps/activitypub/src/views/feed/feed.tsx (1 hunks)
  • apps/activitypub/src/views/feed/note.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/components/reader.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/inbox.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/index.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/components/notification-item.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/index.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/notifications.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/moderation.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/profile.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/settings.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/index.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/preferences.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/actor-list.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/likes.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/posts.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/profile-menu.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/profile-page.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/unblock-button.tsx (1 hunks)
  • apps/activitypub/src/views/profile/index.tsx (1 hunks)
  • apps/activitypub/src/views/profile/profile.tsx (1 hunks)
  • apps/admin-x-framework/types/api/roles.d.ts (1 hunks)
💤 Files with no reviewable changes (9)
  • apps/activitypub/src/views/Inbox/index.tsx
  • apps/activitypub/src/views/Notifications/index.tsx
  • apps/activitypub/src/components/layout/Sidebar/index.tsx
  • apps/activitypub/src/components/layout/Error/index.ts
  • apps/activitypub/src/components/layout/Onboarding/index.tsx
  • apps/activitypub/src/views/Explore/index.tsx
  • apps/activitypub/src/components/layout/Header/index.tsx
  • apps/activitypub/src/views/Profile/index.tsx
  • apps/activitypub/src/views/Preferences/index.tsx
🧰 Additional context used
🧠 Learnings (36)
📓 Common learnings
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use CVA (Class Variance Authority) for component variants when useful instead of heavy prop configuration

Applied to files:

  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/views/preferences/components/profile.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/views/feed/components/feed-input.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/note.tsx
📚 Learning: 2025-10-27T11:59:33.968Z
Learnt from: peterzimon
Repo: TryGhost/Ghost PR: 25261
File: apps/admin/src/layout/app-sidebar/UserMenu.tsx:24-29
Timestamp: 2025-10-27T11:59:33.968Z
Learning: In apps/admin/src/layout/app-sidebar/UserMenu.tsx, the hardcoded placeholder data (avatar URL, initials "US", name "User Name", email "userexample.com") is a known limitation and should not be flagged for replacement with real user data.

Applied to files:

  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/components/feed-input.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Prefer compound subcomponents (e.g., `Header.Title`, `Header.Meta`, `Header.Actions`) for multi-region components instead of many props

Applied to files:

  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/features/**/*.{ts,tsx} : Higher-level, opinionated components (e.g., PostShareModal, SourceTabs) should be placed in `src/components/features/*`

Applied to files:

  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/profile/components/posts.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/profile/components/likes.tsx
  • apps/activitypub/src/views/feed/note.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Use React with Vite for Admin app development (admin-x-settings, admin-x-activitypub, posts, stats)

Applied to files:

  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/note.tsx
📚 Learning: 2025-09-02T07:55:08.601Z
Learnt from: minimaluminium
Repo: TryGhost/Ghost PR: 24798
File: apps/admin-x-activitypub/src/components/feed/layouts/FeedLayout.tsx:133-138
Timestamp: 2025-09-02T07:55:08.601Z
Learning: In apps/admin-x-activitypub FeedLayout component, renderFeedAttachment for Article-type objects intentionally receives onClick (card click handler) instead of onImageClick to ensure clicking article images opens the article rather than triggering the image lightbox.

Applied to files:

  • apps/activitypub/src/components/global/image-lightbox.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
📚 Learning: 2025-09-02T07:58:42.097Z
Learnt from: minimaluminium
Repo: TryGhost/Ghost PR: 24798
File: apps/admin-x-activitypub/src/components/feed/layouts/ReplyLayout.tsx:122-122
Timestamp: 2025-09-02T07:58:42.097Z
Learning: In apps/admin-x-activitypub ReplyLayout component, renderFeedAttachment for Article-type objects intentionally receives onClick (card click handler) instead of onImageClick to ensure clicking article images opens the article rather than triggering the image lightbox.

Applied to files:

  • apps/activitypub/src/components/global/image-lightbox.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/feed/note.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use the `@` alias for internal imports (e.g., `@/lib/utils`)

Applied to files:

  • apps/activitypub/src/components/global/image-lightbox.tsx
  • apps/activitypub/src/views/preferences/components/profile.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/feed/components/feed-input.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/profile/components/posts.tsx
  • apps/activitypub/src/views/preferences/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/layout/onboarding/index.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/views/explore/index.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/layout/**/*.{ts,tsx} : Reusable layout containers (Page, Heading, Header, ViewHeader, ErrorPage) should be placed in `src/components/layout/*`

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/sidebar/index.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/components/layout/error/index.ts
  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/index.ts : Place new UI components under `src/components/ui` and export them from `src/index.ts`

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/components/layout/sidebar/index.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/components/layout/error/index.ts
  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/inbox/index.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/views/feed/components/feed-input.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/preferences/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/profile/index.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/layout/onboarding/index.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/notifications/index.tsx
  • apps/activitypub/src/views/explore/index.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/ui/**/*.{ts,tsx} : Atomic UI components should be placed in `src/components/ui/*` and each component must have a corresponding `*.stories.tsx` file next to it for Storybook documentation

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the Ghost ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/components/modals/search.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/components/modals/search.tsx
📚 Learning: 2025-12-09T08:28:22.100Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 25651
File: apps/activitypub/src/components/modals/Search.tsx:183-199
Timestamp: 2025-12-09T08:28:22.100Z
Learning: In apps/activitypub/src/components/modals/Search.tsx, the topic filtering intentionally uses the immediate `query` value while account search uses `debouncedQuery`. This is by design: topic filtering is a local operation that should update instantly, while account search requires server calls and needs debouncing to avoid excessive API requests.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/modals/search.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/views/feed/components/feed-input.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/views/notifications/components/notification-item.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/views/profile/components/likes.tsx
  • apps/activitypub/src/views/feed/note.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Ember admin uses `AdminXComponent` to dynamically import React apps with Suspense and error boundaries

Applied to files:

  • apps/activitypub/src/views/preferences/preferences.tsx
  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/components/feed/feed-item-stats.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-11-25T11:58:51.652Z
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.

Applied to files:

  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names

Applied to files:

  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/note.tsx
📚 Learning: 2025-08-11T14:18:31.752Z
Learnt from: niranjan-uma-shankar
Repo: TryGhost/Ghost PR: 24626
File: apps/portal/src/components/pages/AccountHomePage/components/AccountFooter.js:15-15
Timestamp: 2025-08-11T14:18:31.752Z
Learning: In Ghost, Portal components render within iframes while admin components (like gh-member-details.hbs, dashboard/charts/recents.hbs, and posts/post-activity-feed.hbs) do not render in iframes. Therefore, iframe-related navigation issues only affect Portal components.

Applied to files:

  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Admin-x React apps build to `apps/*/dist` using Vite, which are then copied by `ghost/admin/lib/asset-delivery` to `ghost/core/core/built/admin/assets/*`

Applied to files:

  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: When working on Admin UI features, build in React using `apps/admin-x-*` or `apps/posts` apps

Applied to files:

  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-11-03T12:33:31.093Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 25320
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:10-10
Timestamp: 2025-11-03T12:33:31.093Z
Learning: The Ghost admin apps (apps/admin/**) do not use SSR, so accessing browser APIs like `navigator`, `window`, or `document` at module load time is safe and does not require typeof guards.

Applied to files:

  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use Tailwind CSS scoped via `.shade` class; dark mode uses `.dark`

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/hooks/**/*.{ts,tsx} : Custom React hooks should be placed in `src/hooks/*`

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
📚 Learning: 2025-11-06T05:35:41.162Z
Learnt from: danielraffel
Repo: TryGhost/Ghost PR: 25366
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:13-23
Timestamp: 2025-11-06T05:35:41.162Z
Learning: In apps/admin/src/layout/app-sidebar/NavHeader.tsx, the React component dispatches a synthetic KeyboardEvent to trigger the Ember keymaster.js search modal shortcut. This approach is known to have cross-browser reliability issues but was deferred for architectural refactoring in a separate PR. The recommended fix is to expose a global function or custom DOM event from the Ember app instead of relying on synthetic keyboard events with keymaster.js.

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: React components should be composable and prefer composable components over heavy prop configuration

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
📚 Learning: 2025-07-14T12:20:35.268Z
Learnt from: sagzy
Repo: TryGhost/Ghost PR: 24346
File: apps/admin-x-settings/src/components/settings/growth/Network.tsx:8-12
Timestamp: 2025-07-14T12:20:35.268Z
Learning: The Network component toggle in `apps/admin-x-settings/src/components/settings/growth/Network.tsx` is intentionally implemented as static UI with a no-op onChange handler, as part of a UI-first development approach before connecting actual ActivityPub functionality.

Applied to files:

  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/preferences/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
📚 Learning: 2025-03-13T09:00:20.205Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/utils/pending-activity.ts:13-71
Timestamp: 2025-03-13T09:00:20.205Z
Learning: The pending activity utilities in Ghost's ActivityPub module are thoroughly tested in `apps/admin-x-activitypub/test/unit/utils/pending-activity.ts`, which covers `generatePendingActivityId`, `isPendingActivity`, and `generatePendingActivity` functions.

Applied to files:

  • apps/activitypub/src/components/modals/search.tsx
📚 Learning: 2025-11-05T16:42:12.989Z
Learnt from: rob-ghost
Repo: TryGhost/Ghost PR: 25356
File: apps/admin/test-utils/fixtures/query-client.tsx:17-35
Timestamp: 2025-11-05T16:42:12.989Z
Learning: In apps/admin/test-utils/fixtures/query-client.tsx, the createTestQueryClient function is intentionally duplicated from admin-x-framework to reduce external dependencies in the admin app's test utilities.

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Ghost admin serves admin-x apps from `/ghost/assets/{app-name}/{app-name}.js` URLs

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-05-29T07:45:35.714Z
Learnt from: ErisDS
Repo: TryGhost/Ghost PR: 23582
File: ghost/core/.c8rc.json:24-24
Timestamp: 2025-05-29T07:45:35.714Z
Learning: In Ghost project, app.js files under core/server/web are intentionally excluded from unit test coverage because they are not easily unit-testable due to being entry points with initialization code and side effects.

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/test/unit/**/*.test.{ts,tsx,js} : Vitest unit tests should be located in `test/unit/*` with pattern `test/unit/**/*.(test).(ts|tsx|js)` and use the `render` helper from `test/unit/utils/test-utils.tsx`

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/{src,test}/**/*.{ts,tsx,js} : Follow ESLint and `tailwindcss/*` plugin rules when writing styles

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-12-09T12:37:23.267Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 25501
File: apps/shade/src/hooks/use-mobile.tsx:5-10
Timestamp: 2025-12-09T12:37:23.267Z
Learning: The Ghost admin apps/shade/** components do not use SSR, so accessing browser APIs like `navigator`, `window`, or `document` at module load time is safe and does not require typeof guards.

Applied to files:

  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/components/layout/layout.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Use `shade` design system for new components in Admin UI (avoid legacy `admin-x-design-system`)

Applied to files:

  • apps/activitypub/src/components/layout/header/header.tsx
🪛 Biome (2.1.2)
apps/activitypub/src/views/inbox/inbox.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/preferences/preferences.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/routes.tsx

[error] 2-2: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/profile/profile.tsx

[error] 2-2: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/feed/feed.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/notifications/notifications.tsx

[error] 6-6: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (52)
apps/activitypub/src/standalone.tsx (1)

2-2: Import path casing correctly updated to kebab-case file name

Switching the import to ./app.tsx matches the renamed entry file and keeps the App component API unchanged, aligning with the new naming convention. Based on learnings, this mirrors the kebab-case wrapper + PascalCase component pattern used in other admin-x apps.

apps/activitypub/src/index.tsx (1)

2-2: Entry import updated to new kebab-case module without API changes

Importing from ./app correctly targets the renamed app wrapper while keeping the AdminXApp export stable, so external consumers remain unaffected and the file naming now follows the standardized convention.

apps/activitypub/src/views/preferences/components/moderation.tsx (2)

1-11: Component import changes look correct.

The import statements have been successfully updated to reference kebab-case file paths while preserving PascalCase component identifiers. The JSX usage of these components (APAvatar, ActivityItem, ProfilePreviewHoverCard) remains correct and consistent with the renamed imports.


1-4: Rename custom components to PascalCase.

The imported components (ap-avatar, activity-item, profile-preview-hover-card) are custom components, not ShadCN-generated. According to the codebase standards, custom component filenames should use PascalCase. Rename these files to ApAvatar.tsx, ActivityItem.tsx, and ProfilePreviewHoverCard.tsx, and update the corresponding import paths accordingly.

⛔ Skipped due to learnings
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Prefer compound subcomponents (e.g., `Header.Title`, `Header.Meta`, `Header.Actions`) for multi-region components instead of many props
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use CVA (Class Variance Authority) for component variants when useful instead of heavy prop configuration
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/features/**/*.{ts,tsx} : Higher-level, opinionated components (e.g., PostShareModal, SourceTabs) should be placed in `src/components/features/*`
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/ui/**/*.{ts,tsx} : Atomic UI components should be placed in `src/components/ui/*` and each component must have a corresponding `*.stories.tsx` file next to it for Storybook documentation
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/index.ts : Place new UI components under `src/components/ui` and export them from `src/index.ts`
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use the `@` alias for internal imports (e.g., `@/lib/utils`)
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use Tailwind CSS scoped via `.shade` class; dark mode uses `.dark`
apps/admin-x-framework/types/api/roles.d.ts (1)

20-20: > Likely an incorrect or invalid review comment.

apps/activitypub/src/views/notifications/components/notification-item.tsx (1)

1-1: LGTM!

The import path update to kebab-case aligns with the PR objective and maintains consistency with the file renaming.

apps/activitypub/src/views/notifications/index.tsx (1)

1-1: LGTM!

Standard barrel export pattern that enables importing from the notifications directory directly.

apps/activitypub/src/views/notifications/notifications.tsx (1)

5-5: LGTM!

All import path updates to kebab-case are consistent with the PR objective and align with the file renaming across the ActivityPub app.

Also applies to: 7-14, 17-17

apps/activitypub/src/views/feed/components/feed-input.tsx (1)

1-2: LGTM! Clean refactor to kebab-case.

The import path updates correctly align with the kebab-case naming convention standardization.

apps/activitypub/src/views/profile/components/likes.tsx (1)

1-1: LGTM! Import path correctly updated.

The refactor properly aligns the import with the new kebab-case file structure.

apps/activitypub/src/views/preferences/components/profile.tsx (1)

3-4: LGTM! Import paths correctly updated.

The refactor properly standardizes the imports to kebab-case naming convention.

apps/activitypub/src/components/global/profile-preview-hover-card.tsx (1)

1-1: LGTM! Import path correctly updated.

The refactor aligns with the kebab-case standardization effort.

apps/activitypub/src/components/modals/search.tsx (1)

1-8: LGTM! Import paths systematically updated.

All import path updates correctly align with the kebab-case naming convention standardization.

apps/activitypub/src/components/layout/sidebar/recommendations.tsx (1)

2-4: LGTM! Import paths correctly standardized.

The refactor properly aligns imports with the kebab-case convention.

apps/activitypub/src/views/inbox/components/reader.tsx (1)

1-19: LGTM! Import paths systematically standardized.

All import path updates correctly align with the kebab-case naming convention. The refactoring is consistent and thorough across all component imports.

apps/activitypub/src/components/layout/header/header.tsx (1)

5-5: BackButton import path update looks correct

The import now targets the kebab-case module @src/components/global/back-button while keeping the BackButton symbol unchanged. Both usages in this file remain valid, so behavior is preserved and the change aligns with the new naming convention.

apps/activitypub/src/components/layout/onboarding/step-2.tsx (1)

1-1: Header import casing normalized to kebab-case

Switching the import to ./components/header matches the kebab-case file naming while retaining the same default Header component, so runtime behavior is unchanged and consistent with the PR’s goals.

apps/activitypub/src/components/feed/feed-item-stats.tsx (1)

1-1: NewNoteModal import path correctly updated

The module path is now @components/modals/new-note-modal while the NewNoteModal component usage remains the same, so the reply modal behavior is preserved and aligned with the new kebab-case file naming.

apps/activitypub/src/views/feed/components/suggested-profiles.tsx (1)

1-3: Global component imports correctly migrated to kebab-case modules

APAvatar, FollowButton, and ProfilePreviewHoverCard are now imported from kebab-case module paths while keeping their existing component identifiers and usages. This standardizes file naming without affecting behavior in the suggested profiles carousel.

apps/activitypub/src/views/profile/components/profile-menu.tsx (1)

2-2: UnblockDialog local import normalized to kebab-case

Updating the import to ./unblock-dialog matches the renamed file while preserving the existing UnblockDialog API in renderUnblockView, so dialog behavior for blocked users/domains is unaffected.

apps/activitypub/src/views/preferences/components/settings.tsx (1)

1-1: EditProfile import path updated to kebab-case file

The Settings dialog now imports EditProfile from ./edit-profile, which aligns with the kebab-case filename convention while leaving the dialog logic and props unchanged.

apps/activitypub/src/components/layout/onboarding/index.tsx (1)

1-1: Onboarding barrel re-export is straightforward and useful

Re-exporting both the default onboarding component and useOnboardingStatus from ./onboarding gives a clean entry point without changing runtime behavior. This fits well with the path and naming cleanup in the PR.

apps/activitypub/src/views/explore/index.tsx (1)

1-1: Explore index passthrough export is correct

The index now cleanly re-exports the default Explore view from ./explore, matching the pattern used for other views and supporting the kebab-case path normalization without altering behavior.

apps/activitypub/src/views/feed/feed.tsx (1)

1-2: Import paths correctly updated to kebab-case.

The import path changes align with the PR objective to standardize file naming conventions across the activitypub app.

apps/activitypub/src/views/preferences/preferences.tsx (1)

1-1: Import paths correctly updated to kebab-case.

The import path changes align with the PR objective to standardize file naming conventions.

Also applies to: 3-3, 5-5

apps/activitypub/src/views/profile/components/actor-list.tsx (1)

1-4: LGTM! Import paths correctly updated to kebab-case.

All import path changes are consistent with the PR objective to standardize file naming conventions across the activitypub app.

apps/activitypub/src/components/layout/onboarding/step-1.tsx (1)

1-1: LGTM! Import path correctly updated to kebab-case.

The import path change aligns with the PR objective to standardize file naming conventions.

apps/activitypub/src/views/inbox/inbox.tsx (1)

1-2: Import paths correctly updated to kebab-case.

The import path changes align with the PR objective to standardize file naming conventions across the activitypub app.

Also applies to: 4-4

apps/activitypub/src/components/layout/sidebar/index.tsx (1)

1-1: LGTM! Barrel export file follows standard pattern.

The new index file correctly re-exports the default export from the sidebar module, following common module organization patterns.

apps/activitypub/src/components/global/image-lightbox.tsx (1)

4-4: LGTM! Import path correctly updated to kebab-case.

The import path change aligns with the PR objective to standardize file naming conventions across the activitypub app.

apps/activitypub/src/components/modals/new-note-modal.tsx (1)

2-3: LGTM! Import paths correctly updated to kebab-case.

Both import path changes align with the PR objective to standardize file naming conventions across the activitypub app.

apps/activitypub/src/components/layout/index.tsx (1)

1-1: Barrel now correctly targets kebab-case layout file

The default re-export from ./layout matches the renamed kebab-case file and keeps the public API shape unchanged.

apps/activitypub/src/views/profile/components/unblock-button.tsx (1)

2-2: UnblockDialog import path rename is consistent

Switching to ./unblock-dialog keeps the component usage intact while aligning with the kebab-case file naming.

apps/activitypub/src/views/profile/components/posts.tsx (1)

1-1: FeedItem import now targets kebab-case module

Importing from @src/components/feed/feed-item matches the new filename without altering component usage.

apps/activitypub/src/views/inbox/index.tsx (1)

1-1: Inbox index barrel correctly re-exports default

Re-exporting from ./inbox is a straightforward barrel setup and fits the naming refactor.

apps/activitypub/src/components/layout/error/error.tsx (1)

1-4: Layout and empty-view imports correctly updated to kebab-case

Both imports now point at the renamed kebab-case modules while keeping the same component symbols, so the error view behavior remains unchanged.

apps/activitypub/src/components/layout/header/index.tsx (1)

1-1: Header index barrel matches new file naming

Default re-export from ./header cleanly exposes the Header component via the layout/header directory.

apps/activitypub/src/components/global/ap-reply-box.tsx (1)

3-4: Global reply box imports now reference kebab-case files

APAvatar and NewNoteModal are still used as PascalCase components while their file paths are updated to kebab-case, which aligns with the cross-app naming RFC.

apps/activitypub/src/components/global/suggested-profiles.tsx (1)

1-4: Suggested-profiles component imports consistently moved to kebab-case paths

All local/global component imports now target kebab-case modules while preserving the same component names and usage, matching the PR’s naming standardization.

apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx (1)

1-2: Import path updates look correct and consistent with the new kebab-case structure

Both APAvatar and EditProfile now point at the expected kebab-case modules under @src/components/global and @src/views/preferences/components, matching the refactor pattern elsewhere in the app.

apps/activitypub/src/views/profile/index.tsx (1)

1-1: Barrel re-export for profile is straightforward and safe

export {default} from './profile'; cleanly exposes the view via the folder index without altering behavior.

apps/activitypub/src/components/layout/onboarding/step-3.tsx (1)

1-1: Onboarding imports correctly updated to kebab-case paths

Header and useOnboardingStatus now resolve via ./components/header and ./onboarding, which matches the new local file naming and keeps behavior unchanged.

Also applies to: 21-21

apps/activitypub/src/components/layout/layout.tsx (1)

1-3: Layout imports align with the new kebab-case modules

Header, onboarding (and its hook), sidebar, and NewNoteModal all point to the expected kebab-case files/aliases, preserving the existing layout behavior.

Also applies to: 5-5

apps/activitypub/src/views/preferences/index.tsx (1)

1-1: Preferences barrel export is consistent and non-breaking

export {default} from './preferences'; provides a simple folder entrypoint, matching other view index files.

apps/activitypub/src/views/feed/note.tsx (1)

1-6: Feed note view imports correctly retargeted to kebab-case modules

All UI pieces (APAvatar, APReplyBox, DeletedFeedItem, FeedItem, Layout, ProfilePreviewHoverCard, ShowRepliesButton, EmptyViewIcon/EmptyViewIndicator) now resolve via the kebab-case component files, matching the rest of the ActivityPub refactor without changing runtime behavior.

Also applies to: 8-8, 11-11

apps/activitypub/src/components/layout/error/index.ts (1)

1-1: Error layout barrel export is clean and consistent

Re-exporting the default from ./error via the index file matches the layout barrel pattern used elsewhere and doesn’t alter behavior.

apps/activitypub/src/views/explore/explore.tsx (1)

1-2: Explore view imports correctly updated to kebab-case components and onboarding hook

The updates for APAvatar, FollowButton, ProfilePreviewHoverCard, TopicFilter, and useOnboardingStatus all point at the new kebab-case modules, maintaining existing Explore behavior while aligning with the repo’s naming convention.

Also applies to: 4-4, 6-6, 12-12

apps/activitypub/src/components/feed/feed-item.tsx (1)

1-11: Import path normalization to kebab-case looks consistent

The updated imports for FeedItemMenu, APAvatar, ImageLightbox, ProfilePreviewHoverCard, and FeedItemStats all align with the new kebab-case file naming and preserve default-import usage. No behavioral changes introduced here.

apps/activitypub/src/views/inbox/components/inbox-list.tsx (1)

1-4: Inbox imports correctly updated to new module paths

FeedItem, Reader, and TopicFilter/Topic now point at the kebab-case modules while preserving the same default/named import shapes. This is consistent with the ActivityPub app naming convention refactor.

apps/activitypub/src/components/layout/sidebar/sidebar.tsx (1)

2-7: Sidebar component imports match kebab-case refactor

FeedbackBox, NewNoteModal, Recommendations, Search, SearchInput, and SidebarMenuLink now resolve via kebab-case file paths with unchanged usage. This keeps the sidebar aligned with the new naming convention without affecting behavior.

apps/activitypub/src/views/profile/components/profile-page.tsx (1)

1-18: ProfilePage imports correctly wired to kebab-case modules

All updated imports (APAvatar, EditProfile, FollowButton, ProfileMenu, UnblockButton, EmptyViewIndicator/EmptyViewIcon, SettingAction, and ProfileTab) now point to kebab-case files and the ../profile type export, with unchanged usage patterns. Looks good.

apps/activitypub/src/views/feed/components/feed-list.tsx (1)

1-10: Feed view imports aligned with new kebab-case structure

FeedInput, FeedItem, NewNoteModal, SuggestedProfiles, and EmptyViewIndicator/EmptyViewIcon now resolve via kebab-case module paths, matching the rest of the ActivityPub app, with no change to how the components are used.

@mike182uk mike182uk force-pushed the mike-ber-3044-use-kebab-case-naming-convention-for-ap-files branch 3 times, most recently from 5637076 to 694f09c Compare December 10, 2025 09:38
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

Caution

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

⚠️ Outside diff range comments (1)
apps/activitypub/src/views/preferences/preferences.tsx (1)

1-15: Rename imported Error component to avoid shadowing global Error (Biome error).

The default import name Error shadows the global Error constructor and is flagged as an error by Biome. Renaming the local alias improves clarity and should clear the lint error without affecting behavior.

-import Error from '@components/layout/error';
+import ErrorView from '@components/layout/error';
@@
-    if (accountError && isApiError(accountError)) {
-        return <Error errorCode={accountError.code} statusCode={accountError.statusCode} />;
-    }
+    if (accountError && isApiError(accountError)) {
+        return <ErrorView errorCode={accountError.code} statusCode={accountError.statusCode} />;
+    }
♻️ Duplicate comments (1)
apps/activitypub/src/routes.tsx (1)

2-2: Rename the imported Error component to avoid shadowing the global Error

The imported Error component shadows the global Error constructor, which Biome flags and can be confusing in this module.

You can avoid that by aliasing the component:

-import Error from '@components/layout/error';
+import ErrorPage from '@components/layout/error';
@@
-        element: <Outlet />,
-        errorElement: <Error />, // This will catch all errors in child routes
+        element: <Outlet />,
+        errorElement: <ErrorPage />, // This will catch all errors in child routes
@@
-            {
-                path: '*',
-                element: <Error />
-            }
+            {
+                path: '*',
+                element: <ErrorPage />
+            }

This keeps the global Error available if needed and resolves the linter complaint.

Also applies to: 30-31, 149-151

🧹 Nitpick comments (1)
apps/activitypub/src/views/inbox/inbox.tsx (1)

1-1: Consider renaming the Error import to avoid shadowing the global

Biome is flagging Error because it shadows the global Error constructor. It’s harmless at runtime here but can be confusing and may keep lint red. Renaming the local alias improves clarity and should satisfy the linter.

For example:

-import Error from '@components/layout/error';
+import ErrorView from '@components/layout/error';
...
-        return <Error errorCode={error.code} statusCode={error.statusCode}/>;
+        return <ErrorView errorCode={error.code} statusCode={error.statusCode}/>;

Also applies to: 20-20

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b77462 and 694f09c.

📒 Files selected for processing (62)
  • apps/activitypub/package.json (1 hunks)
  • apps/activitypub/src/components/feed/feed-item-stats.tsx (1 hunks)
  • apps/activitypub/src/components/feed/feed-item.tsx (1 hunks)
  • apps/activitypub/src/components/global/ap-reply-box.tsx (1 hunks)
  • apps/activitypub/src/components/global/image-lightbox.tsx (1 hunks)
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx (1 hunks)
  • apps/activitypub/src/components/global/suggested-profiles.tsx (1 hunks)
  • apps/activitypub/src/components/layout/Error/index.ts (0 hunks)
  • apps/activitypub/src/components/layout/Header/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/Onboarding/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/Sidebar/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/error/error.tsx (1 hunks)
  • apps/activitypub/src/components/layout/error/index.ts (1 hunks)
  • apps/activitypub/src/components/layout/header/header.tsx (1 hunks)
  • apps/activitypub/src/components/layout/header/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/layout.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx (2 hunks)
  • apps/activitypub/src/components/layout/sidebar/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx (1 hunks)
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx (1 hunks)
  • apps/activitypub/src/components/modals/new-note-modal.tsx (1 hunks)
  • apps/activitypub/src/components/modals/search.tsx (1 hunks)
  • apps/activitypub/src/index.tsx (1 hunks)
  • apps/activitypub/src/routes.tsx (1 hunks)
  • apps/activitypub/src/standalone.tsx (1 hunks)
  • apps/activitypub/src/views/Explore/index.tsx (0 hunks)
  • apps/activitypub/src/views/Inbox/index.tsx (0 hunks)
  • apps/activitypub/src/views/Notifications/index.tsx (0 hunks)
  • apps/activitypub/src/views/Preferences/index.tsx (0 hunks)
  • apps/activitypub/src/views/Profile/index.tsx (0 hunks)
  • apps/activitypub/src/views/explore/explore.tsx (1 hunks)
  • apps/activitypub/src/views/explore/index.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/feed-input.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/feed-list.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx (1 hunks)
  • apps/activitypub/src/views/feed/feed.tsx (1 hunks)
  • apps/activitypub/src/views/feed/note.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/components/reader.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/inbox.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/index.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/components/notification-item.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/index.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/notifications.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/moderation.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/profile.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/settings.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/index.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/preferences.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/actor-list.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/likes.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/posts.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/profile-menu.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/profile-page.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/unblock-button.tsx (1 hunks)
  • apps/activitypub/src/views/profile/index.tsx (1 hunks)
  • apps/activitypub/src/views/profile/profile.tsx (1 hunks)
💤 Files with no reviewable changes (9)
  • apps/activitypub/src/components/layout/Onboarding/index.tsx
  • apps/activitypub/src/views/Profile/index.tsx
  • apps/activitypub/src/components/layout/Header/index.tsx
  • apps/activitypub/src/views/Notifications/index.tsx
  • apps/activitypub/src/views/Explore/index.tsx
  • apps/activitypub/src/views/Inbox/index.tsx
  • apps/activitypub/src/components/layout/Error/index.ts
  • apps/activitypub/src/views/Preferences/index.tsx
  • apps/activitypub/src/components/layout/Sidebar/index.tsx
✅ Files skipped from review due to trivial changes (1)
  • apps/activitypub/src/views/feed/components/feed-input.tsx
🚧 Files skipped from review as they are similar to previous changes (33)
  • apps/activitypub/src/components/layout/error/index.ts
  • apps/activitypub/src/views/profile/index.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/components/layout/onboarding/index.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/views/explore/index.tsx
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx
  • apps/activitypub/src/views/preferences/components/profile.tsx
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/components/global/image-lightbox.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/views/inbox/index.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/components/layout/sidebar/index.tsx
  • apps/activitypub/src/views/preferences/index.tsx
  • apps/activitypub/src/views/notifications/index.tsx
  • apps/activitypub/src/components/feed/feed-item-stats.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/views/profile/components/unblock-button.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/components/layout/layout.tsx
  • apps/activitypub/src/views/profile/components/profile-menu.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
🧰 Additional context used
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/layout/**/*.{ts,tsx} : Reusable layout containers (Page, Heading, Header, ViewHeader, ErrorPage) should be placed in `src/components/layout/*`

Applied to files:

  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/index.ts : Place new UI components under `src/components/ui` and export them from `src/index.ts`

Applied to files:

  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Ember admin uses `AdminXComponent` to dynamically import React apps with Suspense and error boundaries

Applied to files:

  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case

Applied to files:

  • apps/activitypub/src/views/notifications/components/notification-item.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/features/**/*.{ts,tsx} : Higher-level, opinionated components (e.g., PostShareModal, SourceTabs) should be placed in `src/components/features/*`

Applied to files:

  • apps/activitypub/src/views/profile/components/posts.tsx
  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use CVA (Class Variance Authority) for component variants when useful instead of heavy prop configuration

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use the `@` alias for internal imports (e.g., `@/lib/utils`)

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.{ts,tsx} : Prefer less comments and give things clear names

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/profile/components/likes.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Prefer compound subcomponents (e.g., `Header.Title`, `Header.Meta`, `Header.Actions`) for multi-region components instead of many props

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Use React with Vite for Admin app development (admin-x-settings, admin-x-activitypub, posts, stats)

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the Ghost ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-03-13T09:00:20.205Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/utils/pending-activity.ts:13-71
Timestamp: 2025-03-13T09:00:20.205Z
Learning: The pending activity utilities in the Ghost ActivityPub module are covered by tests in the file `apps/admin-x-activitypub/test/unit/utils/pending-activity.ts`.

Applied to files:

  • apps/activitypub/package.json
📚 Learning: 2025-03-13T09:00:20.205Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/utils/pending-activity.ts:13-71
Timestamp: 2025-03-13T09:00:20.205Z
Learning: The pending activity utilities in Ghost's ActivityPub module are thoroughly tested in `apps/admin-x-activitypub/test/unit/utils/pending-activity.ts`, which covers `generatePendingActivityId`, `isPendingActivity`, and `generatePendingActivity` functions.

Applied to files:

  • apps/activitypub/package.json
📚 Learning: 2025-12-09T08:28:22.100Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 25651
File: apps/activitypub/src/components/modals/Search.tsx:183-199
Timestamp: 2025-12-09T08:28:22.100Z
Learning: In apps/activitypub/src/components/modals/Search.tsx, the topic filtering intentionally uses the immediate `query` value while account search uses `debouncedQuery`. This is by design: topic filtering is a local operation that should update instantly, while account search requires server calls and needs debouncing to avoid excessive API requests.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: When working on Admin UI features, build in React using `apps/admin-x-*` or `apps/posts` apps

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/hooks/**/*.{ts,tsx} : Custom React hooks should be placed in `src/hooks/*`

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
📚 Learning: 2025-11-06T05:35:41.162Z
Learnt from: danielraffel
Repo: TryGhost/Ghost PR: 25366
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:13-23
Timestamp: 2025-11-06T05:35:41.162Z
Learning: In apps/admin/src/layout/app-sidebar/NavHeader.tsx, the React component dispatches a synthetic KeyboardEvent to trigger the Ember keymaster.js search modal shortcut. This approach is known to have cross-browser reliability issues but was deferred for architectural refactoring in a separate PR. The recommended fix is to expose a global function or custom DOM event from the Ember app instead of relying on synthetic keyboard events with keymaster.js.

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: React components should be composable and prefer composable components over heavy prop configuration

Applied to files:

  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
📚 Learning: 2025-08-11T19:39:00.428Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 24651
File: ghost/core/test/utils/urlUtils.js:53-57
Timestamp: 2025-08-11T19:39:00.428Z
Learning: In Ghost's test utilities, when fixing specific issues like async behavior, it's preferred to maintain existing error handling patterns (even if suboptimal) to keep PRs focused on their primary objective. Error handling improvements can be addressed in separate, dedicated PRs.

Applied to files:

  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-08-01T12:44:07.467Z
Learnt from: niranjan-uma-shankar
Repo: TryGhost/Ghost PR: 24557
File: apps/admin-x-settings/src/components/settings/general/TimeZone.tsx:7-7
Timestamp: 2025-08-01T12:44:07.467Z
Learning: In Ghost development, PRs may depend on unpublished changes from SDK packages. When this occurs, TypeScript compilation errors for missing exports are expected and documented in the PR description until the dependency packages are published and updated. This is normal workflow for cross-repository feature development.

Applied to files:

  • apps/activitypub/src/views/notifications/notifications.tsx
📚 Learning: 2025-09-02T07:58:42.097Z
Learnt from: minimaluminium
Repo: TryGhost/Ghost PR: 24798
File: apps/admin-x-activitypub/src/components/feed/layouts/ReplyLayout.tsx:122-122
Timestamp: 2025-09-02T07:58:42.097Z
Learning: In apps/admin-x-activitypub ReplyLayout component, renderFeedAttachment for Article-type objects intentionally receives onClick (card click handler) instead of onImageClick to ensure clicking article images opens the article rather than triggering the image lightbox.

Applied to files:

  • apps/activitypub/src/views/notifications/notifications.tsx
📚 Learning: 2025-09-02T07:55:08.601Z
Learnt from: minimaluminium
Repo: TryGhost/Ghost PR: 24798
File: apps/admin-x-activitypub/src/components/feed/layouts/FeedLayout.tsx:133-138
Timestamp: 2025-09-02T07:55:08.601Z
Learning: In apps/admin-x-activitypub FeedLayout component, renderFeedAttachment for Article-type objects intentionally receives onClick (card click handler) instead of onImageClick to ensure clicking article images opens the article rather than triggering the image lightbox.

Applied to files:

  • apps/activitypub/src/views/notifications/notifications.tsx
📚 Learning: 2025-10-27T11:59:33.968Z
Learnt from: peterzimon
Repo: TryGhost/Ghost PR: 25261
File: apps/admin/src/layout/app-sidebar/UserMenu.tsx:24-29
Timestamp: 2025-10-27T11:59:33.968Z
Learning: In apps/admin/src/layout/app-sidebar/UserMenu.tsx, the hardcoded placeholder data (avatar URL, initials "US", name "User Name", email "userexample.com") is a known limitation and should not be flagged for replacement with real user data.

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use Tailwind CSS scoped via `.shade` class; dark mode uses `.dark`

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
📚 Learning: 2025-11-25T11:58:51.652Z
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.

Applied to files:

  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-07-14T12:20:35.268Z
Learnt from: sagzy
Repo: TryGhost/Ghost PR: 24346
File: apps/admin-x-settings/src/components/settings/growth/Network.tsx:8-12
Timestamp: 2025-07-14T12:20:35.268Z
Learning: The Network component toggle in `apps/admin-x-settings/src/components/settings/growth/Network.tsx` is intentionally implemented as static UI with a no-op onChange handler, as part of a UI-first development approach before connecting actual ActivityPub functionality.

Applied to files:

  • apps/activitypub/src/index.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Admin-x React apps build to `apps/*/dist` using Vite, which are then copied by `ghost/admin/lib/asset-delivery` to `ghost/core/core/built/admin/assets/*`

Applied to files:

  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-08-11T14:18:31.752Z
Learnt from: niranjan-uma-shankar
Repo: TryGhost/Ghost PR: 24626
File: apps/portal/src/components/pages/AccountHomePage/components/AccountFooter.js:15-15
Timestamp: 2025-08-11T14:18:31.752Z
Learning: In Ghost, Portal components render within iframes while admin components (like gh-member-details.hbs, dashboard/charts/recents.hbs, and posts/post-activity-feed.hbs) do not render in iframes. Therefore, iframe-related navigation issues only affect Portal components.

Applied to files:

  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-03T12:33:31.093Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 25320
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:10-10
Timestamp: 2025-11-03T12:33:31.093Z
Learning: The Ghost admin apps (apps/admin/**) do not use SSR, so accessing browser APIs like `navigator`, `window`, or `document` at module load time is safe and does not require typeof guards.

Applied to files:

  • apps/activitypub/src/routes.tsx
🪛 Biome (2.1.2)
apps/activitypub/src/views/profile/profile.tsx

[error] 2-2: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/inbox/inbox.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/notifications/notifications.tsx

[error] 6-6: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/feed/feed.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/routes.tsx

[error] 2-2: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/preferences/preferences.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (17)
apps/activitypub/src/views/profile/components/posts.tsx (1)

1-1: Import path rename correctly aligned with kebab-case convention

The FeedItem import now targets the kebab-case module path @src/components/feed/feed-item, matching the PR’s naming standardization while preserving the existing API/usage. No functional impact, looks good.

apps/activitypub/src/views/profile/components/likes.tsx (1)

1-1: LGTM! Import path correctly updated to kebab-case.

The import path has been properly updated to reflect the renamed file while preserving the PascalCase component identifier. This aligns with the PR objectives to standardize file naming conventions across the activitypub app.

apps/activitypub/src/views/inbox/inbox.tsx (1)

1-2: Kebab-case import path updates look consistent

The updated import paths (@components/layout/error, ./components/inbox-list, @src/components/topic-filter) match the new kebab-case convention and preserve the existing behavior. No issues here.

Also applies to: 4-4

apps/activitypub/src/components/layout/sidebar/sidebar.tsx (1)

2-7: Import path renames correctly align with kebab-case convention

The updated imports consistently switch to kebab-case filenames and lowercase directory names while keeping the same default import identifiers. This matches the PR’s goal of standardizing ActivityPub file naming without impacting runtime behavior. No issues spotted here.

apps/activitypub/src/index.tsx (1)

2-2: Import path correctly updated to kebab-case convention.

The import path has been properly updated to reflect the file rename from ./App to ./app. The component identifier remains PascalCase as expected for React components, and the public API is preserved through the AdminXApp export alias. The renamed file exists and no dangling references to the old path remain.

apps/activitypub/src/views/notifications/components/notification-item.tsx (1)

1-1: LGTM!

The import path has been correctly updated to kebab-case, aligning with the PR's objective to standardize file naming conventions.

apps/activitypub/src/views/notifications/notifications.tsx (1)

5-17: LGTM! Systematic import path updates.

All import paths have been correctly updated to kebab-case, maintaining consistency across the notification view. The changes are systematic and align with the PR's objective to standardize file naming conventions.

apps/activitypub/src/views/feed/feed.tsx (1)

1-2: Imports correctly updated to kebab‑case paths

The updated Error and FeedList import paths match the new kebab‑case layout and keep usages intact; no functional changes introduced here.

apps/activitypub/src/views/feed/components/feed-list.tsx (1)

1-2: Import paths normalized to kebab‑case without behavioral change

All affected imports now point to the kebab‑case module names while preserving the same component identifiers and usages; this cleanly matches the PR’s naming‑only scope.

Also applies to: 4-5, 9-9

apps/activitypub/src/views/preferences/components/settings.tsx (1)

1-1: LGTM!

The import path update from './EditProfile' to './edit-profile' correctly reflects the kebab-case naming convention migration. The component identifier remains properly PascalCased.

apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx (1)

1-2: LGTM!

Both import path updates correctly reflect the kebab-case naming convention:

  • APAvatar: ap-avatar
  • EditProfile: preferences/components/edit-profile (note the directory name also lowercased)

Component identifiers remain properly PascalCased throughout the file.

apps/activitypub/src/components/global/suggested-profiles.tsx (1)

1-4: LGTM!

All four import path updates correctly reflect the kebab-case naming convention:

  • APAvatar → ap-avatar
  • ActivityItem → activity-item
  • FollowButton → follow-button
  • ProfilePreviewHoverCard → profile-preview-hover-card

The updates handle relative, parent-relative, and alias-based paths consistently. Component identifiers remain properly PascalCased.

apps/activitypub/src/views/inbox/components/reader.tsx (1)

1-19: Import path renames to kebab-case are consistent and safe

The updated imports correctly point to kebab-case module paths while preserving the existing component APIs (PascalCase identifiers and named exports). All imported symbols are used later in this file, and there are no behavioral changes introduced here. Looks good and aligned with the PR’s naming-convention objective.

apps/activitypub/src/components/layout/onboarding/step-3.tsx (1)

1-1: LGTM! Import paths correctly updated to kebab-case.

The import path updates correctly reflect the file renaming from PascalCase to kebab-case. Component identifiers remain properly PascalCase (Header, useOnboardingStatus), which is the correct React convention.

Note: Retrieved learnings indicate that apps/shade uses PascalCase for component filenames, but this PR explicitly aligns activitypub with an RFC for consistent kebab-case naming (per PR objectives and issue BER-3044), suggesting this is an intentional architectural decision to standardize conventions across different areas of the codebase.

Also applies to: 21-21

apps/activitypub/src/components/layout/error/error.tsx (1)

1-3: Kebab-case import path updates look correct and non-breaking.

The updated Layout and EmptyView* import paths align with the new kebab-case convention and preserve behavior.

apps/activitypub/package.json (1)

3-3: Patch version bump is appropriate for a non-functional refactor

Moving from 3.0.4 to 3.0.5 matches the internal-only, naming-convention changes in this PR and keeps semver consistent.

apps/activitypub/src/routes.tsx (1)

1-14: Kebab-case import path updates look consistent with the new convention

The updated imports for BlueskySharing, Explore, Feed, Note, Notifications, Preferences, and Profile all correctly point to the new kebab-case paths and preserve the existing component usage.

ref https://linear.app/ghost/issue/BER-3044

As part of standardizing naming conventions across the codebase, renamed
all PascalCase and camelCase files/directories in the ActivityPub app to
kebab-case. This aligns with the RFC for consistent file naming and
matches the convention used in shade and admin-x-settings.

- Renamed ~50 component files (e.g., FeedItem.tsx → feed-item.tsx)
- Renamed ~10 directories (e.g., views/Profile/ → views/profile/)
- Updated all import statements to reference new paths
- Hooks and utils were already kebab-case, no changes needed
@mike182uk mike182uk force-pushed the mike-ber-3044-use-kebab-case-naming-convention-for-ap-files branch from 694f09c to ede5d6d Compare December 10, 2025 10:40
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 (5)
apps/activitypub/src/views/profile/components/profile-menu.tsx (1)

2-2: Import path rename to kebab-case is consistent and correct

The default import of UnblockDialog now points to ./unblock-dialog, which matches the kebab-case filename convention being adopted across ActivityPub and aligns with existing shade conventions. Just ensure the on-disk file is actually renamed to unblock-dialog.tsx so this works on case-sensitive file systems.

apps/activitypub/src/views/preferences/preferences.tsx (1)

1-1: Rename imported Error to avoid shadowing the global constructor

Importing as Error shadows the built‑in Error constructor and trips the Biome noShadowRestrictedNames rule, which can be confusing.

Consider renaming the import and its JSX usage, e.g.:

-import Error from '@components/layout/error';
+import AppError from '@components/layout/error';
@@
-        return <Error errorCode={accountError.code} statusCode={accountError.statusCode} />;
+        return <AppError errorCode={accountError.code} statusCode={accountError.statusCode} />;

This keeps intent clear and avoids conflicts with the global Error.

apps/activitypub/src/views/feed/feed.tsx (1)

1-2: Normalize import paths and avoid shadowing global Error

The move to @components/layout/error and ./components/feed-list looks correct and consistent with the kebab-case refactor.

To address the lint warning and avoid confusion with the global Error, consider renaming the imported component locally, e.g.:

-import Error from '@components/layout/error';
+import AppError from '@components/layout/error';

and update its usage:

-    if (error && isApiError(error)) {
-        return <Error errorCode={error.code} statusCode={error.statusCode}/>;
-    }
+    if (error && isApiError(error)) {
+        return <AppError errorCode={error.code} statusCode={error.statusCode} />;
+    }

This keeps behavior identical while satisfying the linter and making the intent clearer.

apps/activitypub/src/views/feed/note.tsx (1)

1-11: Import paths correctly updated to kebab-case.

All imported files exist at their new kebab-case paths and no stale references remain. The component names are correctly preserved in PascalCase (APAvatar, APReplyBox, DeletedFeedItem, etc.), aligning with the PR's file naming standardization objectives.

Note: The file uses both @src/components and @components aliases inconsistently (lines 1–3, 5, 8–9, 11 use @src; lines 4, 6 use @components). Consider standardizing to a single alias pattern for consistency across the app.

apps/activitypub/src/views/feed/components/suggested-profiles.tsx (1)

123-132: Dismiss button is permanently hidden and effectively dead code

The dismiss button uses the hidden class with no conditional or group-hover override, and handleDismiss is a TODO/no-op. That makes the close affordance unusable in practice.

If dismissal isn’t planned yet, consider removing the button (and TODO) for now; if it is planned, you may want to make the button visible (e.g., on hover) and wire up the handler in a follow-up change.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 694f09c and ede5d6d.

📒 Files selected for processing (62)
  • apps/activitypub/package.json (1 hunks)
  • apps/activitypub/src/components/feed/feed-item-stats.tsx (1 hunks)
  • apps/activitypub/src/components/feed/feed-item.tsx (1 hunks)
  • apps/activitypub/src/components/global/ap-reply-box.tsx (1 hunks)
  • apps/activitypub/src/components/global/image-lightbox.tsx (1 hunks)
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx (1 hunks)
  • apps/activitypub/src/components/global/suggested-profiles.tsx (1 hunks)
  • apps/activitypub/src/components/layout/Error/index.ts (0 hunks)
  • apps/activitypub/src/components/layout/Header/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/Onboarding/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/Sidebar/index.tsx (0 hunks)
  • apps/activitypub/src/components/layout/error/error.tsx (1 hunks)
  • apps/activitypub/src/components/layout/error/index.ts (1 hunks)
  • apps/activitypub/src/components/layout/header/header.tsx (1 hunks)
  • apps/activitypub/src/components/layout/header/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/layout.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx (1 hunks)
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx (2 hunks)
  • apps/activitypub/src/components/layout/sidebar/index.tsx (1 hunks)
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx (1 hunks)
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx (1 hunks)
  • apps/activitypub/src/components/modals/new-note-modal.tsx (1 hunks)
  • apps/activitypub/src/components/modals/search.tsx (1 hunks)
  • apps/activitypub/src/index.tsx (1 hunks)
  • apps/activitypub/src/routes.tsx (3 hunks)
  • apps/activitypub/src/standalone.tsx (1 hunks)
  • apps/activitypub/src/views/Explore/index.tsx (0 hunks)
  • apps/activitypub/src/views/Inbox/index.tsx (0 hunks)
  • apps/activitypub/src/views/Notifications/index.tsx (0 hunks)
  • apps/activitypub/src/views/Preferences/index.tsx (0 hunks)
  • apps/activitypub/src/views/Profile/index.tsx (0 hunks)
  • apps/activitypub/src/views/explore/explore.tsx (1 hunks)
  • apps/activitypub/src/views/explore/index.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/feed-input.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/feed-list.tsx (1 hunks)
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx (1 hunks)
  • apps/activitypub/src/views/feed/feed.tsx (1 hunks)
  • apps/activitypub/src/views/feed/note.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/components/reader.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/inbox.tsx (1 hunks)
  • apps/activitypub/src/views/inbox/index.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/components/notification-item.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/index.tsx (1 hunks)
  • apps/activitypub/src/views/notifications/notifications.tsx (2 hunks)
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/moderation.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/profile.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/components/settings.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/index.tsx (1 hunks)
  • apps/activitypub/src/views/preferences/preferences.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/actor-list.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/likes.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/posts.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/profile-menu.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/profile-page.tsx (1 hunks)
  • apps/activitypub/src/views/profile/components/unblock-button.tsx (1 hunks)
  • apps/activitypub/src/views/profile/index.tsx (1 hunks)
  • apps/activitypub/src/views/profile/profile.tsx (2 hunks)
💤 Files with no reviewable changes (9)
  • apps/activitypub/src/views/Explore/index.tsx
  • apps/activitypub/src/views/Inbox/index.tsx
  • apps/activitypub/src/components/layout/Sidebar/index.tsx
  • apps/activitypub/src/components/layout/Error/index.ts
  • apps/activitypub/src/views/Notifications/index.tsx
  • apps/activitypub/src/components/layout/Header/index.tsx
  • apps/activitypub/src/components/layout/Onboarding/index.tsx
  • apps/activitypub/src/views/Profile/index.tsx
  • apps/activitypub/src/views/Preferences/index.tsx
✅ Files skipped from review due to trivial changes (2)
  • apps/activitypub/src/components/layout/sidebar/recommendations.tsx
  • apps/activitypub/src/views/notifications/index.tsx
🚧 Files skipped from review as they are similar to previous changes (30)
  • apps/activitypub/src/components/feed/feed-item-stats.tsx
  • apps/activitypub/src/views/preferences/index.tsx
  • apps/activitypub/src/views/profile/components/posts.tsx
  • apps/activitypub/src/components/layout/sidebar/index.tsx
  • apps/activitypub/src/components/modals/new-note-modal.tsx
  • apps/activitypub/src/views/feed/components/feed-input.tsx
  • apps/activitypub/src/components/global/profile-preview-hover-card.tsx
  • apps/activitypub/src/views/profile/components/unblock-button.tsx
  • apps/activitypub/src/components/layout/onboarding/index.tsx
  • apps/activitypub/package.json
  • apps/activitypub/src/components/feed/feed-item.tsx
  • apps/activitypub/src/components/layout/error/index.ts
  • apps/activitypub/src/components/layout/onboarding/step-3.tsx
  • apps/activitypub/src/components/global/ap-reply-box.tsx
  • apps/activitypub/src/index.tsx
  • apps/activitypub/src/views/feed/components/feed-list.tsx
  • apps/activitypub/src/views/explore/explore.tsx
  • apps/activitypub/src/components/layout/header/header.tsx
  • apps/activitypub/src/views/preferences/components/bluesky-sharing.tsx
  • apps/activitypub/src/views/profile/index.tsx
  • apps/activitypub/src/views/preferences/components/profile.tsx
  • apps/activitypub/src/views/inbox/components/inbox-list.tsx
  • apps/activitypub/src/views/profile/components/profile-page.tsx
  • apps/activitypub/src/views/inbox/index.tsx
  • apps/activitypub/src/views/explore/index.tsx
  • apps/activitypub/src/components/modals/search.tsx
  • apps/activitypub/src/components/layout/sidebar/sidebar.tsx
  • apps/activitypub/src/components/global/suggested-profiles.tsx
  • apps/activitypub/src/views/notifications/notifications.tsx
  • apps/activitypub/src/components/layout/layout.tsx
🧰 Additional context used
🧠 Learnings (33)
📓 Common learnings
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use `PascalCase` for component identifiers in filenames while keeping ShadCN-generated files in kebab-case

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Use CVA (Class Variance Authority) for component variants when useful instead of heavy prop configuration

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/views/profile/components/actor-list.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the Ghost ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-03-13T09:02:50.102Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/views/Feed/components/NewPostModal.tsx:29-34
Timestamp: 2025-03-13T09:02:50.102Z
Learning: In the ActivityPub module, error handling for mutations is handled at the hook level (in use-activity-pub-queries.ts) rather than in individual components. This allows for centralized error handling across the application.

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use the `@` alias for internal imports (e.g., `@/lib/utils`)

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/preferences/components/settings.tsx
  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/global/image-lightbox.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/features/**/*.{ts,tsx} : Higher-level, opinionated components (e.g., PostShareModal, SourceTabs) should be placed in `src/components/features/*`

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/components/reader.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
📚 Learning: 2025-08-11T19:39:00.428Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 24651
File: ghost/core/test/utils/urlUtils.js:53-57
Timestamp: 2025-08-11T19:39:00.428Z
Learning: In Ghost's test utilities, when fixing specific issues like async behavior, it's preferred to maintain existing error handling patterns (even if suboptimal) to keep PRs focused on their primary objective. Error handling improvements can be addressed in separate, dedicated PRs.

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/layout/**/*.{ts,tsx} : Reusable layout containers (Page, Heading, Header, ViewHeader, ErrorPage) should be placed in `src/components/layout/*`

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
  • apps/activitypub/src/views/feed/feed.tsx
  • apps/activitypub/src/views/inbox/inbox.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-08-01T12:44:07.467Z
Learnt from: niranjan-uma-shankar
Repo: TryGhost/Ghost PR: 24557
File: apps/admin-x-settings/src/components/settings/general/TimeZone.tsx:7-7
Timestamp: 2025-08-01T12:44:07.467Z
Learning: In Ghost development, PRs may depend on unpublished changes from SDK packages. When this occurs, TypeScript compilation errors for missing exports are expected and documented in the PR description until the dependency packages are published and updated. This is normal workflow for cross-repository feature development.

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Use React with Vite for Admin app development (admin-x-settings, admin-x-activitypub, posts, stats)

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/views/feed/components/suggested-profiles.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Ember admin uses `AdminXComponent` to dynamically import React apps with Suspense and error boundaries

Applied to files:

  • apps/activitypub/src/views/profile/profile.tsx
  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/index.ts : Place new UI components under `src/components/ui` and export them from `src/index.ts`

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-1.tsx
  • apps/activitypub/src/components/layout/error/error.tsx
  • apps/activitypub/src/components/layout/index.tsx
  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/**/*.{ts,tsx,js} : Use `camelCase` for function and variable names

Applied to files:

  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-09-02T07:58:42.097Z
Learnt from: minimaluminium
Repo: TryGhost/Ghost PR: 24798
File: apps/admin-x-activitypub/src/components/feed/layouts/ReplyLayout.tsx:122-122
Timestamp: 2025-09-02T07:58:42.097Z
Learning: In apps/admin-x-activitypub ReplyLayout component, renderFeedAttachment for Article-type objects intentionally receives onClick (card click handler) instead of onImageClick to ensure clicking article images opens the article rather than triggering the image lightbox.

Applied to files:

  • apps/activitypub/src/views/feed/note.tsx
  • apps/activitypub/src/components/global/image-lightbox.tsx
📚 Learning: 2025-11-25T11:58:51.652Z
Learnt from: ibalosh
Repo: TryGhost/Ghost PR: 25525
File: apps/shade/src/shade-app.tsx:4-4
Timestamp: 2025-11-25T11:58:51.652Z
Learning: In apps/shade, the app wrapper file should be named `src/shade-app.tsx` (kebab-case) while the component itself is exported as `ShadeApp` (PascalCase). Context providers should be placed in `src/providers/*` using kebab-case filenames.

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/ui/**/*.{ts,tsx} : Atomic UI components should be placed in `src/components/ui/*` and each component must have a corresponding `*.stories.tsx` file next to it for Storybook documentation

Applied to files:

  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
📚 Learning: 2025-11-05T16:42:12.989Z
Learnt from: rob-ghost
Repo: TryGhost/Ghost PR: 25356
File: apps/admin/test-utils/fixtures/query-client.tsx:17-35
Timestamp: 2025-11-05T16:42:12.989Z
Learning: In apps/admin/test-utils/fixtures/query-client.tsx, the createTestQueryClient function is intentionally duplicated from admin-x-framework to reduce external dependencies in the admin app's test utilities.

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Admin-x React apps build to `apps/*/dist` using Vite, which are then copied by `ghost/admin/lib/asset-delivery` to `ghost/core/core/built/admin/assets/*`

Applied to files:

  • apps/activitypub/src/standalone.tsx
  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Ghost admin serves admin-x apps from `/ghost/assets/{app-name}/{app-name}.js` URLs

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-05-29T07:45:35.714Z
Learnt from: ErisDS
Repo: TryGhost/Ghost PR: 23582
File: ghost/core/.c8rc.json:24-24
Timestamp: 2025-05-29T07:45:35.714Z
Learning: In Ghost project, app.js files under core/server/web are intentionally excluded from unit test coverage because they are not easily unit-testable due to being entry points with initialization code and side effects.

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/test/unit/**/*.test.{ts,tsx,js} : Vitest unit tests should be located in `test/unit/*` with pattern `test/unit/**/*.(test).(ts|tsx|js)` and use the `render` helper from `test/unit/utils/test-utils.tsx`

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/{src,test}/**/*.{ts,tsx,js} : Follow ESLint and `tailwindcss/*` plugin rules when writing styles

Applied to files:

  • apps/activitypub/src/standalone.tsx
📚 Learning: 2025-09-02T07:55:08.601Z
Learnt from: minimaluminium
Repo: TryGhost/Ghost PR: 24798
File: apps/admin-x-activitypub/src/components/feed/layouts/FeedLayout.tsx:133-138
Timestamp: 2025-09-02T07:55:08.601Z
Learning: In apps/admin-x-activitypub FeedLayout component, renderFeedAttachment for Article-type objects intentionally receives onClick (card click handler) instead of onImageClick to ensure clicking article images opens the article rather than triggering the image lightbox.

Applied to files:

  • apps/activitypub/src/components/global/image-lightbox.tsx
📚 Learning: 2025-11-26T11:05:59.314Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: apps/shade/AGENTS.md:0-0
Timestamp: 2025-11-26T11:05:59.314Z
Learning: Applies to apps/shade/src/components/**/*.{ts,tsx} : Prefer compound subcomponents (e.g., `Header.Title`, `Header.Meta`, `Header.Actions`) for multi-region components instead of many props

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/components/layout/header/index.tsx
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.{ts,tsx} : Prefer less comments and give things clear names

Applied to files:

  • apps/activitypub/src/components/layout/onboarding/step-2.tsx
  • apps/activitypub/src/routes.tsx
  • apps/activitypub/src/views/profile/components/likes.tsx
  • apps/activitypub/src/views/preferences/components/moderation.tsx
  • apps/activitypub/src/views/preferences/preferences.tsx
📚 Learning: 2025-11-06T05:35:41.162Z
Learnt from: danielraffel
Repo: TryGhost/Ghost PR: 25366
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:13-23
Timestamp: 2025-11-06T05:35:41.162Z
Learning: In apps/admin/src/layout/app-sidebar/NavHeader.tsx, the React component dispatches a synthetic KeyboardEvent to trigger the Ember keymaster.js search modal shortcut. This approach is known to have cross-browser reliability issues but was deferred for architectural refactoring in a separate PR. The recommended fix is to expose a global function or custom DOM event from the Ember app instead of relying on synthetic keyboard events with keymaster.js.

Applied to files:

  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-08-11T14:18:31.752Z
Learnt from: niranjan-uma-shankar
Repo: TryGhost/Ghost PR: 24626
File: apps/portal/src/components/pages/AccountHomePage/components/AccountFooter.js:15-15
Timestamp: 2025-08-11T14:18:31.752Z
Learning: In Ghost, Portal components render within iframes while admin components (like gh-member-details.hbs, dashboard/charts/recents.hbs, and posts/post-activity-feed.hbs) do not render in iframes. Therefore, iframe-related navigation issues only affect Portal components.

Applied to files:

  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: When working on Admin UI features, build in React using `apps/admin-x-*` or `apps/posts` apps

Applied to files:

  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-11-03T12:33:31.093Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 25320
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:10-10
Timestamp: 2025-11-03T12:33:31.093Z
Learning: The Ghost admin apps (apps/admin/**) do not use SSR, so accessing browser APIs like `navigator`, `window`, or `document` at module load time is safe and does not require typeof guards.

Applied to files:

  • apps/activitypub/src/routes.tsx
📚 Learning: 2025-10-30T17:13:26.190Z
Learnt from: sam-lord
Repo: TryGhost/Ghost PR: 25303
File: ghost/core/core/server/services/email-service/BatchSendingService.js:19-19
Timestamp: 2025-10-30T17:13:26.190Z
Learning: In ghost/core/core/server/services/email-service/BatchSendingService.js and similar files in the Ghost codebase, prefer using `{...options}` spread syntax without explicit guards like `...(options || {})` when spreading potentially undefined objects, as the maintainer prefers cleaner syntax over defensive patterns when the behavior is safe.

Applied to files:

  • apps/activitypub/src/views/preferences/components/moderation.tsx
📚 Learning: 2025-03-13T09:00:20.205Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/utils/pending-activity.ts:13-71
Timestamp: 2025-03-13T09:00:20.205Z
Learning: The pending activity utilities in Ghost's ActivityPub module are thoroughly tested in `apps/admin-x-activitypub/test/unit/utils/pending-activity.ts`, which covers `generatePendingActivityId`, `isPendingActivity`, and `generatePendingActivity` functions.

Applied to files:

  • apps/activitypub/src/views/preferences/components/moderation.tsx
📚 Learning: 2025-12-09T08:28:22.100Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 25651
File: apps/activitypub/src/components/modals/Search.tsx:183-199
Timestamp: 2025-12-09T08:28:22.100Z
Learning: In apps/activitypub/src/components/modals/Search.tsx, the topic filtering intentionally uses the immediate `query` value while account search uses `debouncedQuery`. This is by design: topic filtering is a local operation that should update instantly, while account search requires server calls and needs debouncing to avoid excessive API requests.

Applied to files:

  • apps/activitypub/src/views/inbox/inbox.tsx
🪛 Biome (2.1.2)
apps/activitypub/src/views/feed/feed.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/inbox/inbox.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

apps/activitypub/src/views/preferences/preferences.tsx

[error] 1-1: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Unit tests (Node 22.18.0)
  • GitHub Check: ActivityPub tests
  • GitHub Check: Lint
  • GitHub Check: Build & Push Docker Image
🔇 Additional comments (19)
apps/activitypub/src/views/preferences/components/moderation.tsx (1)

1-4: Imports now correctly use @components alias and kebab-case paths

The updated imports align with the ActivityPub conventions: components come from the @components/... alias and the paths use kebab-case to match the renamed files. This also resolves the earlier review note about avoiding @src/components/* for these modules. No functional changes introduced here, looks good.

apps/activitypub/src/views/preferences/components/settings.tsx (1)

1-1: LGTM! Import path correctly updated to kebab-case.

The import path change from ./EditProfile to ./edit-profile aligns with the PR's objective to standardize file naming to kebab-case while maintaining the PascalCase component name EditProfile.

apps/activitypub/src/views/preferences/preferences.tsx (1)

3-5: Kebab-case component import paths look correct

The updated imports for Profile and Settings now reference kebab-case file paths under ./components, which matches the PR’s stated goal and keeps the local API unchanged. No further changes needed here.

apps/activitypub/src/components/global/image-lightbox.tsx (1)

4-4: Import path normalization to kebab-case looks correct

Switching the getAttachment import to @components/feed/feed-item matches the new kebab-case convention and should be a no-op at runtime as long as the module was renamed consistently.

apps/activitypub/src/views/profile/components/likes.tsx (1)

1-1: FeedItem import updated consistently to kebab-case

The FeedItem import now targets @src/components/feed/feed-item, aligning with the new file naming convention without affecting component behavior.

apps/activitypub/src/views/notifications/components/notification-item.tsx (1)

1-1: NotificationIcon import path update is correct

Importing NotificationIcon from ./notification-icon aligns with the kebab-case file rename and should be a safe, behavior-preserving change.

apps/activitypub/src/components/layout/onboarding/step-1.tsx (1)

1-1: Import path correctly updated to kebab-case and consistently applied throughout the codebase.

The change from @src/components/global/APAvatar to @src/components/global/ap-avatar is correct. Verification confirms all 29 APAvatar imports across the activitypub app have been consistently updated to use the kebab-case file path, with no remaining old-style PascalCase imports.

apps/activitypub/src/views/inbox/components/reader.tsx (1)

1-1: Import path casing updates look consistent with the new convention

The updated imports correctly switch to kebab-case file paths and still align with how each component/type is used later in this file. I don’t see any obvious typos or mismatches in the new paths or named/default imports.

Also applies to: 3-3, 10-20

apps/activitypub/src/views/feed/components/suggested-profiles.tsx (1)

1-3: Import renames correctly follow the new kebab-case convention

These imports now point at kebab-case module paths and preserve the same default exports, so they’re consistent with the PR’s naming standardization and don’t change behavior.

apps/activitypub/src/components/layout/header/index.tsx (1)

1-1: LGTM! Clean barrel file re-export.

The re-export aligns with the kebab-case naming convention established in this PR.

apps/activitypub/src/components/layout/onboarding/step-2.tsx (1)

1-1: LGTM! Import path updated to kebab-case.

The path change from ./components/Header to ./components/header correctly aligns with the kebab-case convention.

apps/activitypub/src/components/layout/index.tsx (1)

1-1: LGTM! Re-export path normalized to lowercase.

The path change from ./Layout to ./layout maintains consistency with the kebab-case naming convention.

apps/activitypub/src/standalone.tsx (1)

2-2: LGTM! App import path updated to lowercase.

The path change from ./App.tsx to ./app.tsx aligns with the kebab-case file naming convention.

apps/activitypub/src/views/profile/components/actor-list.tsx (1)

1-4: LGTM! All component imports updated to kebab-case paths.

The import path changes for APAvatar, ActivityItem, FollowButton, and ProfilePreviewHoverCard correctly reflect the kebab-case naming convention while preserving the component identifiers.

apps/activitypub/src/components/layout/error/error.tsx (1)

1-3: LGTM! Import paths normalized to kebab-case.

Both Layout and EmptyViewIndicator import paths have been correctly updated to lowercase kebab-case while maintaining the component functionality.

apps/activitypub/src/views/inbox/inbox.tsx (1)

2-4: LGTM! Import paths normalized to kebab-case.

The InboxList and Topic import paths have been correctly updated to kebab-case.

apps/activitypub/src/views/profile/profile.tsx (1)

1-5: LGTM! Import paths updated to kebab-case and Error properly aliased.

All import paths have been correctly normalized to kebab-case. The error component is imported as AppError to avoid shadowing the global Error constructor, which is the recommended pattern.

Note: apps/activitypub/src/views/inbox/inbox.tsx should follow the same aliasing pattern for consistency.

apps/activitypub/src/routes.tsx (2)

1-14: Import paths correctly updated and shadowing issue resolved.

The kebab-case refactoring is correct, and the component previously named Error has been appropriately renamed to AppError, which resolves the global Error constructor shadowing issue flagged in the previous review. All import paths are now consistent with the kebab-case convention.


30-30: Error component usage correctly updated.

Both errorElement instances have been updated to use <AppError /> consistently with the renamed import. The error handling structure remains intact.

Also applies to: 150-150

@mike182uk mike182uk force-pushed the mike-ber-3044-use-kebab-case-naming-convention-for-ap-files branch from ede5d6d to f8d6fa5 Compare December 10, 2025 10:46
@mike182uk mike182uk force-pushed the mike-ber-3044-use-kebab-case-naming-convention-for-ap-files branch from f8d6fa5 to 0d42fd4 Compare December 10, 2025 10:49
Copy link
Contributor

@ibalosh ibalosh left a comment

Choose a reason for hiding this comment

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

Hey @mike182uk

it looks good, only thing I would add is I don't see linting rule to enforce it

@mike182uk
Copy link
Member Author

Ah good catch @ibalosh I've added that in 314cb5a 👍

@ibalosh
Copy link
Contributor

ibalosh commented Dec 10, 2025

thanks! looks great!

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.

2 participants

Comments