Skip to content

Claude Code Setup#1651

Draft
Goader wants to merge 1 commit intomainfrom
claude-setup
Draft

Claude Code Setup#1651
Goader wants to merge 1 commit intomainfrom
claude-setup

Conversation

@Goader
Copy link
Contributor

@Goader Goader commented Feb 18, 2026

Claude Code Setup

Sharing my Claude Code setup. It is mostly automatically generated by Claude itself, but with my instructions on what should be covered and quickly verified. Note that some statements may be incorrect; the main purpose is to reduce token usage so that Claude can infer the patterns we use from a simple description rather than manually reading and analyzing the entire codebase.

Besides that, I'm using:

  • claude-code-setup - general helpers to set up everything
  • claude-md-management - updating, improving CLAUDE.md
  • code-review - self-explanatory (haven't tried it yet)
  • context7 - MCP for documentation
  • typescript-lsp - language server

All of those are official plugins. Haven't explored other plugins yet, and haven't set up any skills for manual testing and whatnot.

Not included, but I'm also using a few hooks, like running a linter after Claude edits the code.

@Goader Goader self-assigned this Feb 18, 2026
Copilot AI review requested due to automatic review settings February 18, 2026 16:37
@vercel
Copy link
Contributor

vercel bot commented Feb 18, 2026

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

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Feb 18, 2026 4:37pm
ensnode.io Ready Ready Preview, Comment Feb 18, 2026 4:37pm
ensrainbow.io Ready Ready Preview, Comment Feb 18, 2026 4:37pm

@changeset-bot
Copy link

changeset-bot bot commented Feb 18, 2026

⚠️ No Changeset found

Latest commit: e9656d7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Feb 18, 2026

📝 Walkthrough

Walkthrough

Introduces comprehensive developer guidance documentation to the repository, including developer onboarding (CLAUDE.md), API patterns, ENS referrals rules, ponder indexing guidelines, and SDK development standards. Also removes CLAUDE.md from the gitignore file to track the documentation.

Changes

Cohort / File(s) Summary
Developer Guidance
.claude/CLAUDE.md
Comprehensive developer guide covering project overview, technology stack, repository structure, development workflows, architecture patterns, coding conventions, environment setup, and testing approach.
API & Architecture Patterns
.claude/rules/api-patterns.md, .claude/rules/sdk-development.md, .claude/rules/ponder-indexing.md
Pattern documentation for API design (SWR cache, Hono factory, response codes), SDK development (serialization, builder pattern, module structure), and ponder indexing plugin system configuration.
Domain-Specific Rules
.claude/rules/ens-referrals.md
Documentation for ENS Referrals rules, covering v0/v1 distinctions, API endpoints, and domain type hierarchy.
Git Configuration
.gitignore
Removed ignore entries for CLAUDE.md to enable file tracking.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A burrow of guidance, so clear and so bright,
Developer patterns emerging from night,
SDK secrets and API design,
All laid out for humans and code to align,
With whiskers held high, I declare this refined!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description lacks the required Lite PR template structure, missing key sections like Summary, Why, Testing, and the Pre-Review Checklist specified in the repository template. Restructure the description to follow the Lite PR template with clear Summary, Why, Testing, and Pre-Review Checklist sections as defined in the repository guidelines.
Title check ❓ Inconclusive The title 'Claude Code Setup' is vague and generic, using non-descriptive terms that don't convey meaningful information about what specific changes are being introduced in the changeset. Consider a more specific title like 'Add Claude development setup documentation and guidelines' to clearly convey that this introduces documentation files rather than generic setup changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 claude-setup

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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive Claude Code setup documentation to guide AI-assisted development. The documentation includes general codebase overview, development commands, architecture patterns, and path-specific rules for different parts of the monorepo. The setup is primarily auto-generated by Claude itself with manual verification, designed to reduce token usage by providing concise pattern descriptions rather than requiring the AI to analyze the entire codebase.

Changes:

  • Added .claude/ directory with four rule files covering SDK development, Ponder indexing, ENS referrals, and API patterns
  • Added root CLAUDE.md file with comprehensive repository overview, technology stack, development commands, and coding conventions
  • Removed CLAUDE.md from .gitignore to commit the documentation

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.gitignore Removed CLAUDE.md ignore entry to allow committing AI assistant documentation
.claude/rules/sdk-development.md Documents serialization patterns, internal module pattern, builder pattern, and SDK package structure
.claude/rules/ponder-indexing.md Describes plugin architecture, directory layout, and key patterns for ENSIndexer
.claude/rules/ens-referrals.md Details v0/v1 stability rules and domain types hierarchy for referral system
.claude/rules/api-patterns.md Covers SWR cache, Hono factory, response codes, and API endpoint patterns
.claude/CLAUDE.md Comprehensive 511-line overview covering repository structure, tech stack, commands, architecture, conventions, and workflows

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/CLAUDE.md:
- Line 211: The README entry incorrectly lists the package scope as
"@ensnode/ens-referrals"; update that string to the correct published package
scope "@namehash/ens-referrals" wherever it appears (e.g., the list item
currently reading "**@ensnode/ens-referrals** - ENS referral program logic.") so
imports generated from this doc use the correct package name.
- Around line 492-493: Tips 2 and 3 are duplicate (both instruct to use
`satisfies`); remove or merge them into a single tip that mentions "Follow the
builder pattern when creating domain objects — use `satisfies` for type safety
and to preserve type inference" and then renumber all subsequent tips
accordingly; update the content where `satisfies` is referenced to point to the
merged tip.
- Line 195: Update the documentation entry for "ensindexer" to point to the
actual handler implementation directory: change the reference from
`apps/ensindexer/ponder/src/` to `apps/ensindexer/src/plugins/`; note that
`apps/ensindexer/ponder/src/register-handlers.ts` only orchestrates imports
while the real event handlers live under the plugin folders (see
`ponder-indexing.md` for the correct pattern), so ensure the single-line
description for ensindexer names `apps/ensindexer/src/plugins/` as the handler
location.

In @.claude/rules/api-patterns.md:
- Around line 114-143: Update the markdown fenced code blocks in this section to
explicitly declare the TypeScript language (change every ``` to ```typescript)
so the linter MD040 passes; specifically ensure the block surrounding the
example that uses describeRoute, factory.createApp, validate, and
paginationQuerySchema is opened with ```typescript and check adjacent fenced
blocks in the same section for missing language specifiers and fix them as well.

In @.claude/rules/ens-referrals.md:
- Around line 42-49: Add a language tag to the fenced code block containing the
domain type hierarchy (the block that starts with "ReferrerMetrics" and lists
ScoredReferrerMetrics, RankedReferrerMetrics, AwardedReferrerMetrics, and
UnrankedReferrerMetrics) so the linter MD040 is satisfied; change the opening
fence from ``` to ```text and keep the closing fence as ``` so the diagram
remains unchanged but is explicitly marked as plain text.
- Around line 6-9: The glob patterns "referr*" already match any path beginning
with "referr", so the explicit "referral*" entries are redundant; remove the
duplicate patterns "apps/ensapi/src/cache/referral*" and
"apps/ensapi/src/middleware/referral*" from the rules so only the broader
"apps/ensapi/src/cache/referr*" and "apps/ensapi/src/middleware/referr*" remain
(update the list in .claude/rules/ens-referrals.md accordingly).

In @.claude/rules/ponder-indexing.md:
- Line 72: Update the incorrect example path that uses `src/` to use `handlers/`
instead: change any occurrences like
`apps/ensindexer/src/plugins/subgraph/plugins/subgraph/src/` to
`apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/`, and similarly
update the subgraph-sharing plugin examples to
`apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/` (and
lineanames/threedns variants); ensure the docs consistently reference the
`handlers/` directory for plugin handler registration.

In @.claude/rules/sdk-development.md:
- Around line 37-46: The deserialize example for deserializeReferrerMetrics is
misleading: replace the simple "deserialize → safeParse" guidance with explicit
instruction to use z.preprocess (not z.transform) so preprocessing runs before
validation; update the documentation and the schema construction in the
deserialize flow to use z.preprocess(buildUnvalidated, finalSchema) and ensure
the preprocess function returns unknown, then safeParse/parse against the final
schema (reference symbols: deserializeReferrerMetrics, buildUnvalidated,
finalSchema, z.preprocess).


### Apps Structure

- **ensindexer** - Ponder-based blockchain indexer. Event handlers in `apps/ensindexer/ponder/src/`.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, check if the files mentioned exist and view the specific line
echo "=== Checking CLAUDE.md line 195 ==="
if [ -f ".claude/CLAUDE.md" ]; then
  sed -n '190,200p' ".claude/CLAUDE.md"
else
  echo "File not found"
fi

echo ""
echo "=== Looking for ponder-indexing.md ==="
find . -name "ponder-indexing.md" -type f 2>/dev/null

Repository: namehash/ensnode

Length of output: 817


🏁 Script executed:

#!/bin/bash
# Verify which paths contain actual event handler implementations
echo "=== Files in apps/ensindexer/ponder/src/ ==="
fd --type f "\.ts$" apps/ensindexer/ponder/src/ 2>/dev/null | head -20

echo ""
echo "=== Files in apps/ensindexer/src/plugins/ ==="
fd --type f "\.ts$" apps/ensindexer/src/plugins/ 2>/dev/null | head -20

Repository: namehash/ensnode

Length of output: 1667


🏁 Script executed:

#!/bin/bash
# Check the overall structure of apps/ensindexer
echo "=== Directory structure of apps/ensindexer ==="
tree -L 3 apps/ensindexer/ 2>/dev/null || find apps/ensindexer/ -maxdepth 3 -type d | head -30

Repository: namehash/ensnode

Length of output: 2186


🏁 Script executed:

#!/bin/bash
# Now let's examine ponder-indexing.md to see the conflicting information
echo "=== Content of ponder-indexing.md ==="
cat "./.claude/rules/ponder-indexing.md"

Repository: namehash/ensnode

Length of output: 2777


🏁 Script executed:

#!/bin/bash
# Let's also check what's inside the register-handlers.ts to understand the relationship
echo "=== Content of register-handlers.ts ==="
cat "apps/ensindexer/ponder/src/register-handlers.ts"

Repository: namehash/ensnode

Length of output: 2292


Correct handler location in documentation.

Line 195 directs event handlers to apps/ensindexer/ponder/src/, but actual handler implementations are in apps/ensindexer/src/plugins/. The ponder/src/ directory contains only orchestration (like register-handlers.ts which imports handlers from plugins). The ponder-indexing.md documentation correctly identifies handlers in plugin directories. Update line 195 to reference apps/ensindexer/src/plugins/ to match the actual codebase structure and prevent developer confusion.

🧰 Tools
🪛 LanguageTool

[typographical] ~195-~195: To join two clauses or introduce examples, consider using an em dash.
Context: ...s) ### Apps Structure - ensindexer - Ponder-based blockchain indexer. Event h...

(DASH_RULE)

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

In @.claude/CLAUDE.md at line 195, Update the documentation entry for
"ensindexer" to point to the actual handler implementation directory: change the
reference from `apps/ensindexer/ponder/src/` to `apps/ensindexer/src/plugins/`;
note that `apps/ensindexer/ponder/src/register-handlers.ts` only orchestrates
imports while the real event handlers live under the plugin folders (see
`ponder-indexing.md` for the correct pattern), so ensure the single-line
description for ensindexer names `apps/ensindexer/src/plugins/` as the handler
location.

- **@ensnode/ponder-subgraph** - Subgraph-compatible GraphQL API implementation.
- **@ensnode/ponder-metadata** - Metadata utilities for Ponder.
- **@ensnode/ensrainbow-sdk** - TypeScript client for ENSRainbow API.
- **@ensnode/ens-referrals** - ENS referral program logic.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Wrong package scope for ens-referrals — causes incorrect import path.

Line 211 lists @ensnode/ens-referrals, but the actual published package name is @namehash/ens-referrals — confirmed by the Package Naming section at line 66 ("Published packages: @namehash/*"), the Gotchas section at line 429 ("v0 of @namehash/ens-referrals"), and ens-referrals.md. An AI following this list would generate imports against the wrong package.

🐛 Proposed fix
-- **@ensnode/ens-referrals** - ENS referral program logic.
+- **@namehash/ens-referrals** - ENS referral program logic.
📝 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
- **@ensnode/ens-referrals** - ENS referral program logic.
- **@namehash/ens-referrals** - ENS referral program logic.
🧰 Tools
🪛 LanguageTool

[style] ~211-~211: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...peScript client for ENSRainbow API. - @ensnode/ens-referrals - ENS referral program ...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[typographical] ~211-~211: To join two clauses or introduce examples, consider using an em dash.
Context: ...ainbow API. - @ensnode/ens-referrals - ENS referral program logic. - **@namehas...

(DASH_RULE)

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

In @.claude/CLAUDE.md at line 211, The README entry incorrectly lists the
package scope as "@ensnode/ens-referrals"; update that string to the correct
published package scope "@namehash/ens-referrals" wherever it appears (e.g., the
list item currently reading "**@ensnode/ens-referrals** - ENS referral program
logic.") so imports generated from this doc use the correct package name.

Comment on lines +492 to +493
2. **Follow the builder pattern** when creating domain objects - use `satisfies` for type safety
3. **Use `satisfies`** for type validation while preserving type inference
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Tips 2 and 3 are duplicates — both advise using satisfies.

Tip 2 already says "Follow the builder pattern when creating domain objects — use satisfies for type safety." Tip 3 restates "Use satisfies for type validation while preserving type inference." Merge or drop one.

🔧 Proposed fix
 2. **Follow the builder pattern** when creating domain objects - use `satisfies` for type safety
-3. **Use `satisfies`** for type validation while preserving type inference
-4. **Match import ordering** defined in `biome.jsonc` - Biome will auto-fix on save
+3. **Match import ordering** defined in `biome.jsonc` - Biome will auto-fix on save
 ...

(Renumber subsequent tips accordingly.)

🧰 Tools
🪛 LanguageTool

[typographical] ~492-~492: To join two clauses or introduce examples, consider using an em dash.
Context: ...r pattern** when creating domain objects - use satisfies for type safety 3. **Use...

(DASH_RULE)

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

In @.claude/CLAUDE.md around lines 492 - 493, Tips 2 and 3 are duplicate (both
instruct to use `satisfies`); remove or merge them into a single tip that
mentions "Follow the builder pattern when creating domain objects — use
`satisfies` for type safety and to preserve type inference" and then renumber
all subsequent tips accordingly; update the content where `satisfies` is
referenced to point to the merged tip.

Comment on lines +114 to +143
```typescript
import { describeRoute } from "hono-openapi";
import { z } from "zod/v4";

const app = factory
.createApp()
.use(someMiddleware)
.get(
"/referral-leaderboard",
describeRoute({
tags: ["ENSAwards"],
summary: "Get Referrer Leaderboard",
description: "Returns paginated leaderboard data",
responses: {
200: { description: "Success" },
500: { description: "Internal server error" },
},
}),
validate("query", paginationQuerySchema),
async (c) => {
try {
const { page, recordsPerPage } = c.req.valid("query");
// ... handler logic
return c.json(serializeResponse(response));
} catch (error) {
logger.error({ error }, "Error in endpoint");
return c.json(errorResponse, 500);
}
},
);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Verify the fenced code block language specifier (MD040).

Static analysis flags a missing language specifier at line 42 in the file (which falls within or adjacent to one of the code blocks in this section). Ensure all fenced blocks in this section explicitly declare typescript.

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

In @.claude/rules/api-patterns.md around lines 114 - 143, Update the markdown
fenced code blocks in this section to explicitly declare the TypeScript language
(change every ``` to ```typescript) so the linter MD040 passes; specifically
ensure the block surrounding the example that uses describeRoute,
factory.createApp, validate, and paginationQuerySchema is opened with
```typescript and check adjacent fenced blocks in the same section for missing
language specifiers and fix them as well.

Comment on lines +6 to +9
- "apps/ensapi/src/cache/referr*"
- "apps/ensapi/src/cache/referral*"
- "apps/ensapi/src/middleware/referr*"
- "apps/ensapi/src/middleware/referral*"
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Redundant glob patterns — referr* subsumes referral*.

referr* matches any path starting with referr, which already includes referral* patterns. The referral* entries at lines 7 and 9 are unreachable duplicates.

🔧 Proposed fix
  - "apps/ensapi/src/cache/referr*"
- - "apps/ensapi/src/cache/referral*"
  - "apps/ensapi/src/middleware/referr*"
- - "apps/ensapi/src/middleware/referral*"
📝 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
- "apps/ensapi/src/cache/referr*"
- "apps/ensapi/src/cache/referral*"
- "apps/ensapi/src/middleware/referr*"
- "apps/ensapi/src/middleware/referral*"
- "apps/ensapi/src/cache/referr*"
- "apps/ensapi/src/middleware/referr*"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/ens-referrals.md around lines 6 - 9, The glob patterns
"referr*" already match any path beginning with "referr", so the explicit
"referral*" entries are redundant; remove the duplicate patterns
"apps/ensapi/src/cache/referral*" and "apps/ensapi/src/middleware/referral*"
from the rules so only the broader "apps/ensapi/src/cache/referr*" and
"apps/ensapi/src/middleware/referr*" remain (update the list in
.claude/rules/ens-referrals.md accordingly).

Comment on lines +42 to +49
```
ReferrerMetrics
└── ScoredReferrerMetrics (+ score calculation)
└── RankedReferrerMetrics (+ rank, isQualified, finalScore)
└── AwardedReferrerMetrics (+ awardPoolShare)

UnrankedReferrerMetrics (for addresses not on leaderboard)
```
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add language specifier to fenced code blocks.

The domain type hierarchy diagrams at lines 42–49 use bare ``` fences without a language tag, triggering MD040. Use ```text to silence the linter and convey intent.

🔧 Proposed fix
-```
+```text
 ReferrerMetrics
   └── ScoredReferrerMetrics (+ score calculation)
       └── RankedReferrerMetrics (+ rank, isQualified, finalScore)
           └── AwardedReferrerMetrics (+ awardPoolShare)

 UnrankedReferrerMetrics (for addresses not on leaderboard)
-```
+```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/ens-referrals.md around lines 42 - 49, Add a language tag to
the fenced code block containing the domain type hierarchy (the block that
starts with "ReferrerMetrics" and lists ScoredReferrerMetrics,
RankedReferrerMetrics, AwardedReferrerMetrics, and UnrankedReferrerMetrics) so
the linter MD040 is satisfied; change the opening fence from ``` to ```text and
keep the closing fence as ``` so the diagram remains unchanged but is explicitly
marked as plain text.


## Working with Ponder Event Handlers

- Handlers are registered in plugin directories under `src/` (e.g., `apps/ensindexer/src/plugins/subgraph/plugins/subgraph/src/`)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check the actual structure of plugins directory
find apps/ensindexer/src/plugins -type d -name "src" | sort

Repository: namehash/ensnode

Length of output: 42


🏁 Script executed:

# Read the specific line from the file to confirm content
sed -n '72p' .claude/rules/ponder-indexing.md

Repository: namehash/ensnode

Length of output: 189


🏁 Script executed:

# Get broader context around line 72
sed -n '70,75p' .claude/rules/ponder-indexing.md

Repository: namehash/ensnode

Length of output: 378


🏁 Script executed:

# List the actual structure of plugins directory
find apps/ensindexer/src/plugins -type f -o -type d | head -50

Repository: namehash/ensnode

Length of output: 3228


🏁 Script executed:

# Get a tree view to understand the structure
ls -lR apps/ensindexer/src/plugins/ 2>/dev/null | head -100

Repository: namehash/ensnode

Length of output: 4361


🏁 Script executed:

# Get complete subgraph structure
find apps/ensindexer/src/plugins/subgraph -type f -o -type d | sort

Repository: namehash/ensnode

Length of output: 2605


🏁 Script executed:

# Also check if there's any nested structure in subgraph
ls -lR apps/ensindexer/src/plugins/subgraph/

Repository: namehash/ensnode

Length of output: 3138


The path example uses src/ but handlers are actually organized in handlers/ directories.

The documentation claims handlers are at apps/ensindexer/src/plugins/subgraph/plugins/subgraph/src/, but the actual structure uses handlers/ instead of src/. All plugins across the codebase follow this pattern: handlers are in handlers/ subdirectories. The nested subgraph/plugins/subgraph/ path is correct (the subgraph plugin does have subgraph-sharing child plugins beneath it), but the directory name is wrong.

Correct paths:

  • Core subgraph plugin: apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/
  • Subgraph-sharing plugins: apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/ (and lineanames, threedns similarly)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/ponder-indexing.md at line 72, Update the incorrect example
path that uses `src/` to use `handlers/` instead: change any occurrences like
`apps/ensindexer/src/plugins/subgraph/plugins/subgraph/src/` to
`apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/`, and similarly
update the subgraph-sharing plugin examples to
`apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/` (and
lineanames/threedns variants); ensure the docs consistently reference the
`handlers/` directory for plugin handler registration.

Comment on lines +37 to +46
// 4. Create deserialize function with Zod validation
function deserializeReferrerMetrics(
serialized: SerializedReferrerMetrics
): ReferrerMetrics {
// First deserialize, then validate with Zod
const deserialized = { ... };
const parsed = schema.safeParse(deserialized);
if (parsed.error) throw new Error(...);
return parsed.data;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Deserialize example omits the z.preprocess() pattern actually used in the codebase.

The pseudocode implies a simple deserialize → safeParse flow, but the actual pattern in packages/ensnode-sdk/src/api/indexing-status/deserialize.ts uses z.preprocess() (not .transform()) precisely because preprocessing must run before validation against the final schema. An AI following this doc might reach for .transform() or a plain parse call and break the intended parse serialized → preprocess to unvalidated → validate pipeline.

Consider adding a note:

// ⚠️ Use z.preprocess(), NOT .transform()
// z.preprocess runs before validation (correct for the unvalidated→validated flow)
// z.transform runs after parsing and receives a typed input (incorrect here)
const schema = z.preprocess(buildUnvalidated, finalSchema);

Based on learnings: the pattern of using z.preprocess() with a function returning unknown is intentional, enforcing the "parse serialized → preprocess to unvalidated → validate final schema" flow. Using .transform() would be incorrect here as it runs after parsing.

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

In @.claude/rules/sdk-development.md around lines 37 - 46, The deserialize
example for deserializeReferrerMetrics is misleading: replace the simple
"deserialize → safeParse" guidance with explicit instruction to use z.preprocess
(not z.transform) so preprocessing runs before validation; update the
documentation and the schema construction in the deserialize flow to use
z.preprocess(buildUnvalidated, finalSchema) and ensure the preprocess function
returns unknown, then safeParse/parse against the final schema (reference
symbols: deserializeReferrerMetrics, buildUnvalidated, finalSchema,
z.preprocess).

### ENSRainbow (apps/ensrainbow)

Label hash recovery service.

Copy link
Contributor

Choose a reason for hiding this comment

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

Documentation incorrectly describes event handler locations as apps/ensindexer/ponder/src/ and under src/ subdirectories, when they are actually at the plugin root in event-handlers.ts files

Fix on Vercel

- **@ensnode/ponder-subgraph** - Subgraph-compatible GraphQL API implementation.
- **@ensnode/ponder-metadata** - Metadata utilities for Ponder.
- **@ensnode/ensrainbow-sdk** - TypeScript client for ENSRainbow API.
- **@ensnode/ens-referrals** - ENS referral program logic.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- **@ensnode/ens-referrals** - ENS referral program logic.
- **@namehash/ens-referrals** - ENS referral program logic.

CLAUDE.md lists incorrect package name @ensnode/ens-referrals instead of @namehash/ens-referrals

Fix on Vercel

): ReferrerMetrics {
// First deserialize, then validate with Zod
const deserialized = { ... };
const parsed = schema.safeParse(deserialized);
Copy link
Contributor

Choose a reason for hiding this comment

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

The documented directory structure for @ensnode/ensnode-sdk in sdk-development.md is inaccurate, showing an api/ directory at the top level when it's actually nested, and omitting several top-level directories.

Fix on Vercel

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.

1 participant

Comments