Skip to content

refactor(packages): consolidate tooling/codegen and clients into packages/client#60

Merged
tataihono merged 7 commits intomainfrom
refactor/59-consolidate-client-packages
Feb 18, 2026
Merged

refactor(packages): consolidate tooling/codegen and clients into packages/client#60
tataihono merged 7 commits intomainfrom
refactor/59-consolidate-client-packages

Conversation

@tataihono
Copy link
Copy Markdown
Contributor

@tataihono tataihono commented Feb 18, 2026

Summary

Consolidate packages/tooling/codegen and packages/clients into single packages/client with codegen tools colocated. GraphQL types generated from Strapi schema; web consumes @forge/client.

Resolves #59

Contracts Changed

  • yes
  • no

Regeneration Required

  • yes
  • no

Validation

  • Contracts validated
  • Generated code verified (no manual edits)
  • Tests and build passed
  • Terraform plan reviewed (if infra change)

Summary by CodeRabbit

  • Technical Infrastructure
    • Migrated data fetching to GraphQL-based architecture across web and mobile applications.
    • Updated project dependencies and configuration to support new GraphQL query infrastructure.
    • Refactored content retrieval mechanisms to use GraphQL instead of previous client libraries.

- Create packages/client with GraphQL codegen + generated types
- Remove packages/tooling/codegen, packages/clients
- Web uses @forge/client; root codegen invokes packages/client
- Update AGENTS.md, README, CODEOWNERS, mobile adapter comments

Resolves #59

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 18, 2026

Warning

Rate limit exceeded

@tataihono has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 9 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

The PR consolidates generated client artifacts and codegen tooling from packages/clients and packages/tooling/codegen into a new packages/graphql package. All documentation and configuration references are updated accordingly, dependencies are modified to use Apollo Client and the new package, and the content fetching implementation is refactored to use GraphQL queries.

Changes

Cohort / File(s) Summary
Configuration & Tooling
eslint.config.mjs, .prettierignore, CONTRIBUTING.md, SECURITY.md
Updated ignore patterns and scope definitions from packages/clients to packages/graphql (and packages/graphql/src/graphql-env.d.ts for Prettier/ESLint).
Documentation & Ownership
AGENTS.md, CODEOWNERS, packages/README.md
Replaced references to packages/clients with packages/graphql, updated CODEOWNERS team assignments, removed codegen tooling documentation.
Root-Level Scripts
package.json
Changed codegen and check:generated scripts to use @forge/graphql filter and run only generate (previously used @forge/tooling-codegen with generate && verify).
Package Consolidation — Deletions
packages/clients/{ts-web,ts-node}/*, packages/tooling/codegen/*
Removed entire packages/clients package (ts-web, ts-node, swift-ios, kotlin-android stubs), codegen scripts, and verification logic from packages/tooling/codegen.
Package Consolidation — New GraphQL Package
packages/graphql/{AGENTS.md,package.json,tsconfig.json,src/graphql-env.d.ts,src/graphql.ts,src/index.ts}
Introduced new packages/graphql package with gql.tada setup, TypeScript configuration, comprehensive GraphQL introspection typings (graphql-env.d.ts with 150+ type definitions), and re-exports for FragmentOf, ResultOf, VariablesOf, readFragment.
Web App Integration
apps/web/package.json, apps/web/README.md, apps/web/src/lib/client.ts, apps/web/src/lib/content.ts
Replaced @forge/client-ts-web dependency with @apollo/client, @forge/graphql, and graphql; created Apollo client instance in new client.ts; refactored readPublishedContent to use GraphQL query via Apollo instead of direct library call; updated boundary imports.
Mobile App Documentation
mobile/android/README.md, mobile/android/app/src/main/kotlin/.../ContentRepository.kt, mobile/ios/README.md, mobile/ios/Sources/.../ContentRepository.swift
Updated READMEs and code comments to reference packages/graphql and ContentClient-based implementation instead of generated client packages.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

chore, tooling

🚥 Pre-merge checks | ✅ 1 | ❌ 4

❌ Failed checks (4 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title references 'packages/client' but the actual changes create 'packages/graphql', not 'packages/client', creating a misleading mismatch. Update the PR title to 'refactor(packages): consolidate tooling/codegen and clients into packages/graphql' to accurately reflect the created package name.
Linked Issues check ⚠️ Warning The PR creates packages/graphql instead of packages/client as required by issue #59, and removes packages/clients but also deletes the codegen tooling rather than consolidating it into the client package. Clarify whether the intent is to use packages/graphql or packages/client, and ensure codegen tooling and generated types are properly consolidated in the chosen package location.
Out of Scope Changes check ⚠️ Warning Multiple out-of-scope changes detected: replacement of graphql-codegen with gql.tada, addition of Apollo Client to web dependencies, and migration from generated client stubs (ContentItem) to GraphQL types via gql.tada are beyond the consolidation scope. Separate tooling migration (codegen tool replacement, Apollo integration) from the package consolidation refactor into distinct PRs or clarify these changes as part of the acceptance criteria.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/59-consolidate-client-packages

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.

…phql

- packages/client → packages/graphql
- gql.tada for typed GraphQL (no codegen step)
- Remove ContentItem, verify script
- Add Apollo Client to web
- Add client.ts, update content.ts

Co-authored-by: Cursor <cursoragent@cursor.com>
tataihono and others added 2 commits February 18, 2026 16:19
- Use relative import for client (no @/ alias)
- Early return when NEXT_PUBLIC_GRAPHQL_URL unset
- Fallback URI for Apollo HttpLink

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown

@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: 11

🧹 Nitpick comments (2)
packages/graphql/package.json (1)

14-16: Missing graphql peer/dev dependency.

gql.tada requires graphql as a peer dependency. It is absent from this package's manifest. While apps/web has graphql: ^16.12.0, consumers of @forge/graphql outside that context (e.g., scripts, other packages) would receive an unsatisfied peer warning or runtime failure.

📦 Suggested fix
   "dependencies": {
-    "gql.tada": "^1.9.0"
+    "gql.tada": "^1.8.13",
+    "graphql": "^16.12.0"
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/graphql/package.json` around lines 14 - 16, The package manifest for
packages/graphql is missing the required graphql dependency for the installed
"gql.tada" package; update packages/graphql's package.json to declare "graphql"
(e.g., "^16.12.0") as a peerDependencies entry and also add it to
devDependencies for local builds/tests, so consumers don't get peer warnings or
runtime failures when using gql.tada.
apps/web/src/lib/client.ts (1)

1-3: Consolidate imports from the same module.

Suggested consolidation
-import { InMemoryCache } from "@apollo/client"
-import { HttpLink } from "@apollo/client"
-import { ApolloClient } from "@apollo/client"
+import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/lib/client.ts` around lines 1 - 3, Consolidate the three
separate imports from "@apollo/client" into a single import statement to reduce
redundancy: replace the individual imports of InMemoryCache, HttpLink, and
ApolloClient with one combined import that includes ApolloClient, HttpLink, and
InMemoryCache; update any references in this module (client.ts) to use those
imported symbols unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AGENTS.md`:
- Line 48: Update the guidance line that currently refers to "src/generated/*"
so it matches the actual generated file location specified by the TypeScript
setting: refer to the artifact at src/graphql-env.d.ts (as set by
tadaOutputLocation in packages/graphql/tsconfig.json) or use the correct glob
(e.g., src/graphql-env.d.ts) so the rule actually prevents editing the generated
file under packages/graphql/src/graphql-env.d.ts.

In `@apps/web/src/lib/client.ts`:
- Line 6: The HttpLink instantiation uses process.env.NEXT_PUBLIC_GRAPHQL_URL
directly (new HttpLink({ uri: process.env.NEXT_PUBLIC_GRAPHQL_URL })) which can
be undefined; add a guard that validates NEXT_PUBLIC_GRAPHQL_URL before
constructing the HttpLink and throws or logs a clear error if missing. Update
the client initialization to read the env var into a local variable, validate
it's a non-empty string, and only pass it into new HttpLink({ uri }) when valid
(otherwise throw a descriptive error or fallback to an explicit default),
referencing the HttpLink creation site and the NEXT_PUBLIC_GRAPHQL_URL variable.
- Around line 5-8: The module creates a singleton ApolloClient (const client =
new ApolloClient({...}) using HttpLink and InMemoryCache) which can leak cache
across SSR requests; replace this pattern with the Next.js-specific integration
from `@apollo/client-integration-nextjs` by moving client creation into the
registerApolloClient/getClient flow (or use ApolloNextAppProvider + makeClient)
so each request gets a request-scoped client; update this file to export the
register/get functions (instead of a module-level `client`) and wire the
HttpLink/InMemoryCache setup into the provider-factory recommended by the
package to ensure proper SSR cache isolation and hydration.

In `@apps/web/src/lib/content.ts`:
- Around line 13-17: The GraphQL call using client.query with GET_EXPERIENCE
(variables { slug, locale }) lacks error handling: wrap the client.query call in
a try/catch, check the returned result for response.errors and handle or rethrow
a descriptive error (or log via your logger) instead of returning
data?.experience blindly; ensure the function throws or returns a clear failure
when client.query throws or when result.errors is non-empty so callers don't
receive undefined silently.
- Around line 4-10: The GraphQL query GET_EXPERIENCE is invalid: change the root
field from the singular experience (which doesn't accept filters) to the plural
experiences with filters, and replace the nonexistent id selection with
documentId; update any consumer logic that expected a single object (e.g., code
using GET_EXPERIENCE result) to read the first item from the experiences array
(e.g., experiences[0]?.documentId) or handle no-results accordingly so callers
use documentId instead of id.

In `@mobile/android/app/src/main/kotlin/com/forge/mobile/ContentRepository.kt`:
- Line 19: The file currently tells developers to implement ContentClient
manually; change it to instruct consuming the generated Kotlin client artifact
instead: replace the in-file comment in ContentRepository.kt that references
"implement ContentClient" to indicate importing/using the generated GraphQL
Kotlin client (ContentClient) artifact and wiring it into ContentRepository
constructors or factory methods; if this represents an intentional policy change
away from generated clients, update mobile/android/AGENTS.md to reflect the new
guidance and remove the conflicting rule in mobile/android/README.md, otherwise
revert the comment to follow the "Integrate via generated Kotlin client
artifacts" guideline.

In `@mobile/android/README.md`:
- Line 5: The README change directs Android devs to implement ContentClient
against packages/graphql types, which conflicts with the existing
mobile/AGENTS.md, mobile/android/AGENTS.md, and mobile/ios/AGENTS.md guidance to
consume generated clients; update those AGENTS.md files (and any agent
documentation) in this PR to document the new ContentClient adapter approach
(including how to implement ContentClient, expected Kotlin/Swift types, and
where packages/graphql types are used) or revert the README and repository
changes so they continue to instruct use of generated Kotlin client artifacts;
ensure references to ContentRepository.kt and ContentRepository.swift and the
symbol ContentClient are aligned with the chosen approach so documentation and
code no longer contradict each other.

In `@mobile/ios/README.md`:
- Line 5: The iOS integration lost its generated Swift client (swift-ios) and
now points at the TypeScript-only packages/graphql, leaving mobile/** unable to
consume a Swift client; restore a consumable iOS client by either re-adding a
generated Swift client (e.g., run Apollo iOS codegen against
apps/cms/schema.graphql and place the output under packages/graphql or a new
packages/clients/swift-ios) or explicitly document in mobile/ios/README.md that
iOS integration is deferred and create a follow-up issue tracking generation of
the Swift client; ensure the chosen fix satisfies the "Consume generated clients
only" rule and reference the packages/graphql and swift-ios identifiers when
updating code or docs.

In `@mobile/ios/Sources/ForgeMobile/ContentRepository.swift`:
- Line 14: The inline comment in ContentRepository.swift currently instructs
implementors to "implement ContentClient (e.g. from packages/graphql GraphQL)"
which conflicts with the project guideline to "Integrate via generated Swift
client artifacts"; update the comment to require consuming the generated Swift
client artifact instead of a manual adapter and reference the generated client
types (ContentClient generated client) so implementors know what to import and
use, and if you intend to change the guideline instead, update
mobile/ios/AGENTS.md (and the similar mobile/android/README.md) to reflect the
new policy so docs and code comments remain consistent.

In `@package.json`:
- Around line 11-12: The two npm scripts "codegen" and "check:generated" are
identical which removes drift detection; restore a verify step by changing
"check:generated" to run a verification flow instead of regenerating in-place:
have it run the generator into a temporary location (or use the tool's built-in
check, e.g., "gql-tada check" if available) and then diff the generated output
against committed files (for example run a diff and fail CI with git diff
--exit-code) so edits to src/graphql-env.d.ts are detected; update the
package.json scripts so "codegen" still generates in-place (pnpm --filter
`@forge/graphql` run generate) while "check:generated" runs the temp/generate+diff
or tool-specific check to enforce no drift.

In `@packages/graphql/AGENTS.md`:
- Around line 8-9: Update the AGENTS.md rules: replace the incorrect prohibited
edit path `src/generated/*` with the actual codegen output
`src/graphql-env.d.ts`, and clarify the command by noting that `pnpm run
codegen` is a workspace/root script while the package-local script is `pnpm run
generate` (or run `pnpm --filter packages/graphql run generate` from the repo
root); update the sentence to state which working directory or exact command to
run to regenerate (e.g., run `pnpm run generate` inside the package or the
workspace-filtered command from root).

---

Nitpick comments:
In `@apps/web/src/lib/client.ts`:
- Around line 1-3: Consolidate the three separate imports from "@apollo/client"
into a single import statement to reduce redundancy: replace the individual
imports of InMemoryCache, HttpLink, and ApolloClient with one combined import
that includes ApolloClient, HttpLink, and InMemoryCache; update any references
in this module (client.ts) to use those imported symbols unchanged.

In `@packages/graphql/package.json`:
- Around line 14-16: The package manifest for packages/graphql is missing the
required graphql dependency for the installed "gql.tada" package; update
packages/graphql's package.json to declare "graphql" (e.g., "^16.12.0") as a
peerDependencies entry and also add it to devDependencies for local
builds/tests, so consumers don't get peer warnings or runtime failures when
using gql.tada.

Comment thread AGENTS.md Outdated
Comment on lines +5 to +8
const client = new ApolloClient({
link: new HttpLink({ uri: process.env.NEXT_PUBLIC_GRAPHQL_URL }),
cache: new InMemoryCache(),
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n apps/web/src/lib/client.ts

Repository: JesusFilm/forge

Length of output: 475


🏁 Script executed:

find . -name "package.json" -path "*/apps/web/*" -type f -exec head -50 {} + | grep -A 20 "@apollo/client"

Repository: JesusFilm/forge

Length of output: 482


🌐 Web query:

Apollo Client Next.js App Router SSR singleton cache best practices 2025

💡 Result:

Best practices (2025+) for Apollo Client cache/singletons with Next.js App Router + SSR

  1. Use the official Next.js integration package (stable)

    • Apollo’s former @apollo/experimental-nextjs-app-support was released as the stable @apollo/client-integration-nextjs (April 7, 2025). Prefer the stable package for App Router SSR patterns and cache hydration. [1]
  2. Never use a “global singleton ApolloClient” on the server

    • In App Router SSR/RSC, a module-level singleton can leak cache data across users/requests.
    • Use Apollo’s registerApolloClient/getClient() pattern so the client (and its InMemoryCache) is scoped to the current request. [2]
  3. For Client Components + SSR hydration, create the client via a factory (makeClient)

    • Wrap your app (typically in app/layout.tsx) with ApolloNextAppProvider and pass a makeClient() that constructs a new NextSSRApolloClient with NextSSRInMemoryCache (and SSR links like SSRMultipartLink on the server). This enables SSR rendering + correct cache hydration on the client. [3]
  4. Keep “singleton” behavior only in the browser (optional)

    • If you want persistence across client-side navigations, you can rely on the provider’s client instance in the browser, but still ensure server-side always stays per-request (no shared module cache).
  5. Be explicit about Next.js rendering/caching mode when needed

    • Next.js will choose static vs on-demand rendering based on data requirements; ensure your route’s rendering mode matches whether your GraphQL data must be per-request/user-specific. (If it must be per-request, avoid patterns that cause static optimization.) [4]

Sources: Apollo stable package announcement [1], Apollo App Router request-scoped registerApolloClient guidance [2], Apollo ApolloNextAppProvider/makeClient SSR setup example [3], Next.js rendering/static optimization behavior [4].


🏁 Script executed:

rg "from.*lib/client|import.*client" apps/web/src --type ts --type tsx -A 2

Repository: JesusFilm/forge

Length of output: 86


🏁 Script executed:

find apps/web/src -name "layout.tsx" -o -name "app.tsx" -o -name "providers.tsx" | head -5 | xargs cat -n

Repository: JesusFilm/forge

Length of output: 346


🏁 Script executed:

rg "from.*lib/client|import.*client" apps/web/src -A 2 -t ts -t js

Repository: JesusFilm/forge

Length of output: 563


🏁 Script executed:

fd -e tsx -e ts apps/web/src | xargs rg "client\b" | grep -E "import|from" | head -20

Repository: JesusFilm/forge

Length of output: 786


🏁 Script executed:

find apps/web/src -type f \( -name "*provider*" -o -name "*apollo*" \) | cat

Repository: JesusFilm/forge

Length of output: 41


🏁 Script executed:

cat -n apps/web/src/lib/content.ts

Repository: JesusFilm/forge

Length of output: 725


🏁 Script executed:

rg "readPublishedContent" apps/web/src -B 2 -A 2

Repository: JesusFilm/forge

Length of output: 698


Migrate to Next.js-specific Apollo integration for server-side client creation.

This module-level singleton ApolloClient pattern is not recommended for Next.js App Router SSR. Apollo's best practice (as of April 2025) is to use the stable @apollo/client-integration-nextjs package with registerApolloClient/getClient() to create request-scoped clients on the server, preventing potential cache sharing across requests.

While the current queries use variable-based cache segmentation (reducing immediate data leakage risk), adopting the official Next.js integration ensures proper SSR cache handling and aligns with current Apollo guidance. Consider refactoring to use registerApolloClient in a server utility or switching to the ApolloNextAppProvider + makeClient pattern for proper SSR + client hydration.

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

In `@apps/web/src/lib/client.ts` around lines 5 - 8, The module creates a
singleton ApolloClient (const client = new ApolloClient({...}) using HttpLink
and InMemoryCache) which can leak cache across SSR requests; replace this
pattern with the Next.js-specific integration from
`@apollo/client-integration-nextjs` by moving client creation into the
registerApolloClient/getClient flow (or use ApolloNextAppProvider + makeClient)
so each request gets a request-scoped client; update this file to export the
register/get functions (instead of a module-level `client`) and wire the
HttpLink/InMemoryCache setup into the provider-factory recommended by the
package to ensure proper SSR cache isolation and hydration.

Comment thread apps/web/src/lib/client.ts Outdated
Comment thread apps/web/src/lib/content.ts
Comment thread apps/web/src/lib/content.ts Outdated
Comment on lines +13 to +17
const { data } = await client.query({
query: GET_EXPERIENCE,
variables: { slug, locale },
})
return data?.experience
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

No error handling for GraphQL failures.

client.query can throw on network errors or return errors in the GraphQL response. The current code only destructures data and ignores potential errors. A failed query will either throw (unhandled) or return undefined silently.

Consider at minimum logging or propagating GraphQL errors:

Basic error handling
- const { data } = await client.query({
+ const { data, errors } = await client.query({
    query: GET_EXPERIENCE,
    variables: { slug, locale },
  })
+ if (errors?.length) {
+   throw new Error(`GraphQL errors: ${errors.map(e => e.message).join(", ")}`)
+ }
  return data?.experience
📝 Committable suggestion

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

Suggested change
const { data } = await client.query({
query: GET_EXPERIENCE,
variables: { slug, locale },
})
return data?.experience
const { data, errors } = await client.query({
query: GET_EXPERIENCE,
variables: { slug, locale },
})
if (errors?.length) {
throw new Error(`GraphQL errors: ${errors.map(e => e.message).join(", ")}`)
}
return data?.experience
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/lib/content.ts` around lines 13 - 17, The GraphQL call using
client.query with GET_EXPERIENCE (variables { slug, locale }) lacks error
handling: wrap the client.query call in a try/catch, check the returned result
for response.errors and handle or rethrow a descriptive error (or log via your
logger) instead of returning data?.experience blindly; ensure the function
throws or returns a clear failure when client.query throws or when result.errors
is non-empty so callers don't receive undefined silently.

Comment thread mobile/android/README.md
Native Kotlin + Jetpack Compose app. Outside Turborepo graph.

Consumes only generated contracts/clients from `packages/clients/kotlin-android`.
Integrates via ContentClient; implement using `packages/graphql` GraphQL types.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check the current state of AGENTS.md files in mobile directories
fd "AGENTS.md" mobile/ --exec bash -c 'echo "=== {} ===" && cat {}' \;

Repository: JesusFilm/forge

Length of output: 634


AGENTS.md files must be updated in this PR to reflect the ContentClient implementation approach.

The coding guidelines require mobile apps to "Consume generated clients only" (mobile/AGENTS.md) and "Integrate via generated Kotlin client artifacts" (mobile/android/AGENTS.md). The README.md change at line 5 directs Android developers to hand-implement ContentClient against packages/graphql types instead, directly contradicting these guidelines.

Since mobile/AGENTS.md, mobile/android/AGENTS.md, and mobile/ios/AGENTS.md have not been updated in this PR, developers will encounter conflicting instructions. If the removal of packages/clients/kotlin-android is intentional, these AGENTS.md files must be updated in the same PR to reflect the new ContentClient adapter pattern and clarify the shift away from pre-generated client consumption.

The same conflict applies to related changes in mobile/android/app/src/main/kotlin/com/forge/mobile/ContentRepository.kt (Line 19) and mobile/ios/Sources/ForgeMobile/ContentRepository.swift (Line 14).

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

In `@mobile/android/README.md` at line 5, The README change directs Android devs
to implement ContentClient against packages/graphql types, which conflicts with
the existing mobile/AGENTS.md, mobile/android/AGENTS.md, and
mobile/ios/AGENTS.md guidance to consume generated clients; update those
AGENTS.md files (and any agent documentation) in this PR to document the new
ContentClient adapter approach (including how to implement ContentClient,
expected Kotlin/Swift types, and where packages/graphql types are used) or
revert the README and repository changes so they continue to instruct use of
generated Kotlin client artifacts; ensure references to ContentRepository.kt and
ContentRepository.swift and the symbol ContentClient are aligned with the chosen
approach so documentation and code no longer contradict each other.

Comment thread mobile/ios/README.md
Native SwiftUI app. Outside Turborepo graph.

Consumes only generated contracts/clients from `packages/clients/swift-ios`.
Integrates via ContentClient; implement using `packages/graphql` GraphQL types.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

iOS integration path is broken: the Swift client was removed with no replacement.

The PR removes the generated Swift client (swift-ios) from packages/clients and redirects iOS to packages/graphql, but packages/graphql is a TypeScript package and cannot be consumed by a Swift app. The iOS app now has no generated client to integrate against.

Either:

  • Re-add a generated Swift client under packages/graphql (e.g., via Apollo iOS codegen against apps/cms/schema.graphql), or
  • Explicitly document that the iOS integration is deferred and create a follow-up issue.

As per coding guidelines, mobile/** must "Consume generated clients only" — the current state leaves that requirement unmet.

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

In `@mobile/ios/README.md` at line 5, The iOS integration lost its generated Swift
client (swift-ios) and now points at the TypeScript-only packages/graphql,
leaving mobile/** unable to consume a Swift client; restore a consumable iOS
client by either re-adding a generated Swift client (e.g., run Apollo iOS
codegen against apps/cms/schema.graphql and place the output under
packages/graphql or a new packages/clients/swift-ios) or explicitly document in
mobile/ios/README.md that iOS integration is deferred and create a follow-up
issue tracking generation of the Swift client; ensure the chosen fix satisfies
the "Consume generated clients only" rule and reference the packages/graphql and
swift-ios identifiers when updating code or docs.

}

// Adapter target: generated client in packages/clients/swift-ios
// Adapter target: implement ContentClient (e.g. from packages/graphql GraphQL)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same guideline conflict as mobile/android/README.md.

This comment now directs implementors to provide a manual ContentClient adapter rather than consuming a generated Swift artifact. Per coding guidelines, mobile/ios/**/*.swift: "Integrate via generated Swift client artifacts." If the policy is changing, mobile/ios/AGENTS.md needs a corresponding update.

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

In `@mobile/ios/Sources/ForgeMobile/ContentRepository.swift` at line 14, The
inline comment in ContentRepository.swift currently instructs implementors to
"implement ContentClient (e.g. from packages/graphql GraphQL)" which conflicts
with the project guideline to "Integrate via generated Swift client artifacts";
update the comment to require consuming the generated Swift client artifact
instead of a manual adapter and reference the generated client types
(ContentClient generated client) so implementors know what to import and use,
and if you intend to change the guideline instead, update mobile/ios/AGENTS.md
(and the similar mobile/android/README.md) to reflect the new policy so docs and
code comments remain consistent.

Comment thread package.json Outdated
Comment thread packages/graphql/AGENTS.md Outdated
Comment on lines +8 to +9
- Do not hand-edit `src/generated/*`.
- Regenerate when schema changes: `pnpm run codegen` (runs `gql-tada generate output`).
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Two minor doc issues in the rules.

  1. Wrong path (Line 8): The prohibited hand-edit path src/generated/* does not exist. Per tsconfig.json, gql.tada writes its output to src/graphql-env.d.ts. Update to match.

  2. Ambiguous command (Line 9): pnpm run codegen resolves to the root workspace script. Running the same command from inside packages/graphql would fail because the package-level script is named generate. Clarify the working directory.

📝 Suggested fix
-  - Do not hand-edit `src/generated/*`.
-  - Regenerate when schema changes: `pnpm run codegen` (runs `gql-tada generate output`).
+  - Do not hand-edit `src/graphql-env.d.ts`.
+  - Regenerate when schema changes: `pnpm run codegen` from repo root (or `pnpm run generate` from within this package).
📝 Committable suggestion

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

Suggested change
- Do not hand-edit `src/generated/*`.
- Regenerate when schema changes: `pnpm run codegen` (runs `gql-tada generate output`).
- Do not hand-edit `src/graphql-env.d.ts`.
- Regenerate when schema changes: `pnpm run codegen` from repo root (or `pnpm run generate` from within this package).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/graphql/AGENTS.md` around lines 8 - 9, Update the AGENTS.md rules:
replace the incorrect prohibited edit path `src/generated/*` with the actual
codegen output `src/graphql-env.d.ts`, and clarify the command by noting that
`pnpm run codegen` is a workspace/root script while the package-local script is
`pnpm run generate` (or run `pnpm --filter packages/graphql run generate` from
the repo root); update the sentence to state which working directory or exact
command to run to regenerate (e.g., run `pnpm run generate` inside the package
or the workspace-filtered command from root).

tataihono and others added 3 commits February 18, 2026 16:24
- format:check step in CI
- lint-staged + pre-commit hook for staged files
- Ignore schema.graphql and .strapi in prettier

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@tataihono
Copy link
Copy Markdown
Contributor Author

Review feedback addressed (cbd1fbc, eeac318)

Fixed:

  • content.ts: Switched to experiences query with filters: { slug: { eq: $slug } } and locale param; use documentId instead of id; added result.error check
  • client.ts: Consolidated Apollo imports into single line
  • AGENTS.md (root + packages/graphql): Updated path from src/generated/* to src/graphql-env.d.ts
  • check:generated: Added git diff --exit-code packages/graphql/src/graphql-env.d.ts for drift detection
  • packages/graphql: Added graphql dependency
  • mobile AGENTS: Updated to "ContentClient adapter; Swift/Kotlin client generation deferred"

Not changed:

  • Apollo Next.js integration (@apollo/client-integration-nextjs): Deferred to follow-up; current singleton works for static/SSR for now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(packages): consolidate tooling/codegen and clients into packages/client

1 participant