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
85 changes: 85 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# AGENTS.md

Guidance for AI coding agents working in this repository. Human contributors
should read [CONTRIBUTING.md](CONTRIBUTING.md); this file is the machine-facing
counterpart.

## What this project is

`gtoc` is a single-binary CLI, written in Go, that generates and maintains a
table of contents in Markdown files. It reads the headings of a file, builds a
hierarchical index with GitHub-compatible anchors, and writes it back between
HTML markers — idempotently.

Module path: `github.com/lpsm-dev/gtoc`.

## Layout

| Path | Responsibility |
| ------------------------ | ------------------------------------------------------------- |
| `main.go` | Entry point; delegates to `cmd.Execute`. |
| `cmd/` | Cobra commands: `generate`, `analyze`, `upgrade`, `version`. |
| `internal/generator/` | Heading extraction, anchor slugging, TOC assembly and file update. Pure, well-tested core. |
| `internal/logger/` | Thin wrapper over `charm.land/log/v2`. |
| `.github/workflows/` | CI (`ci.yaml`), release (`goreleaser.yaml`, `_release.yaml`). |

The `generate` command enumerates headings into a TOC; the `analyze` command
adds README best-practice markers and a "back to top" link at the end of each
top-level (`#`) section. The `upgrade` command self-updates from GitHub
releases.

## Build, test, lint

The project uses [Task](https://taskfile.dev) and [Devbox](https://www.jetify.com/devbox),
but plain `go` works everywhere. Prefer the raw commands in automation:

```bash
go build ./... # or: task go:build
go test ./... # or: task go:test
go vet ./... # or: task go:vet
gofmt -l cmd internal # must print nothing
golangci-lint run ./... # or: task go:lint
```

`task go:all` runs fmt, vet, lint, test and build in sequence.

## Non-negotiable rules

- **Cyclomatic complexity ≤ 10 per function.** Enforced by `golangci-lint`
(`gocyclo`, `min-complexity: 10` in `.golangci.yml`). New code must comply;
do not raise the threshold.
- **Functions ≤ 100 lines**, prefer small single-purpose helpers.
- **All code, comments and identifiers in English.**
- **`gofmt`-clean, `go vet`-clean, zero linter warnings.**
- **Tests must stay green** (`go test ./...`) and new behavior needs new tests.
The `internal/generator` package is the core — keep its coverage high.
- **No unnecessary dependencies.** The core uses only the standard library.
- **Anchors follow GitHub's github-slugger algorithm**: preserve Unicode
letters/accents, do not collapse consecutive hyphens, and suffix duplicate
slugs with `-1`, `-2`, … Changing this breaks existing anchors — add a test
first.
- **Go module major bumps (v2+) are not routine.** Charm modules relocate their
import path on major versions (e.g. `charm.land/glamour/v2`), so a bare
`go.mod` bump breaks the build. Update the import sites and verify a full
build before merging.

## Commits and releases

- **Conventional Commits**: `type(scope): description`, lowercase, imperative,
no trailing period. Types: `feat`, `fix`, `refactor`, `docs`, `test`,
`chore`, `ci`, `perf`. Breaking changes use `feat!:` or a `BREAKING CHANGE:`
footer.
- Keep commits small and single-concern.
- Releases are driven by `semantic-release` and GoReleaser off `main`; never
hand-edit the changelog.

## Definition of done

Before proposing a change as complete, confirm locally:

1. `go build ./...` succeeds.
2. `go test ./...` passes.
3. `go vet ./...` and `gofmt -l cmd internal` are clean.
4. `golangci-lint run ./...` reports no issues (complexity included).
5. If the change affects TOC output, regenerate this repo's `README.md` with
the built binary to confirm behavior end to end.
20 changes: 20 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# CLAUDE.md

This file guides Claude Code (and other Claude-based agents) when working in
this repository. The full, tool-agnostic contribution guidance lives in
[AGENTS.md](AGENTS.md); this file imports it so both stay in sync.

@AGENTS.md

## Claude-specific notes

- Treat the rules in `AGENTS.md` as hard constraints, not suggestions — in
particular the cyclomatic-complexity ≤ 10 guardrail and the GitHub-compatible
anchor algorithm.
- Prefer editing `internal/generator` behavior behind its existing tests: change
a test to describe the new behavior first, then make it pass.
- After any change that affects TOC output, dogfood it: build the binary and run
`gtoc generate README.md` to verify the real result, not just unit tests.
- When touching dependencies, remember Go v2+ modules may move their import path
(e.g. `charm.land/glamour/v2`, `charm.land/log/v2`); update imports and run a
full `go build ./...` before concluding.
52 changes: 52 additions & 0 deletions llms.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# gtoc

> gtoc is a single-binary Go CLI that generates and maintains a table of
> contents in Markdown files. It reads a file's headings, builds a hierarchical
> index with GitHub-compatible anchors (Unicode/accents preserved, duplicate
> headings suffixed `-1`, `-2`, …), and writes it back between HTML markers,
> idempotently.

The tool targets README and documentation upkeep: instead of maintaining a
table of contents by hand, `gtoc generate <file>` rebuilds it from the actual
headings. A companion `gtoc analyze` command adds README best-practice markers
and a "back to top" link at the end of every top-level section, and
`gtoc upgrade` self-updates the binary from GitHub releases.

Module path: `github.com/lpsm-dev/gtoc`. Language: Go (1.25+). License: see
[LICENSE](LICENSE).

## Commands

- `generate [file]`: rebuild the TOC for a Markdown file. Flags: `--file`,
`--depth` (max heading level, 0 = unlimited), `--exclude` (comma-separated
heading texts, case-insensitive substring), `--dry-run`, `--pretty`.
- `analyze`: add `BEGIN_DOCS`/`END_DOCS` markers, a `readme-top` anchor, and a
"back to top" link after each `#` section. Flag: `--file` (default
`README.md`).
- `upgrade`: download and install the latest GitHub release for the current
OS/arch, verifying the published SHA-256 checksum. Flags: `--force`,
`--endpoint`.
- `version`: print the binary version and Go/OS/arch build info.

## Documentation

- [README.md](README.md): overview, installation and usage (Portuguese).
- [README_en.md](README_en.md): the same, in English.
- [CONTRIBUTING.md](CONTRIBUTING.md): human contributor guide.
- [AGENTS.md](AGENTS.md): guidance and hard constraints for AI coding agents.

## Source

- [main.go](main.go): entry point.
- [cmd/](cmd): Cobra command definitions (`generate`, `analyze`, `upgrade`, `version`).
- [internal/generator/generator.go](internal/generator/generator.go): heading
extraction, GitHub-compatible anchor slugging, and TOC assembly — the core
logic, and the best starting point for understanding the tool.
- [internal/logger/logger.go](internal/logger/logger.go): logging wrapper.

## Conventions

- Conventional Commits; releases via semantic-release and GoReleaser off `main`.
- Cyclomatic complexity ≤ 10 per function, enforced by golangci-lint (gocyclo).
- Standard-library-only core; GitHub-compatible anchors must not change without
a test.