Skip to content

feat: use_skill_create_issue()#8

Merged
jonthegeek merged 7 commits intomainfrom
copilot/add-create-issue-skill
Mar 17, 2026
Merged

feat: use_skill_create_issue()#8
jonthegeek merged 7 commits intomainfrom
copilot/add-create-issue-skill

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 13, 2026

Adds use_skill_create_issue(), which installs a rendered create-issue skill into a project by querying the GitHub GraphQL API and filling a whisker template with repo-specific data (owner, repo ID, issue types, and install timestamp).

use_skill_create_issue()
# → writes .github/skills/create-issue/SKILL.md
# → upserts the ## Skills table in AGENTS.md

New exported function

  • use_skill_create_issue() — validates BugReports in DESCRIPTION is a GitHub URL, fetches repo node ID and issue types via gh::gh("POST /graphql", ...), captures a UTC install timestamp (update_time), then delegates to .use_skill()

New internal infrastructure

  • .use_skill(skill, data, ...) — general-purpose skill installer; renders the template, errors on existing file when overwrite = FALSE, creates parent dirs, and upserts AGENTS.md
  • .read_skill_trigger(path) — parses trigger: from YAML front matter between --- delimiters
  • .upsert_agents_skills_row(trigger, save_as) — self-contained: finds AGENTS.md itself, returns NULL invisibly if absent; handles all states: no ## Skills section, section with no table, update existing row, append new row
  • .pkg_abort() — thin wrapper around stbl::pkg_abort() with message_env = rlang::caller_env() so cli {expr} interpolation resolves in the right frame
  • .to_boolean() — logical scalar coercion helper in R/utils.R, analogous to .to_string()
  • .path_pkg() / .path_template() — package and template path helpers in R/utils.R built on fs::path_package()
  • .check_file_exists(save_as, overwrite) — validates file existence in R/utils.R; errors with "file_exists" subclass when overwrite = FALSE

Template

  • inst/templates/skills/create-issue/SKILL.md — whisker template with {{{owner}}}, {{{repo}}}, {{{repo_id}}}, {{{update_time}}}, and a {{#issue_types}} section rendering one table row per issue type
  • ## Implementation section merged into ## Details in both the template and .github/skills/create-issue/SKILL.md

Shared parameters

  • @param data, target_dir, use_skills_subdir, and overwrite unified in R/aaa-shared_params.R and inherited across functions

Skill front matter

  • Added trigger: field to the YAML front matter of all seven .github/skills/*/SKILL.md files

Dependencies

  • gh moved from SuggestsImports
Original prompt

This section details on the original issue you should resolve

<issue_title>feat: use_skill_create_issue()</issue_title>
<issue_description>## 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.

Implementation

  • 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 (re...

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: jonthegeek <33983824+jonthegeek@users.noreply.github.com>
Copilot AI changed the title [WIP] Add pkgskills create-issue skill function feat: use_skill_create_issue() Mar 13, 2026
Copilot AI requested a review from jonthegeek March 13, 2026 13:52
Copy link
Copy Markdown
Contributor

@jonthegeek jonthegeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Implement these changes. Continue to use red-green-refactor TDD and the skills in this repo.

Co-authored-by: jonthegeek <33983824+jonthegeek@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 13, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • CRAN.R-project.org
    • Triggering command: /opt/R/4.5.3/lib/R/bin/exec/R /opt/R/4.5.3/lib/R/bin/exec/R --no-restore --no-echo --args nextArgpkgskills_0.0.0.9000.tar.gznextArg--as-crannextArg--timingsnextArg--no-manual (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from jonthegeek March 13, 2026 15:18
@jonthegeek jonthegeek marked this pull request as ready for review March 17, 2026 19:22
@jonthegeek jonthegeek requested a review from Copilot March 17, 2026 19:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first “skill installer” workflow to pkgskills by introducing use_skill_create_issue(), which fetches GitHub repository metadata and renders an on-disk skill template into a target project (and optionally updates AGENTS.md).

Changes:

  • Introduces use_skill_create_issue() plus internal helpers to fetch repo ID / issue types via GitHub GraphQL and render the create-issue skill template.
  • Adds new internal utilities for coercion, paths, and markdown/YAML-front-matter parsing to support skill installation and AGENTS.md table upserts.
  • Adds substantial test coverage (incl. snapshots) and updates docs/templates/metadata (NAMESPACE, Rd files, skills’ YAML front matter triggers, README install snippet, DESCRIPTION imports).

Reviewed changes

Copilot reviewed 75 out of 75 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/testthat/test-utils.R Replaces prior coercion test with .format_now_utc() formatting test.
tests/testthat/test-utils-text.R Adds tests + snapshots coverage for new text/YAML/table helpers.
tests/testthat/test-utils-path.R Adds tests + snapshots for new path/writability helpers.
tests/testthat/test-utils-coerce.R Adds tests for .to_string() and .to_boolean().
tests/testthat/test-use_skill.R Adds integration tests for .use_skill() + AGENTS.md upsert behavior.
tests/testthat/test-use_skill_create_issue.R Adds tests + snapshots for use_skill_create_issue() validation and wiring.
tests/testthat/helper-local_pkg.R Adds local_gh_mock() and updates default DESCRIPTION fixture.
tests/testthat/helper-expectations.R Adds expect_pkg_error_snapshot() helper and path-scrubbing transform.
tests/testthat/.gitignore Removes testthat artifact ignore rules under tests/testthat/.
tests/testthat/_snaps/utils-text.md Snapshot outputs for YAML-front-matter helpers’ error cases.
tests/testthat/_snaps/utils-path.md Snapshot outputs for path helpers’ error cases.
tests/testthat/_snaps/use_skill.md Snapshot outputs for .use_skill() messaging + error cases.
tests/testthat/_snaps/use_skill_create_issue.md Snapshot outputs for BugReports parsing error cases.
README.Rmd Switches dev install instructions from remotes to pak.
README.md Regenerated README reflecting pak-based install instructions.
R/utils.R Adds .call_gh() wrapper and .format_now_utc(); moves coercion helper out.
R/utils-text.R Adds pattern/table/YAML parsing helpers and line insertion utility.
R/utils-path.R Adds package/template/project path helpers and writability checks.
R/utils-coerce.R Adds .to_string() and .to_boolean() coercion helpers.
R/use_skill.R Adds skill installation + AGENTS.md upsert implementation.
R/use_skill_create_issue.R Adds exported use_skill_create_issue() and GitHub metadata collection.
R/use_agent.R Tightens .use_template() validation and ensures output dir exists.
R/aaa-shared_params.R Expands shared parameter docs used across new helpers.
R/aaa-conditions.R Introduces .pkg_abort() wrapper for package-scoped errors.
NEWS.md Notes new use_skill_create_issue() feature.
NAMESPACE Exports use_skill_create_issue().
man/use_skill_create_issue.Rd Generated docs for new exported function.
man/use_agent.Rd Updates save_as parameter wording.
man/dot-use_template.Rd Updates data parameter description and save_as wording.
man/dot-use_skill.Rd Generated docs for new internal skill installer.
man/dot-upsert_agents_skill.Rd Generated docs for AGENTS.md upsert helper.
man/dot-upsert_agents_skill_from_template.Rd Generated docs for template-based AGENTS.md upsert.
man/dot-to_string.Rd Points .to_string() docs to new source file.
man/dot-to_boolean.Rd Generated docs for .to_boolean().
man/dot-shared-params.Rd Generated docs updates for expanded shared params.
man/dot-read_skill_trigger.Rd Generated docs for YAML trigger reader.
man/dot-pkg_abort.Rd Generated docs for .pkg_abort().
man/dot-path_template.Rd Generated docs for .path_template().
man/dot-path_skill_save_as.Rd Generated docs for .path_skill_save_as().
man/dot-path_proj_save_as.Rd Generated docs for .path_proj_save_as().
man/dot-path_pkg.Rd Generated docs for .path_pkg().
man/dot-parse_yaml_front_matter.Rd Generated docs for YAML front matter parsing helper.
man/dot-make_skills_table.Rd Generated docs for skills table builder.
man/dot-make_skills_section.Rd Generated docs for skills section builder.
man/dot-make_skill_row.Rd Generated docs for skills table row builder.
man/dot-lines_insert_after.Rd Generated docs for .lines_insert_after().
man/dot-is_first_run.Rd Generated docs for .is_first_run().
man/dot-get_create_issue_data.Rd Generated docs for create-issue template data collector.
man/dot-format_now_utc.Rd Generated docs for .format_now_utc().
man/dot-find_table_last_row_idx.Rd Generated docs for table row finder.
man/dot-find_skills_section_idx.Rd Generated docs for skills section finder.
man/dot-find_skill_row_idx.Rd Generated docs for existing skill row finder.
man/dot-find_pattern_idx.Rd Generated docs for first-match index finder.
man/dot-fetch_repo_issue_types.Rd Generated docs for issue types GraphQL fetch helper.
man/dot-fetch_repo_id.Rd Generated docs for repo node ID GraphQL fetch helper.
man/dot-extract_yaml_scalar.Rd Generated docs for YAML scalar extraction helper.
man/dot-extract_repo_from_desc.Rd Generated docs for BugReports URL parsing helper.
man/dot-check_path_writable.Rd Generated docs for .check_path_writable().
man/dot-call_gh.Rd Generated docs for .call_gh() wrapper.
man/dot-agents_lines_upsert_skill.Rd Generated docs for computing AGENTS.md upserted lines.
man/dot-agents_lines_replace_row.Rd Generated docs for replacing an existing skills row.
man/dot-agents_lines_insert_table.Rd Generated docs for inserting a skills table in section.
man/dot-agents_lines_append_section.Rd Generated docs for appending a skills section.
man/dot-agents_lines_append_row.Rd Generated docs for appending a row after last table row.
man/dot-agents_lines_add_to_section.Rd Generated docs for adding row/table within existing section.
man/dot-agents_lines_add_skill_row.Rd Generated docs for adding a new skill row.
inst/templates/skills/create-issue/SKILL.md Adds the installable create-issue skill template with whisker variables.
DESCRIPTION Adds gh and stringr to Imports, adds R dependency, updates Suggests.
.github/skills/tdd-workflow/SKILL.md Adds trigger and improves guidance around snapshots/errors.
.github/skills/search-code/SKILL.md Adds trigger field.
.github/skills/r-code/SKILL.md Adds trigger field.
.github/skills/implement-issue/SKILL.md Adds trigger field.
.github/skills/github/SKILL.md Adds trigger field.
.github/skills/document/SKILL.md Adds trigger and updates documentation workflow guidance.
.github/skills/create-issue/SKILL.md Adds trigger and refines sections guidance (removes “Implementation” section).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@jonthegeek jonthegeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good as long as checks pass!

@jonthegeek jonthegeek enabled auto-merge (squash) March 17, 2026 19:57
@jonthegeek jonthegeek merged commit 82d0939 into main Mar 17, 2026
8 checks passed
@jonthegeek jonthegeek deleted the copilot/add-create-issue-skill branch March 17, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: use_skill_create_issue()

3 participants