From 8e262466006de2f4a36ffb72403989dd25b827af Mon Sep 17 00:00:00 2001 From: sunil-lakshman <104969541+sunil-lakshman@users.noreply.github.com> Date: Tue, 7 Apr 2026 12:38:07 +0530 Subject: [PATCH] Added cursor rules and skill files --- .cursor/rules/README.md | 5 +++ .ruby-version | 2 +- AGENTS.md | 49 +++++++++++++++++++++++++++ Gemfile.lock | 29 +++++++--------- contentstack_utils.gemspec | 6 ++-- skills/README.md | 16 +++++++++ skills/code-review/SKILL.md | 44 +++++++++++++++++++++++++ skills/contentstack-utils/SKILL.md | 51 ++++++++++++++++++++++++++++ skills/dev-workflow/SKILL.md | 53 ++++++++++++++++++++++++++++++ skills/framework/SKILL.md | 44 +++++++++++++++++++++++++ skills/ruby-style/SKILL.md | 42 +++++++++++++++++++++++ skills/testing/SKILL.md | 45 +++++++++++++++++++++++++ 12 files changed, 365 insertions(+), 21 deletions(-) create mode 100644 .cursor/rules/README.md create mode 100644 AGENTS.md create mode 100644 skills/README.md create mode 100644 skills/code-review/SKILL.md create mode 100644 skills/contentstack-utils/SKILL.md create mode 100644 skills/dev-workflow/SKILL.md create mode 100644 skills/framework/SKILL.md create mode 100644 skills/ruby-style/SKILL.md create mode 100644 skills/testing/SKILL.md diff --git a/.cursor/rules/README.md b/.cursor/rules/README.md new file mode 100644 index 0000000..f5c1f87 --- /dev/null +++ b/.cursor/rules/README.md @@ -0,0 +1,5 @@ +# Cursor (optional) + +**Cursor** users: start at **[AGENTS.md](../../AGENTS.md)**. All conventions live in **`skills/*/SKILL.md`**. + +This folder only points contributors to **`AGENTS.md`** so editor-specific config does not duplicate the canonical docs. diff --git a/.ruby-version b/.ruby-version index c20c8ac..0aec50e 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6 \ No newline at end of file +3.1.4 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..3287f26 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,49 @@ +# Contentstack Utils Ruby – Agent guide + +**Universal entry point** for contributors and AI agents. Detailed conventions live in **`skills/*/SKILL.md`**. + +## What this repo is + +| Field | Detail | +|--------|--------| +| **Name:** | [contentstack/contentstack-utils-ruby](https://github.com/contentstack/contentstack-utils-ruby) | +| **Purpose:** | Ruby gem that renders Contentstack rich text and JSON RTE (including GraphQL-shaped payloads) to HTML, with pluggable rendering via `ContentstackUtils::Model::Options` subclasses. | +| **Out of scope (if any):** | This package does not ship an HTTP client or stack SDK; it pairs with the separate Contentstack Ruby delivery client for entry data and `_embedded_items`. | + +## Tech stack (at a glance) + +| Area | Details | +|------|---------| +| Language | Ruby **≥ 3.1** (see `contentstack_utils.gemspec` and `.ruby-version` for local dev) | +| Build | **Bundler** + **RubyGems**; `contentstack_utils.gemspec`, `Gemfile` | +| Tests | **RSpec**; specs under `spec/**/*_spec.rb`, loaded via `spec/spec_helper.rb` | +| Lint / coverage | No RuboCop in-repo; **SimpleCov** in `spec/spec_helper.rb`; API docs via **YARD** (`.yardopts`, `rake yard`) | +| Runtime deps | **activesupport** (7.x), **nokogiri** (HTML / XML for legacy RTE strings) | + +## Commands (quick reference) + +| Command type | Command | +|--------------|---------| +| Install deps | `bundle install` | +| Build (default task) | `bundle exec rake` (runs **spec**) | +| Test | `bundle exec rake spec` or `bundle exec rspec` | +| Docs | `bundle exec rake yard` | + +**CI / automation:** There is no dedicated workflow that runs `rspec` on every push; local verification is `bundle exec rake`. Other workflows include branch checks (PRs into `master`), release publish, CodeQL, policy/SCA scans—see `.github/workflows/`. + +## Where the documentation lives: skills + +| Skill | Path | What it covers | +|-------|------|----------------| +| Code review | `skills/code-review/SKILL.md` | PR checklist for this gem | +| Contentstack Utils SDK | `skills/contentstack-utils/SKILL.md` | Public API, models, CDA vs GQL paths, versioning | +| Development workflow | `skills/dev-workflow/SKILL.md` | Branches, Bundler/Rake, gem build, workflows | +| Framework & packaging | `skills/framework/SKILL.md` | Gemspec, dependencies, Ruby version, release | +| Ruby style and layout | `skills/ruby-style/SKILL.md` | Module layout, naming, matching existing code | +| Testing | `skills/testing/SKILL.md` | RSpec layout, mocks, SimpleCov, WebMock | + +An index with “when to use” hints is in `skills/README.md`. + +## Using Cursor (optional) + +If you use **Cursor**, **`.cursor/rules/README.md`** is the only file under `.cursor/rules`; it points to **`AGENTS.md`**—same docs as everyone else. diff --git a/Gemfile.lock b/Gemfile.lock index 02cd067..2af12be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,31 +2,31 @@ PATH remote: . specs: contentstack_utils (1.2.3) - activesupport (>= 8.0) - nokogiri (>= 1.19) + activesupport (>= 7.0, < 8) + nokogiri (>= 1.13, < 1.19) GEM remote: https://rubygems.org/ specs: - activesupport (8.1.3) + activesupport (7.2.3.1) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) - json logger (>= 1.4.2) - minitest (>= 5.1) + minitest (>= 5.1, < 6) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) - uri (>= 0.13.1) - addressable (2.8.9) + addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) base64 (0.3.0) - bigdecimal (4.0.1) + benchmark (0.5.0) + bigdecimal (4.1.1) concurrent-ruby (1.3.6) - connection_pool (3.0.2) + connection_pool (2.5.5) crack (1.0.1) bigdecimal rexml @@ -36,15 +36,11 @@ GEM hashdiff (1.2.1) i18n (1.14.8) concurrent-ruby (~> 1.0) - json (2.19.3) logger (1.7.0) - minitest (6.0.2) - drb (~> 2.0) - prism (~> 1.5) - nokogiri (1.19.2-arm64-darwin) + minitest (5.27.0) + nokogiri (1.18.10-arm64-darwin) racc (~> 1.4) - prism (1.9.0) - public_suffix (7.0.5) + public_suffix (6.0.2) racc (1.8.1) rake (13.3.1) rexml (3.4.4) @@ -70,7 +66,6 @@ GEM simplecov_json_formatter (0.1.4) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - uri (1.1.1) webmock (3.26.2) addressable (>= 2.8.0) crack (>= 0.3.2) diff --git a/contentstack_utils.gemspec b/contentstack_utils.gemspec index 48d3db9..c8cb639 100644 --- a/contentstack_utils.gemspec +++ b/contentstack_utils.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.authors = [%q{Contentstack}] s.email = ["support@contentstack.com"] - s.required_ruby_version = '>= 3.0' + s.required_ruby_version = '>= 3.1' s.license = "MIT" s.homepage = "https://github.com/contentstack/contentstack-utils-ruby" @@ -21,8 +21,8 @@ Gem::Specification.new do |s| s.test_files = s.files.grep(%r{^spec/}) s.require_paths = ["lib"] - s.add_dependency 'activesupport', '>= 8.0' - s.add_dependency 'nokogiri', '>= 1.19' + s.add_dependency 'activesupport', '>= 7.0', '< 8' + s.add_dependency 'nokogiri', '>= 1.13', '< 1.19' s.add_development_dependency 'rake', '~> 13.0' s.add_development_dependency 'rspec', '~> 3.13' diff --git a/skills/README.md b/skills/README.md new file mode 100644 index 0000000..e7c9f68 --- /dev/null +++ b/skills/README.md @@ -0,0 +1,16 @@ +# Skills – Contentstack Utils Ruby + +Source of truth for detailed guidance. Read [AGENTS.md](../AGENTS.md) first, then open the skill that matches your task. + +## When to use which skill + +| Skill folder | Use when | +|--------------|----------| +| `code-review` | Preparing or reviewing a PR | +| `contentstack-utils` | Changing rendering behavior, JSON RTE / GQL paths, options API, or public `lib/` entry points | +| `dev-workflow` | Setting up the repo, running tests/docs, opening PRs, understanding CI and release | +| `framework` | Gemspec, Bundler, Ruby version constraints, activesupport/nokogiri dependencies, gem build/release | +| `ruby-style` | File layout, modules, or staying consistent with existing Ruby style in this repo | +| `testing` | Adding or changing specs, fixtures, mocks, or coverage | + +Each folder contains `SKILL.md` with YAML frontmatter (`name`, `description`). diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md new file mode 100644 index 0000000..2634370 --- /dev/null +++ b/skills/code-review/SKILL.md @@ -0,0 +1,44 @@ +--- +name: code-review +description: Use when reviewing or preparing a PR for this gem—behavior, tests, API compatibility, and release notes. +--- + +# Code review – Contentstack Utils Ruby + +## When to use + +- Authoring a pull request that changes rendering, models, or dependencies +- Reviewing someone else’s PR before merge +- Checking release readiness (version + changelog) + +## Instructions + +### Blockers (fix before merge) + +- **Tests:** `bundle exec rake` (or `bundle exec rspec`) passes locally +- **Breaking API:** unintended removal or signature change of public methods on **`ContentstackUtils`**, **`ContentstackUtils::GQL`**, or **`ContentstackUtils::Model::Options`** without version bump and changelog entry +- **Security:** no secrets in code, fixtures, or logs; HTML output changes reviewed for injection or XSS risk when embedding untrusted fields + +### Major (should address) + +- **CHANGELOG.md** updated for user-visible behavior fixes or features +- **`lib/contentstack_utils/version.rb`** updated when publishing a release (if this PR is release-bound) +- New JSON/RTE node types or GQL shapes covered by **`spec/lib/utils_spec.rb`** (or focused new spec files) +- Dependency range changes in **`contentstack_utils.gemspec`** justified and compatible with Ruby **≥ 3.1** + +### Minor (nice to have) + +- **README.md** examples match actual class names (**`Options`**, not a non-existent **`Option`** unless aliased) +- YARD or comments only where they clarify non-obvious RTE or GQL mapping + +### Process + +- Respect **CODEOWNERS** and branch policy (**`master`** vs **`staging`**) described in [dev-workflow](../dev-workflow/SKILL.md) + +## References + +- [AGENTS.md](../../AGENTS.md) +- [Development workflow](../dev-workflow/SKILL.md) +- [Contentstack Utils SDK](../contentstack-utils/SKILL.md) +- [Framework & packaging](../framework/SKILL.md) +- [Testing](../testing/SKILL.md) diff --git a/skills/contentstack-utils/SKILL.md b/skills/contentstack-utils/SKILL.md new file mode 100644 index 0000000..44471c0 --- /dev/null +++ b/skills/contentstack-utils/SKILL.md @@ -0,0 +1,51 @@ +--- +name: contentstack-utils +description: Use when changing the public Ruby API, RTE rendering (HTML string or JSON), GQL payloads, Model::Options/Metadata, or integration boundaries with the delivery client. +--- + +# Contentstack Utils SDK – Contentstack Utils Ruby + +## When to use + +- Implementing or fixing HTML output for rich text / JSON RTE +- Extending or subclassing rendering options (`ContentstackUtils::Model::Options`) +- Parsing GraphQL-shaped RTE (`ContentstackUtils::GQL`) +- Changing load paths or public entry points under `lib/` (gemspec and dependency ranges: see [framework](../framework/SKILL.md)) + +## Instructions + +### Entry points + +- **`lib/contentstack_utils.rb`** — requires version and `utils` +- **`lib/contentstack_utils/utils.rb`** — main module **`ContentstackUtils`** with class methods: + - **`render_content(content, options)`** — legacy HTML string RTE (array of strings or single string); uses Nokogiri and `_embedded_items` on the entry passed via options + - **`json_to_html(content, options)`** — JSON RTE document tree (Hash/Array) for CDA-style payloads with embedded items on the entry + - Internal helpers such as **`json_doc_to_html`** (used by GQL path) +- **`ContentstackUtils::GQL`** — **`json_to_html(content, options)`** for GraphQL responses: expects keys like `json` and optional `embedded_itemsConnection.edges`; reuses `ContentstackUtils.json_doc_to_html` with a GQL-specific reference resolver + +### Models and extension points + +- **`ContentstackUtils::Model::Options`** (`lib/contentstack_utils/model/options.rb`) — default **`render_option`**, **`render_mark`**, **`render_node`**; subclass for custom HTML (see tests under `spec/mock/custom_render_option.rb`) +- **`ContentstackUtils::Model::Metadata`** — built from DOM nodes (HTML path) or JSON reference nodes +- **`ContentstackUtils::Interface::Rendarable`** (`lib/contentstack_utils/interface/renderable.rb`) — base for options; implement **`render_option`** in subclasses + +### Data contracts + +- **CDA / delivery JSON path:** options may carry an **`entry`** hash with **`_embedded_items`** keyed by field UIDs +- **GQL path:** payload uses **`embedded_itemsConnection.edges`** with **`node`** objects; reference resolution matches **`metadata.item_uid`** to **`node.system.uid`** + +### Boundaries + +- HTTP and stack access belong to the separate **Contentstack Ruby** client; this gem only renders given content + embedded metadata + +### Versioning + +- Public API and behavior changes should be reflected in `CHANGELOG.md` and `lib/contentstack_utils/version.rb` + +## References + +- Product overview: [README.md](../../README.md) +- [Framework & packaging](../framework/SKILL.md) +- [Testing](../testing/SKILL.md) +- [Ruby style and layout](../ruby-style/SKILL.md) +- [Contentstack documentation](https://www.contentstack.com/docs/) diff --git a/skills/dev-workflow/SKILL.md b/skills/dev-workflow/SKILL.md new file mode 100644 index 0000000..fdd7813 --- /dev/null +++ b/skills/dev-workflow/SKILL.md @@ -0,0 +1,53 @@ +--- +name: dev-workflow +description: Use when setting up the dev environment, running build/test/docs, or understanding CI, branches, and gem release for this repo. +--- + +# Development workflow – Contentstack Utils Ruby + +## When to use + +- Cloning the repo or onboarding a new contributor +- Running tests, generating docs, or building the gem locally +- Understanding branch rules and GitHub Actions for this repository + +## Instructions + +### Prerequisites + +- Ruby **≥ 3.1** (matches `s.required_ruby_version` in `contentstack_utils.gemspec`) +- Bundler; install gems with `bundle install` + +### Everyday commands + +- **Run tests (default Rake task):** `bundle exec rake` or `bundle exec rake spec` +- **RSpec directly:** `bundle exec rspec` (pattern `spec/**/*_spec.rb` is configured in `Rakefile`) +- **YARD API docs:** `bundle exec rake yard` (see `.yardopts` for included paths) +- **Build gem artifact:** `gem build contentstack_utils.gemspec` (also used in `.github/workflows/release-gem.yml`) + +### Version and changelog + +- Gem version lives in `lib/contentstack_utils/version.rb` as `ContentstackUtils::VERSION` +- Document user-visible changes in `CHANGELOG.md` when releasing + +### Branches and PRs + +- `.github/workflows/check-branch.yml` blocks merging into **`master`** unless the head branch is **`staging`** (organizational policy). Prefer PRs that follow team conventions for `master` / `staging`. +- Use `CODEOWNERS` for required reviewers when applicable + +### CI and automation (no RSpec workflow today) + +- **Release:** `.github/workflows/release-gem.yml` — on GitHub **release created**, builds and pushes to RubyGems (note: workflow pins Ruby 2.7 for publish; align with gemspec minimum when changing) +- **Security / compliance:** CodeQL, policy scan, SCA scan — see `.github/workflows/` +- **Issues:** Jira integration workflow in `.github/workflows/issues-jira.yml` + +### Optional housekeeping + +- `.talismanrc` is used for secret scanning hooks in some environments; do not commit credentials or tokens + +## References + +- [AGENTS.md](../../AGENTS.md) +- [Contentstack Utils SDK](../contentstack-utils/SKILL.md) +- [Framework & packaging](../framework/SKILL.md) +- [Testing](../testing/SKILL.md) diff --git a/skills/framework/SKILL.md b/skills/framework/SKILL.md new file mode 100644 index 0000000..d102ad6 --- /dev/null +++ b/skills/framework/SKILL.md @@ -0,0 +1,44 @@ +--- +name: framework +description: Use when changing the gemspec, Bundler setup, Ruby/runtime constraints, or runtime dependencies (activesupport, nokogiri) and native extension implications. +--- + +# Framework & packaging – Contentstack Utils Ruby + +## When to use + +- Editing **`contentstack_utils.gemspec`** (dependencies, `required_ruby_version`, files list) +- Changing **`Gemfile`** / **`Gemfile.lock`** workflow or documenting install for contributors +- Evaluating impact of **nokogiri** (native extension) or **activesupport** version ranges on consumers + +## Instructions + +### Gem definition + +- **`contentstack_utils.gemspec`** — canonical metadata: `s.files` from `git ls-files`, `spec/` as test files, `lib` as `require_paths` +- **`Gemfile`** — `gemspec` only; runtime and development dependencies are declared in the gemspec + +### Runtime dependencies (as shipped) + +- **activesupport** `>= 7.0`, `< 8` +- **nokogiri** `>= 1.13`, `< 1.19` — HTML/XML parsing for legacy string RTE paths; consumers need a compatible platform build + +### Development dependencies + +- **rake**, **rspec**, **webmock**, **simplecov**, **yard** — see gemspec; used for tasks in `Rakefile` and CI-style local checks + +### Ruby version + +- **`s.required_ruby_version`** is **>= 3.1**; `.ruby-version` pins a team default for local dev +- **Release workflow** (`.github/workflows/release-gem.yml`) uses its own Ruby pin for `gem build` / `gem push`; keep it aligned with gemspec when updating + +### Build and publish + +- Local artifact: `gem build contentstack_utils.gemspec` +- Publishing is triggered by GitHub **release** per `release-gem.yml` + +## References + +- [Development workflow](../dev-workflow/SKILL.md) +- [Contentstack Utils SDK](../contentstack-utils/SKILL.md) +- [Ruby style and layout](../ruby-style/SKILL.md) diff --git a/skills/ruby-style/SKILL.md b/skills/ruby-style/SKILL.md new file mode 100644 index 0000000..cf62410 --- /dev/null +++ b/skills/ruby-style/SKILL.md @@ -0,0 +1,42 @@ +--- +name: ruby-style +description: Use when editing Ruby in this repo—module layout, require paths, and staying consistent with existing style (not introducing a new linter config). +--- + +# Ruby style and layout – Contentstack Utils Ruby + +## When to use + +- Adding new `.rb` files under `lib/` or `spec/` +- Refactoring while keeping diffs readable for reviewers +- Deciding where a new helper or model class should live + +## Instructions + +### Layout + +- **Library code:** `lib/contentstack_utils/` with nested folders `model/`, `interface/`, `support/` +- **Top-level require:** `lib/contentstack_utils.rb` should stay a thin loader +- **Specs:** mirror behavior under `spec/lib/` and `spec/mock/` / `spec/support/` as in existing examples + +### Conventions in this codebase + +- **`ContentstackUtils`** as the root module; nested **`Model`**, **`Interface`**, **`GQL`** as already used +- **`require_relative`** for internal lib files (see `utils.rb`, `options.rb`) +- Existing files use a mix of spacing and `def self.` patterns; **prefer matching the surrounding file** over wholesale reformatting +- Typo in base class name **`Rendarable`** is historical; new code should remain compatible unless a dedicated rename is approved project-wide + +### Linting and format + +- There is **no RuboCop or Standard** configuration in this repository; do not add large style-only churn unless the team adopts a formatter +- Run **`bundle exec rake spec`** before pushing substantive changes + +### Documentation + +- YARD can document public APIs; keep user-facing usage examples in `README.md` accurate (e.g. class name **`Options`** vs informal “Option” in prose) + +## References + +- [Contentstack Utils SDK](../contentstack-utils/SKILL.md) +- [Framework & packaging](../framework/SKILL.md) +- [Development workflow](../dev-workflow/SKILL.md) diff --git a/skills/testing/SKILL.md b/skills/testing/SKILL.md new file mode 100644 index 0000000..7d6fccf --- /dev/null +++ b/skills/testing/SKILL.md @@ -0,0 +1,45 @@ +--- +name: testing +description: Use when writing or fixing RSpec tests, mocks, fixtures, SimpleCov filters, or WebMock usage in this repo. +--- + +# Testing – Contentstack Utils Ruby + +## When to use + +- Adding coverage for a new code path in `lib/` +- Debugging a failing spec in `spec/` +- Adjusting SimpleCov scope or shared test helpers + +## Instructions + +### Runner and config + +- **RSpec** is the test framework; **`spec/spec_helper.rb`** loads SimpleCov, then `contentstack_utils`, mocks, and support files +- **Default task:** `bundle exec rake` runs **`spec`** with `--format documentation` (see `Rakefile`) + +### Layout + +- **`spec/lib/`** — primary examples (`utils_spec.rb`, `model/option_spec.rb`, `model/metadata_spec.rb`) +- **`spec/mock/`** — constants and custom option subclasses used across examples +- **`spec/support/`** — helpers (e.g. XML/JSON fixture builders like `getGQLJSONRTE`) + +### Coverage + +- **SimpleCov** starts in `spec_helper.rb` and **filters** `spec/` and `lib/contentstack_utils/support` from coverage metrics +- Aim to cover both **HTML `render_content`** paths and **JSON / GQL `json_to_html`** branches when changing `utils.rb` + +### HTTP and external I/O + +- **webmock** is a development dependency; stub outbound HTTP if future tests introduce network calls (current suite is largely pure parsing/rendering) + +### Credentials + +- Do not add real API keys, delivery tokens, or stack secrets to the repo; use fixture hashes and constants as in `spec/mock/` and `spec/support/constant.rb` + +## References + +- [Development workflow](../dev-workflow/SKILL.md) +- [Contentstack Utils SDK](../contentstack-utils/SKILL.md) +- [RSpec](https://rspec.info/) +- [SimpleCov](https://github.com/simplecov-ruby/simplecov)