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
421 changes: 421 additions & 0 deletions .agents/guidelines/english-style.md

Large diffs are not rendered by default.

97 changes: 97 additions & 0 deletions .agents/guidelines/project-owned-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Project-owned files

## Rule for this repository

This repository has no `.gitmodules`, so it has no submodule contents or
`config`-distributed files to exclude. Treat every tracked path as
project-owned, including root documentation, `.agents/`, `.github/`,
`scripts/`, `showcase/`, and `test/resources/`.

Do not apply the reusable skip rules below in this repository.

## Why ownership matters

Some skills edit or stamp files across a whole repository. For example,
`proofread` rewrites prose. These skills must touch only the files the
repository **owns**. Editing an upstream file is worse than a no-op: the
next `./config/pull` (or submodule update) overwrites the change or turns it
into a merge conflict, and the same edit is needed again.

This page defines *project-owned* and the two kinds of upstream-owned paths to
skip. Each consuming skill applies the rule to its file types; this page defines
the shared mechanism, while the file filter remains in the consuming skill.

## Reusable rules for repositories with submodules

Apply these rules only when `.gitmodules` declares the relevant submodule.
Determine submodule ownership from `.gitmodules`, never from a directory name.
A repository does **not** own the two kinds of tracked files below. Skip them
in every mode: full sweeps, scoped sweeps, and incremental branch-diff runs alike.

### 1. Submodule contents

Skip every path declared as a submodule in `.gitmodules`, and everything
beneath it — the `config` submodule (usually `config/`), the shared-agents
submodule at `.agents/shared`, and any others a repo adds (for example
`BuildSpeed/`, or example projects mounted under `docs/`).

When a skill enumerates files with `git ls-files`, submodules are already
excluded — a submodule appears to the parent repo as a single gitlink, not
as its files. Apply the skip explicitly anyway, so a diff-based run (which
lists changed *paths*) drops a submodule entry the same way.

### 2. Files distributed by the `config` repository

When a repository consumes `config` (its `.gitmodules` declares a submodule
with `path = config`), `config`'s `migrate` step copies shared files *out
of* the submodule into the project tree, where they become ordinary tracked
files. `git ls-files` and `git diff` therefore surface them even though the
project does not own them, and `./config/pull` overwrites them on every pull.

Skip the config-distributed set below. A consuming skill only encounters
the members that match its own file filter — a prose skill meets the
Markdown and source members; a header-stamping skill meets the
copyright-bearing members — so each skill skips the relevant subset without
needing its own copy of this list.

- **`buildSrc/`** — the entire Gradle build-logic tree (hundreds of Kotlin
files with KDoc); by far the largest source of false edits.
**Exception:** `buildSrc/src/main/kotlin/module.gradle.kts` is
project-owned — `migrate` saves and restores it, so `./config/pull` never
overwrites it. Only that exact file is project-owned; its
`*-module.gradle.kts` siblings (for example `jvm-module.gradle.kts`) *are*
distributed and stay skipped.
- **Root documentation** — `AGENTS.md`, `CLAUDE.md`, `CODE_OF_CONDUCT.md`.
- **Root configuration** — `gradle.properties`, `.codecov.yml`, `lychee.toml`.
- **Agent and IDE files** — `.junie/guidelines.md`,
`.github/copilot-instructions.md`, and `.idea/`.
- **`.github/workflows/<name>`** when the `config` submodule carries a
workflow of the same basename in its `.github/workflows/` (or
`.github-workflows/`) directory. Repo-specific workflows — including
variants that replace a distributed workflow via a `config:replaces`
directive and so ship under a different basename — stay project-owned.
When the submodule is not checked out, the comparison is impossible; treat
the workflow as project-owned.
- **`CONTRIBUTING.md`** only when it is the unmodified org-wide copy —
byte-for-byte identical to the submodule's `config/CONTRIBUTING.md`.
`config` writes it **only into a repo that lacks one** (an
*initialize if absent* step), so a repo shipping its own contributor
guide owns it. If it differs, or the `config` submodule is not checked
out so you cannot confirm, treat it as project-owned.

This set mirrors what `config`'s `migrate` script copies. If that script
changes what it distributes, update this page (and any skill that encodes
the set in a script) to match.

## The `config` and `agents` source repositories

The `config` and `agents` repositories declare no `config` submodule, so rule 2
is inert there: their own `AGENTS.md`, `buildSrc/`, `gradle.properties`, and the
rest are project-owned and stay in scope. This is correct: a fix or stamp must
originate at the source that floats to every consumer.

Do **not** instead skip a path merely because a same-named file exists
under the `config/` submodule. `config` carries files it does *not*
distribute (for example its own `README.md`), and skipping by name would
wrongly exclude a project's own `README.md`.

2 changes: 2 additions & 0 deletions .agents/skills/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ the routing source of truth.
- `writer`: documentation authoring, editing, restructuring, and claim checks.
- `review-docs`: documentation review for prose, examples, comments, and
agent instructions.
- `proofread`: English grammar, punctuation, and spelling fixes in
project-owned comments and documentation.
134 changes: 134 additions & 0 deletions .agents/skills/proofread/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
name: proofread
description: >-
Use when proofreading project-owned comments or documentation for English
grammar, punctuation, and spelling. Follow the shared English catalog,
preserve code and machine-read text, and report ambiguous cases instead of guessing.
---

# Proofread

Fix English-language errors in the prose of comments and documentation,
applying the catalog in `.agents/guidelines/english-style.md`. That
guideline is the single source of truth for *what* is an error and *when*
to leave an occurrence alone; this skill is the *how* — scoping, scanning,
and reporting. Do not restate or reinterpret the catalog's rules; follow them.

The guiding bias is the catalog's own: **a missed error is cheaper than a
wrong fix.** When a fix is not clearly correct, leave the text and report it.

## Workflow

1. **Choose the mode from the caller's argument.**
- **No argument → branch-diff mode.** Scan only the files changed on the
current branch, *including uncommitted and brand-new edits* — agents
here often work before an explicit commit, so a committed-only diff
would miss the very comments under review. Resolve a base ref, then take
the union of three lists:
- `git diff --name-only --diff-filter=ACMR <base>...HEAD` — committed
changes since the branch diverged from `<base>` (three-dot, not a
tip-to-tip diff);
- `git diff --name-only --diff-filter=ACMR HEAD` — staged and unstaged
edits to tracked files; and
- `git ls-files --others --exclude-standard` — untracked, non-ignored
files (brand-new prose not yet `git add`ed).

Resolve `<base>` to the first ref that exists: `origin/master`, else
`master`. `origin/master` is the base used across this repo's skills and
resolves in most clones and CI; the `master` fallback covers a checkout
that fetched only `master` with no remote-tracking ref. If neither
resolves, use the two working-tree lists alone and note the missing base
in the report. `--diff-filter=ACMR` excludes deleted paths, so step 3
never reads a file that no longer exists.
On a stacked branch, this fallback can include changes inherited from a
parent branch. Use path mode when a path cleanly isolates this branch's
prose; otherwise review the expanded file list before editing.
- **Argument is exactly `all` → full-sweep mode.** Scan every
project-owned file in the repository. Enumerate candidates with
`git ls-files`. (To scope a directory literally named `all`, pass it
as `./all`.)
- **Argument is a path → scoped-sweep mode.** Scan the project-owned
files under that directory or file: `git ls-files -- <path>`. Use this
to stage a full sweep over a very large repository one module at a time.

2. **Identify target files.** Apply this file-type filter in every mode:
- `**/*.kt`, `**/*.kts`, `**/*.java` — Kotlin and Java
- `**/*.proto` — Protobuf
- `**/*.ts`, `**/*.tsx`, `**/*.js`, `**/*.jsx`, `**/*.mjs`, `**/*.cjs`
— TypeScript and JavaScript
- `**/*.go` — Go
- `**/*.md` — Markdown
- `**/*.adoc` — AsciiDoc

In full-sweep and scoped-sweep modes, scan **git-tracked files only**:
`git ls-files` lists tracked files, so untracked build output and ignored
artifacts stay out; as a safeguard, also drop any `build/` and `.gradle/`
paths explicitly. In branch-diff mode, the step-1 list already includes
untracked, non-ignored files (new prose not yet `git add`ed) alongside tracked
changes. Keep them, then intersect the whole list with the file-type filter.

**Apply the repository-specific ownership conclusion.** This repository has
no `.gitmodules`, so it has no project-ownership exclusions. Keep every
candidate that survives the file filter, including root documentation,
agent guidance, showcase pages, test fixtures, and eligible Go source files.

If this skill is reused in another repository, follow
`.agents/guidelines/project-owned-files.md`. Drop submodule contents only
when `.gitmodules` declares them, and drop `config`-distributed files only
when `.gitmodules` declares the `config` submodule.

3. **Scan and fix each file.** Restrict edits to **prose only**, per the
“Where English prose lives” and “Never edit” sections of
`.agents/guidelines/english-style.md`:
- In `.kt`, `.kts`, `.java`, `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`,
`.cjs`, `.go`, and `.proto` files, edit only comment text — KDoc,
Javadoc, TSDoc, JSDoc, Go doc comments, block comments, and line
comments. Leave every string literal, identifier, and executable token untouched.
- In `.md` and `.adoc` files, edit only body prose and headings.
- In both, skip every code form (fenced and inline code, `{@code}` /
`<pre>` blocks, `@sample` references) and every machine-read comment
directive named under “Never edit” — Go pragmas (`//go:…`, `// +build`,
`Deprecated:`, the leading identifier of a doc comment), TS/JS
directives (`// @ts-…`, `// eslint-…`, `// prettier-ignore`, coverage
and webpack magic comments, triple-slash references), Protobuf
`// buf:lint:ignore`, Kotlin/Java `//noinspection` and doc-link
targets, copyright headers, and the machine-read TODO prefix.

Within the prose, apply **every topic** in the catalog's error catalog,
making the fix only when no leave-alone guard for that topic matches.
Keep edits minimal — the smallest change that fixes the error, preserving
the author's wording and voice. Apply per-file consistency (spelling
dialect, serial comma) as the catalog's principle 5 specifies.

Apply edits in place, file by file, batching a file's occurrences into
one edit per file rather than one edit per occurrence.

**When uncertain** whether a given occurrence is an error, leave it
unchanged and add it to `Skipped[]` with the catalog topic and reason
`ambiguous` (see **Report**).

4. **Report.** Produce the summary in the **Report** section below.

## Repo notes

- The catalog and its rationale live in `.agents/guidelines/english-style.md`;
the project-owned scoping lives in `.agents/guidelines/project-owned-files.md`.
This skill adds no independent rules.
- Prefer a missed case over a wrong fix. If a sentence is ambiguous, record
it in `Skipped[]` and let a human decide.
- For large repositories in full-sweep mode, process files directory by
directory to stay within context limits. The path argument stages the
same work across sessions.

## Report

Return:

- `Mode` — `branch-diff` | `all` | `path:<dir>`
- `FilesScanned`, `FilesChanged`
- `Changes[]` grouped by catalog topic; each entry: file, line, before → after
- `Skipped[]` — file, line, catalog topic, reason (usually `ambiguous`)

Grouping `Changes[]` by catalog topic is the learning loop: it shows which
error classes recur, which feeds back into the catalog.

9 changes: 9 additions & 0 deletions .agents/skills/proofread/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface:
display_name: "Proofread"
short_description: "Proofread comments and docs against the English catalog"
default_prompt: >-
Use $proofread to fix English grammar, punctuation, and spelling errors in
the comments and documentation of this repository. Pass `all` for a full
sweep, a path to scope the review, or no argument to check the current
branch's changes.

14 changes: 14 additions & 0 deletions .claude/commands/proofread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
description: >
Fix English grammar, punctuation, and spelling errors in the comments and
documentation of this repository, per the shared error catalog.
argument-hint: "[all | <path>]"
allowed-tools: >-
Read, Edit, Grep, Glob, Bash(git diff:*), Bash(git ls-files:*),
Bash(git status:*), Bash(cmp:*)
model: sonnet
---

Follow the [proofread skill](../../.agents/skills/proofread/SKILL.md) exactly,
passing `$ARGUMENTS` as its argument.

2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ agent operating policy and repository-wide rules.
- Read [PROJECT.md](PROJECT.md) for the project overview and project map.
- Use matching discovered skills when they are available. Each skill's
frontmatter is the routing source of truth.
- Run `golangci-lint run ./...` before handing off any workspace changes. Do
not consider a task complete while the linter reports failures.
- Ask clarifying questions before implementation, review, or documentation work
when scope, acceptance criteria, or constraints are not explicit.
- Never create commits, push, tag, merge, rebase, cherry-pick, or rewrite Git
Expand Down
5 changes: 5 additions & 0 deletions PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ them inside code fences, and checks whether existing snippets are up-to-date.
- `PROJECT.md`: project map, package ownership, documentation ownership, and CI
notes for contributors and agents.
- `AGENTS.md`: repository operating policy for agents.
- `.agents/skills/`: repository-specific implementation, testing, writing,
review, and proofreading workflows.
- `.agents/guidelines/`: shared English-language and file-ownership rules
used by repository skills.
- `.claude/commands/`: thin command delegates to repository skills.

Keep usage details in the showcase. Keep architecture and ownership details in
this file. Keep the root README short.
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ require a language compiler or parser.
## Gradle Plugin

Gradle users can apply the [Embed Code Gradle plugin][gradle-plugin] to download
the released executable for their platform and add tasks that check and embed
the released executable for their platform and add tasks that check and embed
code snippets.

## Download

Download the asset for your platform from [GitHub Releases][releases].
Download the asset for your platform from [GitHub Releases][releases].
You do not need to install Go to use a release binary.

| Platform | Release asset | Executable |
Expand All @@ -101,15 +101,15 @@ You do not need to install Go to use a release binary.

## Build From Source

Using Embed Code does not require Go.
Using Embed Code does not require Go.
To build the application from this repository, install Go `1.26.4` and run:

```bash
go build -trimpath -o embed-code main.go
```

This creates an executable named `embed-code`.
On Windows, use`-o embed-code.exe` to give it the standard `.exe` suffix.
This creates an executable named `embed-code`.
On Windows, use `-o embed-code.exe` to give it the standard `.exe` suffix.
The `-trimpath` flag prevents local absolute paths from appearing in stack traces.

You can also run the application directly from the source checkout:
Expand Down
4 changes: 2 additions & 2 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import (

// Config contains user-specified embed-code settings.
type Config struct {
// BaseCodePaths contains directories with source code files.
// BaseCodePaths contains directories with source-code files.
BaseCodePaths _type.NamedPathList `yaml:"code-path"`

// BaseDocsPath is the root directory containing documentation files.
Expand Down Expand Up @@ -82,7 +82,7 @@ type EmbeddingConfig struct {
// Name identifies the embedding target.
Name string `yaml:"name"`

// CodePaths contains directories with source code files.
// CodePaths contains directories with source-code files.
CodePaths _type.NamedPathList `yaml:"code-path"`

// DocsPath is the root directory containing documentation files.
Expand Down
2 changes: 1 addition & 1 deletion cli/cli_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import (
// IllegalFolderNameChars contains characters that are not allowed in folder names.
const IllegalFolderNameChars = `/\ *?:"<>|`

// IsUsingConfigFile reports whether user configs are set with file.
// IsUsingConfigFile reports whether user configs are set with a file.
//
// Parameters:
// config - provides user CLI settings.
Expand Down
2 changes: 1 addition & 1 deletion configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var DefaultDocIncludes = []string{"**/*.md", "**/*.html"}
// Configuration contains embed-code processing settings.
//
// It is used to get data for scanning docs and resolving source files.
// The example of creating the Configuration with default values:
// An example of creating the Configuration with default values:
//
// var config = configuration.NewConfiguration()
type Configuration struct {
Expand Down
2 changes: 1 addition & 1 deletion embedding/commentfilter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (

// EmbeddingCommentFilter filters comments for one embed-code instruction.
type EmbeddingCommentFilter struct {
// filePath is the path to the source code file.
// filePath is the path to the source-code file.
filePath string

// embeddingDocPath is the path to the documentation containing the instruction.
Expand Down
2 changes: 1 addition & 1 deletion embedding/parsing/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

package parsing

// EmbeddingTag is a name of a tag which marks where to embed the code.
// EmbeddingTag is a name of a tag that marks where to embed the code.
const EmbeddingTag = "embed-code"

// TransitionMap is a type for mapping one State to a list of possible next States.
Expand Down
2 changes: 1 addition & 1 deletion embedding/parsing/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
"embed-code/embed-code-go/configuration"
)

// State represent a transition of a single line in the parsing process.
// State represents a transition of a single line in the parsing process.
type State interface {

// Accept updates the parsing context based on the transition.
Expand Down
2 changes: 1 addition & 1 deletion embedding/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func newProcessor(
}
}

// Embed constructs embedding and modifies the doc file if embedding is needed.
// Embed constructs an embedding and modifies the doc file if embedding is needed.
//
// Returns:
// *parsing.Context - parsing context, empty when the file is excluded by configuration.
Expand Down
2 changes: 1 addition & 1 deletion files/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func IsDirExist(path string) (bool, error) {
return false, nil
}

// Reports whether the given path is valid and exist in the file system. Also returns a FileInfo if
// Reports whether the given path is valid and exists in the file system. Also returns a FileInfo if
// the path (relative or absolute) exists.
func validatePathExists(path string) (bool, os.FileInfo, error) {
// Getting matches for the given path if it is a glob format. Otherwise, does nothing.
Expand Down
Loading
Loading