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
4 changes: 4 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
^pkgdown$
^principles\.md$
^exploration$
^data-raw$
^\.positai$
^\.claude$
^AGENTS\.md$
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When reviewing pull requests, do not review `man/*.Rd`.
117 changes: 117 additions & 0 deletions .github/skills/create-issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
name: create-issue
trigger: create GitHub issues
description: Creates GitHub issues for the package repository. Use when asked to create, file, or open a GitHub issue, or when planning new features or functions that need to be tracked.
compatibility: Requires the `gh` CLI and an authenticated GitHub session.
---

# Create a GitHub issue

Use `gh api graphql` with the `createIssue` mutation to create issues. This sets the issue type in a single step. Write the body to a temp file first, then pass it via `$(cat ...)`.

If `gh` is not authenticated, stop and ask the user to authenticate before continuing.

## Looking up IDs

The hardcoded IDs below are correct for this repo as of 2026-04-28 13:47:49 UTC. If they ever change, or if you're working in a fork, re-run these queries to get fresh values:

```bash
# Repository node ID
gh api graphql -f query='{ repository(owner: "jonthegeek", name: "rapid") { id } }'

# Available issue type IDs
gh api graphql -f query='{ repository(owner: "jonthegeek", name: "rapid") { issueTypes(first: 20) { nodes { id name description } } } }'
```

## Issue type

Choose the type that best fits the issue:

| Type | ID | Use for |
|---|---|---|

## Issue title

Titles use conventional commit prefixes:

- `feat: my_function()` — new exported function or feature
- `fix: short description` — bug fix
- `docs: short description` — documentation
- `chore: short description` — maintenance or task

## Issue body structure

Which sections to include depends on the issue type:

| Section | Feature | Bug | Documentation | Task |
|---|---|---|---|---|
| `## Summary` | ✓ | ✓ | ✓ | ✓ |
| `## Details` | optional | optional | optional | optional |
| `## Proposed signature` | ✓ | — | — | — |
| `## Behavior` | ✓ | ✓ | — | — |
| `## References` | optional | optional | optional | optional |

### `## Summary` (all types)

A single user story sentence (no other content in this section):

```markdown
> As a [role], in order to [goal], I would like to [feature].
```

Example:

```markdown
## Summary

> As a package developer, in order to set up agent skills quickly, I would like to generate a skill template from a single function call.
```

### `## Details` (optional, all types)

For information that's important to capture but doesn't fit naturally into any other section, including implementation details such as packages to add to `Imports` in `DESCRIPTION` or files to add to `inst`. Use sparingly — if the content belongs in `## Behavior`, `## Proposed signature`, or `## References`, put it there instead.

### `## Proposed signature` (Feature only)

The proposed R function signature, arguments table, and return value description:

````markdown
## Proposed signature

```r
function_name(arg1, arg2)
```

**Arguments**

- `arg1` (`TYPE`) — Description.
- `arg2` (`TYPE`) — Description.

**Returns** a `TYPE` with description.
````

### `## Behavior` (Feature and Bug)

- **Feature**: bullet points describing expected behavior, edge cases, and any internal helpers to implement as part of this issue.
- **Bug**: describe the current (broken) behavior, the expected behavior, and steps to reproduce if known.

### `## References` (optional, all types)

Only include when there are specific reference implementations, external URLs, or related code to link to. Omit it entirely when there are none.

## Creating the issue

Use the `repoId` and the `typeId` for the chosen issue type from the table above.

```bash
gh api graphql \
-f query='mutation($repoId:ID!, $title:String!, $body:String!, $typeId:ID!) {
createIssue(input:{repositoryId:$repoId, title:$title, body:$body, issueTypeId:$typeId}) {
issue { url }
}
}' \
-f repoId="R_kgDOKA67Zw" \
-f title="feat: my_function()" \
-f body="$(cat /tmp/issue_body.md)" \
-f typeId="{typeId}"
```
172 changes: 172 additions & 0 deletions .github/skills/document/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
---
name: document
trigger: document functions
description: Document package functions. Use when asked to document functions.
---

# Document functions

*All* R functions in `R/` should be documented in roxygen2 `#'` style, including internal/unexported functions.

- Run `air format .` then `devtools::document()` after changing any roxygen2 docs.
- Use sentence case for all headings.
- Wrap roxygen comments at 80 characters.
- Files matching `R/import-standalone-*.R` are imported from other packages and have their own conventions. Do not modify their documentation.
- After documenting functions, run `devtools::document(roclets = c('rd', 'collate', 'namespace'))`.
- If `_pkgdown.yml` exists and contains a `reference` section:
- Whenever you add a new (non-internal) documentation topic, also add the topic to `_pkgdown.yml`.
- Use `pkgdown::check_pkgdown()` to check that all topics are included in the reference index.

## Shared parameters

**Parameters used in more than one function** go in `R/aaa-shared_params.R` under `@name .shared-params`. Functions inherit them with `@inheritParams .shared-params`. See `R/aaa-shared_params.R` for current definitions (if it exists).

Shared params blocks: alphabetize parameters, use `@name .shared-params` (with leading dot), include `@keywords internal`, end with `NULL`.

Multiple shared-params groups (e.g. `.shared-params-io`, `.shared-params-parsing`) are appropriate when parameters are only shared within a file and closely related files.

## Parameter documentation format

```r
#' @param param_name (`TYPE`) Brief description (usually 1-3 sentences. Can
#' include [cross_references()]. Additional details on continuation lines if
#' needed.
```

Function-specific `@param` definitions always appear *before* any `@inheritParams` lines. If all parameters are defined locally, omit `@inheritParams` entirely.

### Type notation

| Notation | Meaning |
|----------|---------|
| ``(`character`)`` | Character vector |
| ``(`character(1)`)`` | Single string |
| ``(`logical(1)`)`` | Single logical |
| ``(`integer`)`` | Integer vector |
| ``(`integer(1)`)`` | Single integer |
| ``(`double`)`` | Double vector |
| ``(`vector(0)`)`` | A prototype (zero-length vector) |
| ``(`vector`)`` | A vector of unspecified type |
| ``(`list`)`` | List |
| ``(`data.frame`)`` | Data frame or tibble |
| ``(`function` or `NULL`)`` | A function or NULL |
| ``(`my_class`)`` | A class-specific type (use the actual class name) |
| ``(`any`)`` | Any type |

### Enumerated values

When a parameter takes one of a fixed set of values, document them with a bullet list:

```r
#' @param method (`character(1)`) The aggregation method. Can be one of:
#' * `"mean"`: Arithmetic mean.
#' * `"median"`: Median value.
#' * `"sum"`: Total sum.
```

## Returns

Use `@returns` (not `@return`). Include a type when it's informative:

```r
#' @returns A summary tibble.
#' @returns (`logical(1)`) `TRUE` if `x` is a valid record.
#' @returns Either a tibble or a list, depending on the input.
#' @returns `NULL` (invisibly).
```

**Structured returns with columns:**

```r
#' @returns A [tibble::tibble()] with columns:
#' - `name`: Record name.
#' - `value`: Numeric value.
#' - `status`: Status (`"active"` or `"inactive"`).
```

## Exported functions

```r
#' Title in sentence case
#'
#' Description paragraph providing context and details.
#'
#' @param param_name (`TYPE`) Description.
#' @inheritParams .shared-params
#'
#' @returns Description of return value.
#' @seealso [related_function()]
#' @export
#'
#' @examples
#' example_code()
```

- Blank `#'` lines separate: title/description, description/params, and `@export`/`@examples`.
- `@seealso` (optional) goes between `@returns` and `@export`.
- `@details` can supplement the description when needed.

## Internal (unexported) functions

Internal helpers (identified by a dot prefix, e.g. `.parse_response()`) use abbreviated documentation. Mark them with `@keywords internal` and omit `@export`:

```r
#' Title in sentence case
#'
#' @param one_off_param (`TYPE`) Description.
#' @inheritParams .shared-params
#' @returns (`TYPE`) What it returns.
#' @keywords internal
```

Description paragraph is optional (only include when usage isn't obvious), fewer blank `#'` lines, and no `@examples`.

## S3 methods and `@rdname` grouping

Use `@rdname` to group related functions under one help page. This applies to:
- **S3 methods we own** (generic defined in this package): generic gets full docs, methods get `@rdname` + `@export`.
- **Related exported functions** (e.g. multiple variants of the same operation): primary function gets full docs, variants get `@rdname` + `@export`.

```r
#' Format a summary object
#'
#' @param x (`any`) The object to format.
#' @param ... Additional arguments passed to methods.
#' @returns A formatted character string.
#' @keywords internal
.format_summary <- function(x, ...) {
UseMethod(".format_summary")
}

#' @rdname .format_summary
#' @export
.format_summary.data_summary <- function(x, ...) {
# method implementation
}
```

**S3 methods we don't own** (generic from another package) need standalone documentation:

```r
#' Title describing the method
#'
#' @param x (`TYPE`) Description.
#' @param ... Additional arguments (ignored).
#' @returns Description.
#' @exportS3Method pkg::generic
method.class <- function(x, ...) { ... }
```

## Style notes

**Cross-references:** Use square brackets — `[fetch_records()]` (internal), `[tibble::tibble()]` (external), `[topic_name]` (topics).

**Section comment headers** optionally organize code within a file, lowercase with dashes to column 80:

```r
# helpers ----------------------------------------------------------------------
```

Only use such headers in complex files. The need for section comment headers might indicate that the file should be split into multiple files.

**Examples:** Exported functions include `@examples`. Use `@examplesIf interactive()` for network-dependent or slow functions. Use section-style comments (`# Section ---`) to organize longer example blocks. Internal functions do not get examples.
22 changes: 22 additions & 0 deletions .github/skills/github/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: github
trigger: from github
description: GitHub workflows using the `gh` CLI, including viewing issues/PRs and commit message conventions. Use when interacting with GitHub in any way, such as viewing, creating, or editing issues and pull requests, making commits, or running any `gh` command.
compatibility: Requires the `gh` CLI and an authenticated GitHub session.
---

# GitHub

Use `gh` CLI, not web URLs: `gh issue view 123`, `gh issue list`, `gh pr view 456`, `gh pr list`.

## Commit messages

Conventional commits; backtick-quote function names; close issues in body with `- Closes #N`.

```
feat: add `create_skill()`

Generates a new skill directory with a SKILL.md template.

- Closes #3
```
53 changes: 53 additions & 0 deletions .github/skills/implement-issue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
name: implement-issue
trigger: implement issue / work on #NNN
description: Implements a GitHub issue end-to-end. Use when asked to implement, work on, or fix a specific issue number.
compatibility: Requires the `gh` CLI and an authenticated GitHub session.
---

# Implement a GitHub issue

This skill wraps the Standard Workflow defined in `AGENTS.md`. Run the steps below before and after that workflow.

## Before the standard workflow

**A. Read the issue in full:**

```bash
gh issue view {number}
```

If `gh` is not authenticated, stop and ask the user to authenticate before continuing.

**B. Check/create the branch:**

- If on `main`: `usethis::pr_init("fix-{number}-{description}")`
- Branch format: `fix-{number}-{description}`
- Parts separated by hyphens; `{description}` uses snake_case
- Example: `fix-42-validate_input`
- If a branch already exists for this issue, check it out instead

## Run the Standard Workflow from AGENTS.md

Steps 1–9 of the Standard Workflow are the core development loop.

## After the standard workflow

**C. Commit and push:**

1. Review commits already on this branch (not on `main`) — these are all part of the same PR and should inform the PR description:
```bash
git log main..HEAD --oneline
```
2. Stage and commit all changes:
```bash
git add -A
git commit -m "{short imperative summary}"
```
3. Push and open the PR:
```bash
gh pr create --fill
```
Use `--title` and `--body` explicitly if `--fill` produces an inadequate description.

This step may be overridden — the user may ask you to stop before committing, handle the push themselves, or complete only part of the workflow. Always follow explicit user instructions over these defaults.
Loading
Loading