Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .claude/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
plans/
skills/
commands/
agents/
hooks/
44 changes: 44 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Go implementation of [JSON Pointer (RFC 6901)](https://datatracker.ietf.org/doc/html/rfc6901) for navigating
and mutating JSON documents represented as Go values. Unlike most implementations, it works not only with
`map[string]any` and slices, but also with Go structs (resolved via `json` struct tags and reflection).

See [docs/MAINTAINERS.md](../docs/MAINTAINERS.md) for CI/CD, release process, and repo structure details.

### Package layout (single package)

| File | Contents |
|------|----------|
| `pointer.go` | Core types (`Pointer`, `JSONPointable`, `JSONSetable`), `New`, `Get`, `Set`, `Offset`, `Escape`/`Unescape` |
| `errors.go` | Sentinel errors: `ErrPointer`, `ErrInvalidStart`, `ErrUnsupportedValueType` |

### Key API

- `New(string) (Pointer, error)` — parse a JSON pointer string (e.g. `"/foo/0/bar"`)
- `Pointer.Get(document any) (any, reflect.Kind, error)` — retrieve a value
- `Pointer.Set(document, value any) (any, error)` — set a value (document must be pointer/map/slice)
- `Pointer.Offset(jsonString string) (int64, error)` — byte offset of token in raw JSON
- `GetForToken` / `SetForToken` — single-level convenience helpers
- `Escape` / `Unescape` — RFC 6901 token escaping (`~0` ↔ `~`, `~1` ↔ `/`)

Custom types can implement `JSONPointable` (for Get) or `JSONSetable` (for Set) to bypass reflection.

### Dependencies

- `github.com/go-openapi/swag/jsonname` — struct tag → JSON field name resolution
- `github.com/go-openapi/testify/v2` — test-only assertions

### Notable historical design decisions

See also .claude/plans/ROADMAP.md.

- Struct fields **must** have a `json` tag to be reachable; untagged fields are ignored
(differs from `encoding/json` which defaults to the Go field name).
- Anonymous embedded struct fields are traversed only if tagged.
- The RFC 6901 `"-"` array suffix (append) is **not** implemented.

10 changes: 10 additions & 0 deletions .claude/rules/go-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
paths:
- "**/*.go"
---

# Code conventions (go-openapi)

- All files must have SPDX license headers (Apache-2.0).
- Go version policy: support the 2 latest stable Go minor versions.
- Commits require DCO sign-off (`git commit -s`).
17 changes: 17 additions & 0 deletions .claude/rules/linting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
paths:
- "**/*.go"
---

# Linting conventions (go-openapi)

```sh
golangci-lint run
```

Config: `.golangci.yml` — posture is `default: all` with explicit disables.
See `docs/STYLE.md` for the rationale behind each disabled linter.

Key rules:
- Every `//nolint` directive **must** have an inline comment explaining why.
- Prefer disabling a linter over scattering `//nolint` across the codebase.
47 changes: 47 additions & 0 deletions .claude/rules/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
paths:
- "**/*_test.go"
---

# Testing conventions (go-openapi)

## Running tests

**Single module repos:**

```sh
go test ./...
```

**Mono-repos (with `go.work`):**

```sh
# All modules
go test work ./...

# Single module
go test ./conv/...
```

Note: in mono-repos, plain `go test ./...` only tests the root module.
The `work` pattern expands to all modules listed in `go.work`.

CI runs tests on `{ubuntu, macos, windows} x {stable, oldstable}` with `-race` via `gotestsum`.

## Fuzz tests

```sh
# List all fuzz targets
go test -list Fuzz ./...

# Run a specific target (go test -fuzz cannot span multiple packages)
go test -fuzz=Fuzz -run='FuzzTargetName$' -fuzztime=1m30s ./package
```

Fuzz corpus lives in `testdata/fuzz/` within each package. CI runs each fuzz target for 1m30s
with a 5m minimize timeout.

## Test framework

`github.com/go-openapi/testify/v2` — a zero-dep fork of `stretchr/testify`.
Because it's a fork, `testifylint` does not work.
181 changes: 0 additions & 181 deletions .cliff.toml

This file was deleted.

1 change: 1 addition & 0 deletions .github/copilot
47 changes: 47 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copilot Instructions

## Project Overview

Go implementation of [JSON Pointer (RFC 6901)](https://datatracker.ietf.org/doc/html/rfc6901) for navigating
and mutating JSON documents represented as Go values. Works with `map[string]any`, slices, and Go structs
(resolved via `json` struct tags and reflection).

## Package Layout (single package)

| File | Contents |
|------|----------|
| `pointer.go` | Core types (`Pointer`, `JSONPointable`, `JSONSetable`), `New`, `Get`, `Set`, `Offset`, `Escape`/`Unescape` |
| `errors.go` | Sentinel errors: `ErrPointer`, `ErrInvalidStart`, `ErrUnsupportedValueType` |

## Key API

- `New(string) (Pointer, error)` — parse a JSON pointer string (e.g. `"/foo/0/bar"`)
- `Pointer.Get(document any) (any, reflect.Kind, error)` — retrieve a value
- `Pointer.Set(document, value any) (any, error)` — set a value (document must be pointer/map/slice)
- `Pointer.Offset(jsonString string) (int64, error)` — byte offset of token in raw JSON
- `GetForToken` / `SetForToken` — single-level convenience helpers
- `Escape` / `Unescape` — RFC 6901 token escaping (`~0` ↔ `~`, `~1` ↔ `/`)

Custom types can implement `JSONPointable` (for Get) or `JSONSetable` (for Set) to bypass reflection.

## Design Decisions

- Struct fields **must** have a `json` tag to be reachable; untagged fields are ignored.
- Anonymous embedded struct fields are traversed only if tagged.
- The RFC 6901 `"-"` array suffix (append) is **not** implemented.

## Dependencies

- `github.com/go-openapi/swag/jsonname` — struct tag to JSON field name resolution
- `github.com/go-openapi/testify/v2` — test-only assertions (zero-dep fork of `stretchr/testify`)

## Conventions

- All `.go` files must have SPDX license headers (Apache-2.0).
- Commits require DCO sign-off (`git commit -s`).
- Linting: `golangci-lint run` — config in `.golangci.yml` (posture: `default: all` with explicit disables).
- Every `//nolint` directive **must** have an inline comment explaining why.
- Tests: `go test ./...` with `-race`. CI runs on `{ubuntu, macos, windows} x {stable, oldstable}`.
- Test framework: `github.com/go-openapi/testify/v2` (not `stretchr/testify`).

See `.github/copilot/` (symlinked to `.claude/rules/`) for detailed rules on Go conventions, linting, and testing.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
.idea
.env
.mcp.json
.claude/
Loading