Skip to content

feat: use_skill_create_issue() #6

@jonthegeek

Description

@jonthegeek

Summary

As a package developer, in order to give AI agents the ability to create well-structured GitHub issues for my package, I would like to install a pkgskills create-issue skill with a single function call.

Proposed signature

use_skill_create_issue(
  target_dir = ".github",
  use_skills_subdir = TRUE,
  overwrite = TRUE,
  open = rlang::is_interactive(),
  gh_token = gh::gh_token()
)

Arguments

  • target_dir (character(1)) — Directory where the skill will be installed, relative to the project root. Defaults to ".github".
  • use_skills_subdir (logical(1)) — Whether to place the create-issue folder under a skills subdirectory of target_dir. Defaults to TRUE, producing .github/skills/create-issue/SKILL.md.
  • overwrite (logical(1)) — Whether to overwrite an existing skill file. Defaults to TRUE.
  • open (logical(1)) — Whether to open the installed file in the editor after creation. Defaults to rlang::is_interactive().
  • gh_token (character(1)) — A GitHub personal access token. Defaults to gh::gh_token().

Returns the path to the installed skill file, invisibly (following the usethis convention).

Under the hood, use_skill_create_issue() delegates to an internal helper with this signature:

.use_skill(
  skill,
  data,
  target_dir = ".github",
  use_skills_subdir = TRUE,
  overwrite = TRUE,
  open = rlang::is_interactive()
)

.use_skill() arguments

  • skill (character(1)) — Skill name (folder name under inst/templates/skills/), e.g. "create-issue". Determines the template path (inst/templates/skills/{skill}/SKILL.md) and the install subdirectory.
  • data (list) — Named list of whisker template variables to fill into the skill template.
  • Other arguments are the same as those of use_skill_create_issue() above.

Behavior

use_skill_create_issue()

  • Validates all arguments using stbl (following the r-code skill conventions). target_dir and gh_token are character(1); use_skills_subdir and overwrite are logical(1).
  • Validates that the active project has a BugReports field in DESCRIPTION pointing to a GitHub URL. If not, errors with a {cli} message that includes {.run usethis::use_github()}.
  • Extracts the repo owner and repo name from the BugReports URL.
  • Uses gh::gh() (with gh_token) to fetch:
    • The repository's node ID (repoId)
    • All available issue types via issueTypes GraphQL query, requesting id, name, and description for each node
  • Builds a data list containing owner, repo, repo_id, and issue_types: a list of lists, each with name, id, and description keys.
  • Calls .use_skill("create-issue", data = data, target_dir, use_skills_subdir, overwrite, open).

.use_skill()

  • Validates all arguments using stbl.
  • Computes save_as:
    • If use_skills_subdir = TRUE: fs::path(target_dir, "skills", skill, "SKILL.md")
    • If use_skills_subdir = FALSE: fs::path(target_dir, skill, "SKILL.md")
  • Reads the trigger: field from the YAML front matter of the source template (inst/templates/skills/{skill}/SKILL.md within the pkgskills package). The front matter uses simple key: value lines between --- delimiters.
  • Calls .use_template() (defined in R/use_agent.R) pointing to skills/{skill}/SKILL.md, with the derived save_as argument and the provided data and open arguments.
  • If AGENTS.md exists at the project root, upserts a row for this skill into the ## Skills table: | {trigger} | @{save_as} |. If a row for save_as already exists, its trigger is updated in place; otherwise a new row is appended. If AGENTS.md exists but has no ## Skills section, the section is created.
  • Emits a cli::cli_inform() message confirming the skill was installed and its path.
  • Returns the installed file path invisibly.

.use_skill() is the general pattern for how all use_skill_*() functions in this package will work — analogous to how use_agent() calls .use_template() internally.

Details

  • Add trigger: to the YAML front matter of all skill files under .github/skills/ and all templates under inst/templates/skills/. The value is the trigger phrase as it will appear in the ## Skills table of AGENTS.md.
  • Create inst/templates/skills/create-issue/SKILL.md: a whisker-rendered version of .github/skills/create-issue/SKILL.md in which hardcoded values are replaced with template variables:
    • {{{owner}}} and {{{repo}}} — repo owner and name (used in the GraphQL lookup examples)
    • {{{repo_id}}} — repository node ID (replaces the hardcoded R_kgDORkNSGw)
    • {{#issue_types}} / {{/issue_types}} whisker section iterating over a list of lists, each with {{name}}, {{id}}, and {{description}} — renders one table row per issue type (replaces the hardcoded table rows)
  • Create R/use_skill.R containing .use_skill(). Unlike usual convention, this helper gets its own file because it will likely be exported eventually. The AGENTS.md upsert logic can live in a private helper in the same file (e.g. .upsert_agents_skills_row()).
  • Create R/use_skill_create_issue.R containing use_skill_create_issue().
  • Add gh to Imports in DESCRIPTION (needed for gh::gh() and gh::gh_token()).
  • Update the issueTypes lookup query in .github/skills/create-issue/SKILL.md to request description alongside id and name.

References

  • use_agent() in R/use_agent.R — model for how the public function calls an internal helper (.use_template()) and the general shape of use_skill_*() functions.
  • gh package — for GitHub API calls and token management.
  • usethis::use_template() — for rendering and writing the skill file.
  • Existing .github/skills/create-issue/SKILL.md — source for the template.

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions