Skip to content

feat: introduce enscli and ensskills#2242

Open
shrugs wants to merge 15 commits into
mainfrom
feat/enscli-ensskills
Open

feat: introduce enscli and ensskills#2242
shrugs wants to merge 15 commits into
mainfrom
feat/enscli-ensskills

Conversation

@shrugs
Copy link
Copy Markdown
Member

@shrugs shrugs commented Jun 2, 2026

Summary

  • new enscli package: an agent- and human-friendly, read-only CLI for ENS — raw omnigraph queries (ensnode omnigraph "<q>" --variables …), offline schema exploration (omnigraph schema [Type[.field]]), offline contract identification (datasources identify <address> — which well-known ENS contract an address is, by namespace/chain), namehash/labelhash, ensrainbow heal/count, and ensnode indexing-status. json when piped / pretty in a tty, structured errors, input hardening, namespace+url config resolution (flag > env > .env > namespace default).
  • new ensskills package: versioned, skills-npm-installable agent skills. ships a foundational base skill (shared cross-cutting conventions every other skill assumes), plus ens-protocol (a concise, vendor-neutral conceptual model with pull-as-needed reference pages), omnigraph (autogenerated schema reference + vetted example queries), and enscli skills; stubs reserved for enssdk / enskit / migrate-to-omnigraph / unigraph-sql.
  • @ensnode/datasources: new identifyDatasourceContracts(namespaceId, query) — finds every well-known contract in a namespace's datasources whose address matches a given address, optionally scoped to a chain.
  • @ensnode/ensnode-sdk: getDefaultEnsNodeUrl now returns the hosted default for the sepolia-v2 namespace.
  • docs: fleshed out the enscli, ensskills, and ai-llm integration pages, and added a new llms.txt page documenting the /llms.txt + /llms-full.txt endpoints for loading the docs into an agent (the base skill points agents at them).

Why

Testing

  • pnpm typecheck and pnpm lint clean.
  • enscli unit tests: config-resolution precedence, input-hardening rejections, schema rendering from bundled introspection, datasources identify address/chain/CAIP-10 parsing and miss-returns-empty.
  • enscli integration tests spawn the built bin against the ens-test-env devnet (pnpm test:integration).
  • ensskills generate verified idempotent (schema/examples regions stay in lockstep with the sdk).

Notes for Reviewer

  • v0 is read-only by design; mutations and an MCP surface are deferred.
  • ensskills installs via the consumer-side prepare: skills-npm convention — no bin, no postinstall, version pinned to the suite.
  • the omnigraph skill's schema/examples live between <!-- AUTOGEN --> markers and are generated by pnpm -F ensskills generate — don't hand-edit those regions.

@shrugs shrugs requested a review from a team as a code owner June 2, 2026 16:51
Copilot AI review requested due to automatic review settings June 2, 2026 16:51
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Jun 2, 2026

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

Project Deployment Actions Updated (UTC)
enskit-react-example.ensnode.io Ready Ready Preview, Comment Jun 3, 2026 12:39am
3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Jun 3, 2026 12:39am
ensnode.io Skipped Skipped Jun 3, 2026 12:39am
ensrainbow.io Skipped Skipped Jun 3, 2026 12:39am

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 2, 2026

🦋 Changeset detected

Latest commit: 2397fd1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 24 packages
Name Type
@ensnode/datasources Minor
enscli Minor
ensskills Minor
@ensnode/ensnode-sdk Minor
ensadmin Minor
ensapi Minor
ensindexer Minor
fallback-ensapi Minor
@ensnode/integration-test-env Minor
@namehash/namehash-ui Minor
ensrainbow Minor
@docs/ensnode Minor
@namehash/ens-referrals Minor
@ensnode/ensdb-sdk Minor
@ensnode/ensrainbow-sdk Minor
@docs/ensrainbow Minor
enssdk Minor
enskit Minor
@ensnode/ponder-sdk Minor
@ensnode/ponder-subgraph Minor
@ensnode/shared-configs Minor
@ensnode/ensindexer-perf-testing Minor
@ensnode/enskit-react-example Patch
@ensnode/enssdk-example Patch

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: edb026ac-0482-465d-b197-cb376bdd424f

📥 Commits

Reviewing files that changed from the base of the PR and between 9e69b64 and 2397fd1.

⛔ Files ignored due to path filters (2)
  • packages/enssdk/src/omnigraph/generated/schema.graphql is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (40)
  • LICENSE
  • apps/ensadmin/LICENSE
  • apps/ensapi/LICENSE
  • apps/ensindexer/LICENSE
  • apps/ensrainbow/LICENSE
  • apps/fallback-ensapi/LICENSE
  • docs/ensnode.io/LICENSE
  • docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts
  • docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
  • docs/ensrainbow.io/LICENSE
  • examples/enskit-react-example/LICENSE
  • examples/enssdk-example/LICENSE
  • examples/ensskills-example/LICENSE
  • examples/omnigraph-graphql-example/LICENSE
  • packages/datasources/LICENSE
  • packages/datasources/src/identify-contracts.ts
  • packages/ens-referrals/LICENSE
  • packages/enscli/LICENSE
  • packages/enscli/src/cli.integration.test.ts
  • packages/enscli/src/commands/datasources/identify.ts
  • packages/enscli/src/commands/ensnode/omnigraph-schema.ts
  • packages/enscli/src/commands/ensnode/omnigraph.ts
  • packages/enscli/src/lib/config.ts
  • packages/enscli/src/lib/output.ts
  • packages/ensdb-sdk/LICENSE
  • packages/enskit/LICENSE
  • packages/ensnode-sdk/LICENSE
  • packages/ensrainbow-sdk/LICENSE
  • packages/enssdk/LICENSE
  • packages/ensskills/LICENSE
  • packages/ensskills/package.json
  • packages/ensskills/scripts/generate.ts
  • packages/ensskills/skills/ens-protocol/SKILL.md
  • packages/ensskills/skills/enscli/SKILL.md
  • packages/ensskills/skills/omnigraph/SKILL.md
  • packages/integration-test-env/LICENSE
  • packages/namehash-ui/LICENSE
  • packages/ponder-sdk/LICENSE
  • packages/ponder-subgraph/LICENSE
  • packages/shared-configs/LICENSE
💤 Files with no reviewable changes (2)
  • packages/datasources/src/identify-contracts.ts
  • docs/ensnode.io/config/integrations/starlight/sidebar-topics/integrate.ts

📝 Walkthrough

Walkthrough

Introduces a new ENS CLI (enscli) with commands and shared libs, ensskills agent skill bundles with generators, datasources contract identification API/CLI, SDK default URL for sepolia-v2, extensive docs/MDX and sidebar updates, tests, examples, and changesets.

Changes

CLI + Skills + Datasources identification

Layer / File(s) Summary
End-to-end CLI, skills, datasources, SDK, and docs
packages/enscli/*, packages/ensskills/*, packages/datasources/*, packages/ensnode-sdk/*, docs/**, apps/**, examples/**, .changeset/*, LICENSE
Adds the enscli CLI with commands/libs/tests, ensskills bundles and generator, datasources identify (library + CLI), SDK sepolia-v2 default URL, examples, and broad documentation and navigation updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

  • namehash/ensnode#2112 — Touches the same enscli and ensskills integration-option docs expanded here.
  • namehash/ensnode#2101 — Aligns enscli tests and schema expectations with Domain.canonical changes referenced here.
  • namehash/ensnode#2225 — Related hosted-instance/version-warning component logic also modified in this PR.

Suggested labels

ensnode-sdk, javascript, docs

Poem

A rabbit taps the keys with glee,
Shipping enscli for you and me.
Skills in bundles, neatly tied,
Queries hop and hashes glide.
Contracts found, rainbows heal—
Sepolia sings; the docs reveal.
Carrots cached, releases sealed. 🥕✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/enscli-ensskills

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 2, 2026

Greptile Summary

This PR introduces two new packages — enscli (a read-only, agent-friendly CLI wrapping the ENS Omnigraph, ENSRainbow, and datasource catalog) and ensskills (versioned SKILL.md files for AI coding agents) — along with a new identifyDatasourceContracts helper in @ensnode/datasources and a hosted default for the sepolia-v2 namespace in the SDK.

  • enscli: bundles the Omnigraph SDL for offline schema exploration, resolves config via a flag > env > .env > namespace-default precedence chain, validates all user inputs before any network call, and prints JSON when piped / pretty in a TTY. The variables JSON object-type guard (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) is properly in place.
  • ensskills: ships base, ens-protocol, omnigraph, and enscli skills; autogenerated schema/examples regions are bounded by <!-- AUTOGEN:... --> markers and regenerated idempotently via pnpm generate:skills.
  • @ensnode/datasources: identifyDatasourceContracts correctly handles single and multi-address contracts, optional chain-scoping, and skips contracts with no fixed address.

Confidence Score: 5/5

Safe to merge — the new CLI and skills packages are read-only additions with no mutations, and the core logic (config resolution, input validation, JSON variable type-checking) is well-guarded and covered by unit tests.

The changes introduce two new standalone packages and a small datasource helper. The input-hardening, config precedence, and JSON variable validation are all correctly implemented. No existing functionality is modified in a breaking way. The one gap — a missing test:integration npm script that the PR description promises — is a developer ergonomics issue, not a runtime defect.

No files require special attention; enscli/package.json is worth a quick look to add the missing test:integration script.

Important Files Changed

Filename Overview
packages/enscli/package.json New CLI package; uses prepublish (not prepublishOnly); vitest.integration.config.ts exists but no test:integration script is defined to invoke it
packages/enscli/src/lib/config.ts New config resolution module: flag > env > .env > namespace default precedence chain for namespace, ENSNode URL, and ENSRainbow URL; empty-string guard in fromEnv is correctly applied throughout
packages/enscli/src/commands/ensnode/omnigraph.ts Variables JSON is validated for object type (not array or scalar) before use; schema subcommand dispatches offline without a network call; logic looks correct
packages/enscli/src/commands/datasources/identify.ts Parses bare address, chainId:address, and eip155:chainId:address formats; validates chain ID with strict digit-only regex; delegates normalization to toNormalizedAddress; logic is correct
packages/datasources/src/identify-contracts.ts New identifyDatasourceContracts function; correctly handles array and single addresses, optional chainId filter, and skips contracts with no fixed address
packages/ensskills/scripts/generate.ts Generates autogen regions in SKILL.md files from live SDL and example sources; uses regex-anchored region replacement and prettier formatting to stay idempotent
packages/enscli/src/commands/ensnode/omnigraph-schema.ts Offline schema introspection over the bundled SDL; dispatches cleanly across root/type/field/search paths with proper error messages
packages/enscli/src/lib/validate.ts assertCleanIdentifier iterates Unicode code points correctly; rejects control chars, ?, #, % before any network call
packages/ensskills/package.json New ensskills package; ships only the skills/ directory, has no runtime dependencies, and uses devDependencies for generation tooling

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    CLI["enscli (bin: dist/cli.js)"] --> EN["ensnode"]
    CLI --> ER["ensrainbow"]
    CLI --> DS["datasources"]
    CLI --> NH["namehash"]
    CLI --> LH["labelhash"]

    EN --> OG["omnigraph <query>"]
    EN --> OGS["omnigraph schema [Type[.field]]"]
    EN --> IS["indexing-status"]

    ER --> HEAL["heal <labelhash>"]
    ER --> COUNT["count"]

    DS --> IDN["identify <address>"]

    OG -->|"resolveEnsNodeUrl()"| CONFIG["config.ts\n(flag > env > .env > namespace default)"]
    OGS -->|"bundled SDL (offline)"| SDL["enssdk/omnigraph/schema.graphql"]
    IS --> CONFIG
    HEAL -->|"resolveEnsRainbowUrl()"| CONFIG
    COUNT --> CONFIG
    IDN -->|"identifyDatasourceContracts()"| DATASOURCES["@ensnode/datasources"]

    CONFIG -->|"getDefaultEnsNodeUrl()"| SDK["@ensnode/ensnode-sdk"]
    CONFIG -->|"DEFAULT_ENSRAINBOW_URL"| RBSDK["@ensnode/ensrainbow-sdk"]
Loading

Reviews (5): Last reviewed commit: "test(enscli): surface build logs on fail..." | Re-trigger Greptile

Copy link
Copy Markdown
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 introduces two new public-facing integration surfaces—enscli (a read-only, agent-friendly CLI) and ensskills (versioned agent skill bundles)—to standardize how humans and AI agents query ENS state via the Omnigraph, plus supporting docs and a small SDK default-URL enhancement.

Changes:

  • Added enscli package (CLI commands for Omnigraph queries + offline schema exploration, hashing helpers, ENSRainbow heal/count, and ENSNode indexing status), including unit + integration tests.
  • Added ensskills package (skill bundles for ens-protocol, omnigraph with AUTOGEN regions, enscli, and stub skills), plus a generator script to keep schema/examples in sync.
  • Updated @ensnode/ensnode-sdk to provide a hosted default URL for the sepolia-v2 namespace; expanded docs pages for enscli, ensskills, and AI/LLM integration.

Agent DX CLI Scale (enscli, 0–21): 12 / 21 (Agent-ready)

  • Machine-readable output: 2/3 (JSON-by-default when non-TTY; structured JSON errors)
  • Raw payload input: 3/3 (raw GraphQL query payload is first-class)
  • Schema introspection: 1/3 (strong Omnigraph schema introspection, but not full CLI-args schema)
  • Context window discipline: 2/3 (GraphQL field masking + explicit guidance)
  • Input hardening: 1/3 (good start; not comprehensive per the scale definition)
  • Safety rails: 0/3 (read-only helps, but no dry-run concept needed; no response sanitization)
  • Agent knowledge packaging: 3/3 (versioned, installable skills with strong guidance)

Reviewed changes

Copilot reviewed 47 out of 49 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds new workspace importers/deps for enscli and ensskills (incl. citty).
packages/ensskills/tsconfig.json TypeScript config for ensskills scripts.
packages/ensskills/skills/unigraph-sql/SKILL.md Stub skill placeholder for future SQL querying guidance.
packages/ensskills/skills/omnigraph/SKILL.md Omnigraph skill content incl. AUTOGEN schema + example queries.
packages/ensskills/skills/migrate-to-omnigraph/SKILL.md Stub migration skill placeholder.
packages/ensskills/skills/enssdk/SKILL.md Stub SDK skill placeholder.
packages/ensskills/skills/enskit/SKILL.md Stub React skill placeholder.
packages/ensskills/skills/enscli/SKILL.md Skill describing how agents should drive enscli.
packages/ensskills/skills/ens-protocol/SKILL.md Protocol conceptual model skill + reference index.
packages/ensskills/skills/ens-protocol/references/resolution.md Reference page: forward/reverse resolution, Universal Resolver, coinTypes.
packages/ensskills/skills/ens-protocol/references/records.md Reference page: ENS record types and caveats (avatar, reverse, etc.).
packages/ensskills/skills/ens-protocol/references/names-and-hashing.md Reference page: normalization, namehash/labelhash, encoded labelhash.
packages/ensskills/skills/ens-protocol/references/ensv1-and-ensv2.md Reference page: coexistence model and “two domains” consequences.
packages/ensskills/skills/ens-protocol/references/architecture.md Reference page: registry/resolver/registrar + ENSNode canonical extensions.
packages/ensskills/scripts/generate.ts Generator that refreshes AUTOGEN regions in omnigraph skill from repo sources.
packages/ensskills/README.md Documents how to install ensskills via skills-npm and pin versions.
packages/ensskills/package.json Publishes skills/ only; adds generate/lint/typecheck scripts and deps.
packages/ensnode-sdk/src/ensnode/deployments.ts Adds hosted default ENSNode URL for sepolia-v2 namespace.
packages/enscli/vitest.integration.config.ts Vitest integration test config for enscli.
packages/enscli/vitest.config.ts Vitest unit test config for enscli.
packages/enscli/tsup.config.ts Enscli bundling config (single self-contained ESM bin; .graphql text loader).
packages/enscli/tsconfig.json TypeScript config for enscli source.
packages/enscli/src/main.ts Root command definition and subcommand wiring.
packages/enscli/src/lib/validate.ts Identifier hardening helper (rejects control chars and ?/#/%).
packages/enscli/src/lib/validate.test.ts Unit tests for identifier hardening.
packages/enscli/src/lib/output.ts JSON/pretty output routing + structured error handling.
packages/enscli/src/lib/output.test.ts Unit tests for output format resolution.
packages/enscli/src/lib/config.ts Namespace + ENSNode/ENSRainbow URL resolution with .env support.
packages/enscli/src/lib/config.test.ts Unit tests for resolution precedence and error cases.
packages/enscli/src/lib/args.ts Shared argument definitions (namespace/url + output format).
packages/enscli/src/graphql-sdl.d.ts Ambient type to import .graphql files as strings.
packages/enscli/src/commands/namehash.ts CLI command: local namehash computation via enssdk.
packages/enscli/src/commands/labelhash.ts CLI command: local labelhash computation via enssdk.
packages/enscli/src/commands/ensrainbow/index.ts ENSRainbow command group wiring.
packages/enscli/src/commands/ensrainbow/heal.ts ENSRainbow heal command (labelhash → label).
packages/enscli/src/commands/ensrainbow/count.ts ENSRainbow count command.
packages/enscli/src/commands/ensnode/omnigraph.ts Raw Omnigraph query runner + offline schema submode dispatch.
packages/enscli/src/commands/ensnode/omnigraph-schema.ts Offline schema explorer (JSON + pretty render) using bundled SDL.
packages/enscli/src/commands/ensnode/indexing-status.ts Fetches ENSNode indexing status via SDK client.
packages/enscli/src/commands/ensnode/index.ts ENSNode command group wiring.
packages/enscli/src/cli.ts Entrypoint bin with EPIPE handling for piped output.
packages/enscli/src/cli.integration.test.ts Integration tests running built dist/cli.js against devnet.
packages/enscli/README.md CLI package README and quickstart usage.
packages/enscli/package.json CLI package metadata, bin entry, scripts, and dependencies.
package.json Adds generate:skills to root script set.
docs/ensnode.io/src/content/docs/docs/integrate/integration-options/ensskills.mdx New docs for installing/using ensskills with skills-npm.
docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enscli.mdx New docs for enscli commands, output contract, and configuration.
docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx Updates AI/LLM integration narrative to center ensskills + enscli.
.changeset/enscli-ensskills-initial.md Changeset announcing new packages and the SDK sepolia-v2 default URL.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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

Comment thread packages/enscli/src/lib/config.ts Outdated
Comment thread packages/enscli/src/lib/output.ts Outdated
Comment thread packages/enscli/src/commands/ensnode/omnigraph.ts
Comment thread packages/ensskills/scripts/generate.ts Outdated
Comment thread packages/ensskills/skills/ens-protocol/SKILL.md Outdated
Comment thread packages/ensskills/skills/ens-protocol/SKILL.md Outdated
Comment thread packages/ensskills/skills/ens-protocol/SKILL.md Outdated
Comment thread packages/enscli/src/commands/ensnode/omnigraph.ts
Comment thread packages/enscli/src/lib/config.ts
Comment thread packages/enscli/package.json
Comment thread packages/enscli/src/lib/config.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/enscli/src/cli.integration.test.ts`:
- Around line 36-42: The test "omnigraph schema: describes a type from the
bundled SDL (no network)" uses multiple separate assertions on the parsed
schema; replace these with a single concise matcher using toMatchObject: call
runCli(["ensnode","omnigraph","schema","Domain"]) as before, parse result.stdout
into schema, then assert expect(schema).toMatchObject({ name: "Domain", fields:
expect.arrayContaining([expect.objectContaining({ name: "canonical" })]) }) so
the assertions remain equivalent but more concise; update the test body around
the existing runCli/result/schema variables and remove the separate
expect(...).toBe/expect(...).toContain lines.

In `@packages/enscli/src/commands/ensnode/omnigraph-schema.ts`:
- Around line 191-197: The code currently uses target.split(".", 2) which
silently truncates targets like "Type.field.extra" instead of rejecting them;
update the runOmnigraphSchema parsing to validate that target is exactly two
non-empty dot-separated segments before calling describeFieldPath: replace the
split-and-truncate approach (the call site referencing target.split(".", 2) and
the variables typeName/fieldName) with a strict parser (prefer using zod.parse)
that enforces the pattern /^[^.]+\.[^.]+$/ and then extract the two segments to
pass to describeFieldPath; on validation failure, return a user-facing
error/exit rather than proceeding.

In `@packages/enscli/src/commands/ensnode/omnigraph.ts`:
- Around line 53-60: The parsed --variables value (args.variables) may be a
non-object JSON (array, number, string, etc.); after JSON.parse assign to
variables, validate that variables is a non-null object and not an Array (e.g.,
typeof variables === "object" && variables !== null &&
!Array.isArray(variables)) and if it fails throw an Error like "Invalid
--variables: expected a JSON object string." so the Record<string, unknown>
contract is preserved; ensure this validation is applied in the same block that
currently parses args.variables and keep the variable name variables unchanged.

In `@packages/enscli/src/lib/config.test.ts`:
- Around line 9-18: The tests currently only scrub process.env but fail to
isolate reads from a local .env file (used by resolveNamespace and the ENS URL
resolvers), so make the tests hermetic by mocking the .env reader or running the
suite in a temporary cwd: either add a vi.mock for the module that loads .env
(e.g., mock 'dotenv' or 'dotenv/config' with vi.mock and provide a parse/get
implementation via vi.fn that returns controlled values) or in the beforeEach
switch to a temp directory (use fs.mkdtempSync and process.chdir) and create a
controlled .env if needed, then restore cwd in afterEach; reference the test
hooks (beforeEach/afterEach), the resolveNamespace function and the ENS URL
resolver modules when making the change and prefer vi.mock/vi.fn per guidelines.

In `@packages/enscli/src/lib/config.ts`:
- Around line 39-70: Update resolveNamespace to use ENSNamespaceSchema.parse on
the raw value (flag("namespace") ?? fromEnv("NAMESPACE") ??
ENSNamespaceIds.Mainnet) instead of manual isNamespace check and throwing;
replace resolveEnsNodeUrl and resolveEnsRainbowUrl URL construction to use
makeUrlSchema().parse for parsing explicit values
(flag("ensnode-url")/fromEnv("ENSNODE_URL") and
flag("ensrainbow-url")/fromEnv("ENSRAINBOW_URL") respectively) and, for the
fallback in resolveEnsNodeUrl call getDefaultEnsNodeUrl(namespace) but still
parse its result with makeUrlSchema().parse or let getDefaultEnsNodeUrl remain
and parse its return; import ENSNamespaceSchema and makeUrlSchema from
`@ensnode/ensnode-sdk/internal` and retain parse() behavior (so ZodError is thrown
on invalid input), and adjust tests to expect Zod error messages instead of the
previous "Invalid namespace" text.

In `@packages/enscli/src/lib/output.ts`:
- Around line 20-26: The printResult function should be made generic so the data
and its prettyText renderer share the same type: change printResult to accept a
generic type parameter (e.g., <T>) and type its parameters as data: T and
prettyText?: (data: T) => string, remove the unsafe cast data as never, and keep
the existing resolveFormat(args) === "pretty" check; update any internal
references accordingly so the compiler enforces that prettyText accepts the same
T as data (refer to function printResult and resolveFormat).
- Around line 7-12: Replace the hand-rolled validation in resolveFormat with a
zod schema (add zod as a package dependency) and call schema.parse(args.output)
to coerce/validate the value, returning the typed "json" | "pretty" union;
update the resolveFormat function to use that schema. In printResult, remove the
unsafe never casts and type prettyText to the actual payload type (use a generic
or the concrete result type expected by printResult) so the serializer functions
accept the real data shape instead of (data: never). In fail, stop calling
process.exit(1) immediately after writing to stderr; either drain/flush stderr
before exiting or simply throw an Error (or return a rejected Promise) so the
top-level runner handles process.exit, ensuring stderr write completes reliably.
Ensure you update imports/usages of resolveFormat/printResult/fail to match the
new typings.

In `@packages/ensskills/README.md`:
- Line 28: The README currently links to a package-local license via "See
[LICENSE](./LICENSE)"; change that link to point at the repository root license
(e.g. "See [LICENSE](../../LICENSE)" from packages/ensskills/ or use an absolute
"/LICENSE") so the GitHub-rendered README resolves to the repo LICENSE; update
the link in the README.md where the "See [LICENSE](./LICENSE)" text appears.

In `@packages/ensskills/skills/ens-protocol/SKILL.md`:
- Line 88: Replace the typo "The closes thing" with "The closest thing" in the
ENS protocol documentation sentence that starts "After ENSv2 launches..." (the
line describing stable identifiers for ENSv1 `(chainId, registryAddress, node)`
and ENSv2 `(chainId, registryAddress, storageId)`), ensuring the corrected
sentence reads "The closest thing to a stable identifier is...".
- Line 25: Fix the typo in SKILL.md by replacing "Domains ae keyed" with
"Domains are keyed" in the sentence under the hashing note so the line reads
"Because Domains are keyed by these hashes on-chain, in ENSv1 a label string is
frequently **unknown** (you have only its hash)."

In `@packages/ensskills/skills/enscli/SKILL.md`:
- Around line 37-48: The fenced code block in SKILL.md for the command diagram
lacks a language tag; update the opening triple-backtick to include the language
identifier "text" so it reads ```text to satisfy linters and improve clarity;
locate the block containing the ENS CLI tree (lines showing enscli, ensnode,
omnigraph, indexing-status, etc.) and change its opening fence accordingly
(leave the block contents unchanged and keep the closing ```).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 43f4577c-a180-4cfb-8961-d66dfbd21341

📥 Commits

Reviewing files that changed from the base of the PR and between 0b38798 and 61ee51a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (48)
  • .changeset/enscli-ensskills-initial.md
  • docs/ensnode.io/src/content/docs/docs/integrate/ai-llm.mdx
  • docs/ensnode.io/src/content/docs/docs/integrate/integration-options/enscli.mdx
  • docs/ensnode.io/src/content/docs/docs/integrate/integration-options/ensskills.mdx
  • package.json
  • packages/enscli/README.md
  • packages/enscli/package.json
  • packages/enscli/src/cli.integration.test.ts
  • packages/enscli/src/cli.ts
  • packages/enscli/src/commands/ensnode/index.ts
  • packages/enscli/src/commands/ensnode/indexing-status.ts
  • packages/enscli/src/commands/ensnode/omnigraph-schema.ts
  • packages/enscli/src/commands/ensnode/omnigraph.ts
  • packages/enscli/src/commands/ensrainbow/count.ts
  • packages/enscli/src/commands/ensrainbow/heal.ts
  • packages/enscli/src/commands/ensrainbow/index.ts
  • packages/enscli/src/commands/labelhash.ts
  • packages/enscli/src/commands/namehash.ts
  • packages/enscli/src/graphql-sdl.d.ts
  • packages/enscli/src/lib/args.ts
  • packages/enscli/src/lib/config.test.ts
  • packages/enscli/src/lib/config.ts
  • packages/enscli/src/lib/output.test.ts
  • packages/enscli/src/lib/output.ts
  • packages/enscli/src/lib/validate.test.ts
  • packages/enscli/src/lib/validate.ts
  • packages/enscli/src/main.ts
  • packages/enscli/tsconfig.json
  • packages/enscli/tsup.config.ts
  • packages/enscli/vitest.config.ts
  • packages/enscli/vitest.integration.config.ts
  • packages/ensnode-sdk/src/ensnode/deployments.ts
  • packages/ensskills/README.md
  • packages/ensskills/package.json
  • packages/ensskills/scripts/generate.ts
  • packages/ensskills/skills/ens-protocol/SKILL.md
  • packages/ensskills/skills/ens-protocol/references/architecture.md
  • packages/ensskills/skills/ens-protocol/references/ensv1-and-ensv2.md
  • packages/ensskills/skills/ens-protocol/references/names-and-hashing.md
  • packages/ensskills/skills/ens-protocol/references/records.md
  • packages/ensskills/skills/ens-protocol/references/resolution.md
  • packages/ensskills/skills/enscli/SKILL.md
  • packages/ensskills/skills/enskit/SKILL.md
  • packages/ensskills/skills/enssdk/SKILL.md
  • packages/ensskills/skills/migrate-to-omnigraph/SKILL.md
  • packages/ensskills/skills/omnigraph/SKILL.md
  • packages/ensskills/skills/unigraph-sql/SKILL.md
  • packages/ensskills/tsconfig.json

Comment thread packages/enscli/src/cli.integration.test.ts
Comment thread packages/enscli/src/commands/ensnode/omnigraph-schema.ts
Comment thread packages/enscli/src/commands/ensnode/omnigraph.ts
Comment thread packages/enscli/src/lib/config.test.ts
Comment thread packages/enscli/src/lib/config.ts
Comment thread packages/enscli/src/lib/output.ts Outdated
Comment thread packages/ensskills/README.md
Comment thread packages/ensskills/skills/ens-protocol/SKILL.md Outdated
Comment thread packages/ensskills/skills/ens-protocol/SKILL.md Outdated
Comment thread packages/ensskills/skills/enscli/SKILL.md Outdated
Comment thread packages/ensskills/scripts/generate.ts
Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestion:

main() is an async function called without await or error handling, causing unhandled promise rejections if the script fails

Fix on Vercel

Comment thread packages/enscli/src/lib/config.ts
Comment thread packages/enscli/src/commands/ensnode/omnigraph.ts
Comment thread packages/enscli/src/lib/output.ts Outdated
Comment thread packages/enscli/src/lib/config.ts Outdated
Comment thread packages/enscli/package.json
Comment thread packages/enscli/src/lib/output.ts
Comment thread packages/enscli/src/commands/ensnode/omnigraph-schema.ts Outdated
Comment thread packages/enscli/src/lib/config.ts
- config: treat empty-string env vars as unset so ENSRAINBOW_URL= / NAMESPACE=
  fall back to defaults instead of crashing on new URL("") (Greptile P1)
- omnigraph: reject non-object JSON --variables (arrays/scalars) with a clear error
- omnigraph schema: reject malformed Type.field targets instead of truncating extra
  segments or accepting empty selectors
- output: make printResult generic so prettyText is typed to the payload (drop the
  `data as never` cast)
- datasources identify: require base-10 digits for chainId (reject 1e3 / 0x10)
- ensskills generate: await main() with a .catch that exits non-zero; format written
  SKILL.md files with Prettier so generated output matches the linted committed state
- skills: fix typos / grammar in ens-protocol SKILL; tag the enscli command-tree
  fenced block as `text`; refresh the autogenerated omnigraph schema reference
- tests: use toMatchObject for the omnigraph-schema integration assertion

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 2, 2026 22:43
@vercel vercel Bot temporarily deployed to Preview – ensnode.io June 2, 2026 22:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io June 2, 2026 22:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io June 2, 2026 22:43 Inactive
Copy link
Copy Markdown
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

Copilot reviewed 77 out of 113 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread packages/ensskills/skills/ens-protocol/SKILL.md Outdated
- datasources: drop redundant @returns JSDoc on identifyDatasourceContracts
- enscli identify: omit "(null)" in pretty output when a contract's chain is
  unresolved; comment the base-10 chainId guard
- license: standardize every LICENSE copyright to "NameHash Labs"
- docs: merge the llms.txt endpoint + prompt content into the AI/LLM Tooling page
  and remove the standalone llms-txt page (and its sidebar entry)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented Jun 2, 2026

@greptile review

…rotocol skill

Use 'subnames (a.k.a. subdomains)' to match the sibling architecture reference doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 2, 2026 22:58
@vercel vercel Bot temporarily deployed to Preview – ensnode.io June 2, 2026 22:58 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io June 2, 2026 22:58 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io June 2, 2026 22:58 Inactive
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented Jun 2, 2026

@greptile review

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

Copilot reviewed 101 out of 137 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread packages/enscli/src/cli.integration.test.ts
Comment thread packages/enscli/package.json
Switch the beforeAll build from stdio: "ignore" to capturing pipe, printing
stdout/stderr only when the build throws — quiet on success, diagnosable on CI failure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented Jun 3, 2026

@greptile review

@vercel vercel Bot temporarily deployed to Preview – ensnode.io June 3, 2026 00:39 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io June 3, 2026 00:39 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io June 3, 2026 00:39 Inactive
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.

Narrative Overhaul: ensskills agent skills

2 participants