Skip to content

feat(cli): add skill command for AI agent integration#691

Merged
yuanchen8911 merged 3 commits into
NVIDIA:mainfrom
yuanchen8911:feat/skill-command-fix
Apr 27, 2026
Merged

feat(cli): add skill command for AI agent integration#691
yuanchen8911 merged 3 commits into
NVIDIA:mainfrom
yuanchen8911:feat/skill-command-fix

Conversation

@yuanchen8911

Copy link
Copy Markdown
Contributor

Summary

Adds aicr skill --agent <claude-code|codex> which generates a skill file from the live CLI command tree and installs it to the agent's standard discovery location, with --stdout for preview, --force for non-interactive overwrite, and a [y/N] prompt on TTY when the target file exists.

Motivation / Context

Coding agents (Claude Code, Codex) need a structured "skill" file to discover and correctly invoke the AICR CLI. Hand-maintained skill files drift from the CLI flag/criteria surface; this command generates the file from the same urfave/cli command tree the user runs, so it stays in sync automatically.

Fixes: N/A
Related: N/A

Type of Change

  • New feature (non-breaking change that adds functionality)
  • Documentation update

Component(s) Affected

  • CLI (cmd/aicr, pkg/cli)
  • Docs/examples (docs/, examples/)

Implementation Notes

  • Single source of truth. claudeCodeGenerator produces the canonical content; codexGenerator.generate delegates to it. Only the install path differs (~/.claude/skills/aicr/SKILL.md vs ~/.codex/skills/aicr/SKILL.md), so the two skills cannot drift.
  • Self-reference avoidance. extractCLIMeta excludes the skill command itself and any hidden commands; extractFlagMeta excludes auto-generated help/version flags.
  • Wrapper-aware flag extraction. extractFlagMeta matches *completableStringFlag explicitly so Usage/Default/Required/Completions are captured. (Without this, the wrapper falls through to a generic default branch and those fields are dropped.)
  • Overwrite safety. When the target exists and --force is not set: prompt overwrite? [y/N] on TTY (empty/EOF/unknown answers default to no); on non-TTY stdin (CI, piped), refuse with a hint to use --force rather than silently clobber.
  • Pure write. writeSkillFile is a pure write; existence/confirmation lives in the caller so test-only writes don't fight the prompt logic.

Testing

make qualify          # pass
make lint             # pass (Go + YAML)
go test -race ./pkg/cli/...   # pass

Coverage (pkg/cli): 37.5% → 50.5% (+13.0%); no new exported symbols.

End-to-end smoke test on this branch:

aicr skill --agent claude-code --stdout    # prints SKILL.md to stdout
aicr skill --agent claude-code             # interactive: prompts on existing file
echo n | aicr skill --agent claude-code    # non-TTY: errors with --force hint
aicr skill --agent claude-code --force     # overwrites without prompting
aicr skill --agent codex --force           # produces byte-identical content
diff ~/.claude/skills/aicr/SKILL.md ~/.codex/skills/aicr/SKILL.md   # no diff

Risk Assessment

  • Low — Isolated change, well-tested, easy to revert

Rollout notes: New command in the Utilities category; no existing behavior touched. aicr skill writes only to the user's home directory (~/.claude/... or ~/.codex/...), never to the repo. No flags, env vars, or APIs renamed.

Checklist

  • Tests pass locally (make test with -race)
  • Linter passes (make lint)
  • I did not skip/disable tests to make CI green
  • I added/updated tests for new functionality
  • I updated docs if user-facing behavior changed
  • Changes follow existing patterns in the codebase
  • Commits are cryptographically signed (git commit -S)

@coderabbitai

coderabbitai Bot commented Apr 27, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an aicr skill CLI subcommand that generates agent-specific SKILL.md files for claude-code and codex. It extracts recursive CLI metadata (commands and flags), normalizes flag kinds and completions, and renders markdown via pluggable generators. Output can be emitted to stdout or installed under per-agent locations in the user home directory. Installation creates parent directories, writes atomically, refuses to overwrite symlinks, and prompts for overwrite unless --force is supplied. A comprehensive test suite covers extraction, generators, file I/O, parsing, and command behavior.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Details

  • pkg/cli/skill_generator.go (+348): New metadata models (cliMeta, cmdMeta, flagMeta), parsing/validation of agent types, recursive extraction of urfave/cli command trees (excluding hidden/framework commands and the skill command), flag kind normalization and completion extraction, install-path helper (skillInstallPath), atomic file write utility (writeSkillFile) that creates parent directories and refuses to overwrite symlinks, and interactive/non-TTY overwrite confirmation (confirmOverwrite).

  • pkg/cli/skill_claude_code.go (+282): Claude Code generator that builds a SKILL.md with YAML frontmatter, versioned heading, prerequisites, a dynamic "Command Reference" enumerating commands/subcommands and flags (aliases, type, usage, default, required marker, completions), conditional "Criteria Values" extraction for recipe flags, and appended guidance/workflow examples. Defines install path .claude/skills/aicr/SKILL.md.

  • pkg/cli/skill_codex.go (+31): Codex generator adapter delegating generation to the Claude generator and returning Codex install path .codex/skills/aicr/SKILL.md. Includes compile-time interface conformance check.

  • pkg/cli/skill.go (+138): New skill subcommand implementation with flags (--agent, --stdout, --force), agent dispatch via parseAgentType, extraction of CLI metadata (extractCLIMeta), stdout vs install-file flow, overwrite prompting logic, and error propagation/messages.

  • pkg/cli/skill_test.go (+717): Extensive tests covering CLI metadata extraction (inclusions/exclusions), flag-type inference and completable values, criteria-values allowlisting, parseAgentType and supported agent list, writeSkillFile behaviors (nested creation, overwrite, symlink refusal), confirmOverwrite interactive and non-TTY behavior, userHomeDir and skillInstallPath assertions, Claude/Codex generator output structure and parity, and end-to-end aicr skill command cases (including --stdout and missing --agent).

  • pkg/cli/doc.go (+14) and docs/user/cli-reference.md (+49): Documentation additions describing the skill subcommand, supported --agent values, --stdout and --force flags, target install locations, overwrite semantics, and usage examples.

  • pkg/cli/root.go (+1): Registers the new skill subcommand with the root CLI command tree.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(cli): add skill command for AI agent integration' accurately and concisely describes the main change: a new CLI command for agent skill file generation.
Description check ✅ Passed The description clearly explains the feature (aicr skill command), motivation (keeping skill files in sync with CLI), implementation details, testing, and risk assessment, all directly related to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/user/cli-reference.md`:
- Around line 1454-1492: The markdown blocks under the "Synopsis", "**Flags:**",
"**Install Locations:**" and "**Examples:**" headings are missing surrounding
blank lines which triggers MD031/MD058; fix by inserting a blank line before and
after the fenced code block under "Synopsis", a blank line before the table
after "**Flags:**", a blank line before the table after "**Install
Locations:**", and a blank line before the fenced code block under
"**Examples:**" (and ensure there is a blank line after each block as well) so
each block is separated from the surrounding headings and text.

In `@pkg/cli/skill_claude_code.go`:
- Around line 230-233: The verify example emits an unsupported flag; update the
fmt.Fprintf call that prints "aicr verify --bundle ./bundles" in
pkg/cli/skill_claude_code.go so the example uses a positional argument instead
(e.g., "aicr verify ./bundles") so the CLI invocation matches the actual parser
and won't cause agents to produce a parse error.

In `@pkg/cli/skill_generator.go`:
- Around line 66-71: The CLI metadata currently omits root/global flags because
cliMeta only has Name, Version, and Commands and extractCLIMeta only walks
root.Commands; add a Flags field (e.g., []flagMeta) to cliMeta and update
extractCLIMeta to also iterate and extract root.Flags (similar to how command
flags are handled in cmdMeta) so global flags like --debug and --log-json are
captured and serialized into the generated skill output; ensure any existing
flag extraction logic (the flagMeta shape and the code used for cmdMeta.Flags)
is reused for the root-level flags.

In `@pkg/cli/skill.go`:
- Around line 47-75: The skill CLI command currently contains business logic;
extract all skill generation and install behavior from skillCmd/runSkillCmd into
a new functional package (e.g., a package that exposes GenerateSkill,
ResolveInstallPath, and InstallSkill/WriteOrStdout functions) and have
runSkillCmd simply validate flags (using skillCmdFlags), call those exported
functions, and format/report results; move handling of generator dispatch,
metadata extraction, overwrite policy, path resolution, and file writes into
those new functions so pkg/cli only captures intent and delegates
implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 62a4ae09-02c2-4c83-8188-c47615b48d3d

📥 Commits

Reviewing files that changed from the base of the PR and between 3c9f6ec and f203c2f.

📒 Files selected for processing (8)
  • docs/user/cli-reference.md
  • pkg/cli/doc.go
  • pkg/cli/root.go
  • pkg/cli/skill.go
  • pkg/cli/skill_claude_code.go
  • pkg/cli/skill_codex.go
  • pkg/cli/skill_generator.go
  • pkg/cli/skill_test.go

Comment thread docs/user/cli-reference.md
Comment thread pkg/cli/skill_claude_code.go
Comment thread pkg/cli/skill_generator.go
Comment thread pkg/cli/skill.go
@yuanchen8911 yuanchen8911 force-pushed the feat/skill-command-fix branch from f203c2f to d13f93b Compare April 27, 2026 04:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/cli/skill_claude_code.go`:
- Around line 164-203: The current writeCriteriaValues collects any recipe flag
with completions (recipeMeta.Flags where f.Completions != nil) which incorrectly
includes non-criteria flags like "--format"; update writeCriteriaValues to only
include true recipe criteria flags by adding an explicit filter when building
fields: check a dedicated marker (e.g., f.IsCriteria or f.Metadata["criteria"]
== "true") if available on cmdMeta.Flags, otherwise exclude known
non-criteria/global flags (e.g., skip f.Name == "format" and other global flags
or f.IsGlobal/f.Hidden if present); update the loop that appends to fields
(references: writeCriteriaValues, recipeMeta.Flags, criteriaField, f.Name,
f.Completions) to only append when the flag passes this criteria predicate.

In `@pkg/cli/skill.go`:
- Around line 120-131: The current flow does a pre-check with os.Stat and
confirmOverwrite then separately calls writeSkillFile, creating a TOCTOU race;
instead, move the overwrite decision and the actual file replacement into a
single atomic helper (update or replace writeSkillFile) that: re-checks the
destination with os.Lstat to reject symlinks, writes content to a uniquely named
temp file in the same directory, fsyncs the temp file, then atomically replaces
the target via os.Rename; ensure confirmOverwrite is called before the helper
but have the helper perform the final lstat-and-write+rename so the confirmed
path cannot be swapped between confirmation and write (references:
confirmOverwrite, writeSkillFile, os.Lstat, os.Rename).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 5b0c28b4-64fa-4989-9643-153da673271f

📥 Commits

Reviewing files that changed from the base of the PR and between f203c2f and d13f93b.

📒 Files selected for processing (8)
  • docs/user/cli-reference.md
  • pkg/cli/doc.go
  • pkg/cli/root.go
  • pkg/cli/skill.go
  • pkg/cli/skill_claude_code.go
  • pkg/cli/skill_codex.go
  • pkg/cli/skill_generator.go
  • pkg/cli/skill_test.go

Comment thread pkg/cli/skill_claude_code.go Outdated
Comment thread pkg/cli/skill.go Outdated
@yuanchen8911 yuanchen8911 force-pushed the feat/skill-command-fix branch from d13f93b to 6d8af23 Compare April 27, 2026 05:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
pkg/cli/skill_generator.go (1)

56-145: 🛠️ Refactor suggestion | 🟠 Major

Move the skill implementation out of pkg/cli.

These segments implement metadata extraction, generator interfaces, install-path resolution, and file-write behavior. That is domain logic, not CLI wiring, so the command still owns the implementation instead of delegating to a functional package.

Based on learnings: In this repo, ensure packages under pkg/cli contain only CLI wiring and user-interaction helpers; move skillGenerator, claudeCodeGenerator/codexGenerator, cliMeta, and extractCLIMeta into a dedicated package such as pkg/skill.

Also applies to: 247-320

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cli/skill_generator.go` around lines 56 - 145, The CLI package currently
contains domain logic that should live in a dedicated skill package; move the
types and functions skillGenerator, cliMeta, cmdMeta, flagMeta, flagType*
constants, cmdNameHelp/cmdNameCompletion, isFrameworkCommand, extractCLIMeta,
extractCmdMeta, extractFlagMeta and any generator implementations (e.g.,
claudeCodeGenerator, codexGenerator) plus their installPath/generate methods
into a new package (suggested pkg/skill), change their package declaration, make
any needed identifiers exported (capitalize) for cross-package use, update
imports in the CLI command to call pkg/skill.ExtractCLIMeta (or renamed exports)
and to construct generators from pkg/skill, and run `go vet`/`go test` to fix
compile errors (import paths, visibility) introduced by the move.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/cli/skill_test.go`:
- Around line 660-683: The test builds a synthetic root instead of exercising
the real CLI root, so change TestSkillCmd_Stdout to use the actual newRootCmd()
(so runSkillCmd() reads cmd.Root() as in production): call root := newRootCmd(),
set root.Writer = &buf (retain capturing output), then run
root.Run(context.Background(),
[]string{"aicr","skill","--agent","claude-code","--stdout"}) and keep the same
assertions; this ensures the test exercises runSkillCmd(), the real top-level
metadata, and stdout formatting rather than the isolated skillCmd().

---

Duplicate comments:
In `@pkg/cli/skill_generator.go`:
- Around line 56-145: The CLI package currently contains domain logic that
should live in a dedicated skill package; move the types and functions
skillGenerator, cliMeta, cmdMeta, flagMeta, flagType* constants,
cmdNameHelp/cmdNameCompletion, isFrameworkCommand, extractCLIMeta,
extractCmdMeta, extractFlagMeta and any generator implementations (e.g.,
claudeCodeGenerator, codexGenerator) plus their installPath/generate methods
into a new package (suggested pkg/skill), change their package declaration, make
any needed identifiers exported (capitalize) for cross-package use, update
imports in the CLI command to call pkg/skill.ExtractCLIMeta (or renamed exports)
and to construct generators from pkg/skill, and run `go vet`/`go test` to fix
compile errors (import paths, visibility) introduced by the move.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 13504519-f5e9-4177-b6b6-8b8e22259a61

📥 Commits

Reviewing files that changed from the base of the PR and between d13f93b and 6d8af23.

📒 Files selected for processing (8)
  • docs/user/cli-reference.md
  • pkg/cli/doc.go
  • pkg/cli/root.go
  • pkg/cli/skill.go
  • pkg/cli/skill_claude_code.go
  • pkg/cli/skill_codex.go
  • pkg/cli/skill_generator.go
  • pkg/cli/skill_test.go

Comment thread pkg/cli/skill_test.go
@yuanchen8911 yuanchen8911 force-pushed the feat/skill-command-fix branch from 6d8af23 to 194e734 Compare April 27, 2026 05:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
pkg/cli/skill_generator.go (1)

56-348: 🛠️ Refactor suggestion | 🟠 Major

Move the skill-generation implementation out of pkg/cli.

This file is almost entirely functional logic: agent modeling, CLI metadata extraction, install-path resolution, file writes, and overwrite policy. That keeps the feature coupled to the UI layer instead of a reusable domain package and continues the pkg/cli boundary violation already discussed on this PR.

Based on learnings, pkg/cli here should keep only command wiring, urfave/cli flag plumbing, and user-interaction helpers like TTY confirmation, while skillGenerator, cliMeta, extractCLIMeta, and the generator/install helpers move to a dedicated package such as pkg/skill.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cli/skill_generator.go` around lines 56 - 348, The code that models
skills and performs generation/installation should be moved out of pkg/cli into
a new pkg/skill package: extract and relocate the skillGenerator interface,
cliMeta, cmdMeta, flagMeta types, constants (flagType*), the functions
extractCLIMeta, extractCmdMeta, extractFlagMeta, userHomeDir, skillInstallPath,
writeSkillFile (and any helper types like completableStringFlag /
CompletableFlag used by these funcs) into pkg/skill; leave CLI-only wiring and
user-interaction helpers (confirmOverwrite, isFrameworkCommand, and any
urfave/cli command registration) in pkg/cli. After moving, update package
declarations, imports, and any call sites to reference pkg/skill (e.g.,
skill.ExtractCLIMeta, skill.WriteSkillFile or import alias), and ensure error
types (errors.*) and referenced symbols compile in the new package.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/cli/skill.go`:
- Around line 120-129: The os.Stat(path) error is being treated as "missing" for
all failures which can hide real errors; modify the logic around the os.Stat
call used with cmd.Bool("force") and confirmOverwrite so that only
os.ErrNotExist bypasses the overwrite prompt—i.e., if os.Stat(path) returns an
error, check if errors.Is(err, os.ErrNotExist) and only then proceed without
prompting; for any other stat error return that error instead; keep the existing
confirmOverwrite(path, os.Stdin, cmd.Root().Writer) and the early return
behavior when the user declines.

---

Duplicate comments:
In `@pkg/cli/skill_generator.go`:
- Around line 56-348: The code that models skills and performs
generation/installation should be moved out of pkg/cli into a new pkg/skill
package: extract and relocate the skillGenerator interface, cliMeta, cmdMeta,
flagMeta types, constants (flagType*), the functions extractCLIMeta,
extractCmdMeta, extractFlagMeta, userHomeDir, skillInstallPath, writeSkillFile
(and any helper types like completableStringFlag / CompletableFlag used by these
funcs) into pkg/skill; leave CLI-only wiring and user-interaction helpers
(confirmOverwrite, isFrameworkCommand, and any urfave/cli command registration)
in pkg/cli. After moving, update package declarations, imports, and any call
sites to reference pkg/skill (e.g., skill.ExtractCLIMeta, skill.WriteSkillFile
or import alias), and ensure error types (errors.*) and referenced symbols
compile in the new package.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 8eeb17d6-fd65-485b-a4db-f602a93b159b

📥 Commits

Reviewing files that changed from the base of the PR and between 6d8af23 and 194e734.

📒 Files selected for processing (8)
  • docs/user/cli-reference.md
  • pkg/cli/doc.go
  • pkg/cli/root.go
  • pkg/cli/skill.go
  • pkg/cli/skill_claude_code.go
  • pkg/cli/skill_codex.go
  • pkg/cli/skill_generator.go
  • pkg/cli/skill_test.go

Comment thread pkg/cli/skill.go Outdated
@yuanchen8911 yuanchen8911 requested a review from mchmarny April 27, 2026 05:46
@yuanchen8911 yuanchen8911 force-pushed the feat/skill-command-fix branch from 194e734 to be016ed Compare April 27, 2026 05:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/cli/skill_claude_code.go`:
- Around line 145-159: The flag Usage text is appended verbatim and may contain
newlines/tabs which break the generated markdown; before inlining use a
normalized/sanitized string (e.g., create a local variable like usage :=
strings.Join(strings.Fields(f.Usage), " ") or strings.ReplaceAll to collapse
newlines/tabs and trim) and use that sanitized variable when building line
(replace uses of f.Usage with usage); apply the same normalization to f.Default
and elements of f.Completions if they might contain whitespace/newlines to
ensure the bullet layout in SKILL.md stays intact.

In `@pkg/cli/skill_generator.go`:
- Around line 74-80: cmdMeta currently lacks a field for positional argument
syntax so generated SKILL.md omits required args; add a field (e.g., ArgsUsage
string) to the cmdMeta struct, populate it in extractCmdMeta by reading
cmd.ArgsUsage, and update writeCommandEntry to include or append that ArgsUsage
(or emit a short synopsis combining Name and ArgsUsage) when rendering each
command so positional arguments like "<bundle-dir>" appear in the output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: dc3e8193-6037-4a8c-9170-a8f293401939

📥 Commits

Reviewing files that changed from the base of the PR and between 194e734 and be016ed.

📒 Files selected for processing (8)
  • docs/user/cli-reference.md
  • pkg/cli/doc.go
  • pkg/cli/root.go
  • pkg/cli/skill.go
  • pkg/cli/skill_claude_code.go
  • pkg/cli/skill_codex.go
  • pkg/cli/skill_generator.go
  • pkg/cli/skill_test.go

Comment thread pkg/cli/skill_claude_code.go Outdated
Comment thread pkg/cli/skill_generator.go Outdated
Adds `aicr skill --agent <claude-code|codex>` which generates a skill
file that teaches a coding agent how to use the AICR CLI and installs
it to the agent's standard discovery location:

  claude-code → ~/.claude/skills/aicr/SKILL.md
  codex       → ~/.codex/skills/aicr/SKILL.md

Both agents share the same generated content (Claude Code is the
canonical generator; the Codex generator delegates to it) so the two
skills stay aligned. Only the install path differs.

The generator walks the live urfave/cli command tree and emits YAML
frontmatter (name, description, user_invocable), a dynamic command
reference covering both root-level (global) flags and per-command
flags with aliases/defaults/required/completions, a criteria values
section pulled from the recipe command's criterion flags, plus
prerequisites, output-format guidance, workflow examples, error
handling, and best practices.

Filtering rules applied during extraction:
- Hidden commands and the skill command itself are excluded.
- Auto-generated --help/--version flags are excluded.
- urfave/cli/v3 auto-injects an unhidden "help" subcommand on every
  non-leaf command via setupDefaults->ensureHelp at Run() time. This
  filter excludes "help" so the SKILL.md does not document framework
  plumbing as an AICR workflow command.
- The shell-completion command added via EnableShellCompletion is
  similarly filtered. (root.go's ConfigureShellCompletionCommand sets
  Hidden=false on it; the name-based filter catches it regardless.)
- The criteria values section uses an explicit allowlist (service,
  accelerator, intent, os, platform) so completable but non-criterion
  flags such as --format are not mislabeled as criteria.

Flags:
  --agent <name>  target coding agent (required, completable)
  --stdout        print to stdout instead of writing to disk
  --force         overwrite an existing skill file without prompting

Overwrite safety:
- When the target file exists and --force is not set, the command
  prompts "overwrite? [y/N]" on a TTY and aborts on no/empty/EOF.
- Non-TTY stdin is rejected with a hint to use --force, so CI runs do
  not silently clobber files.
- writeSkillFile uses os.Lstat to refuse overwriting a symlink at the
  target, then writes via os.CreateTemp + os.Rename so the replace is
  atomic and TOCTOU-safe (an attacker cannot redirect the write by
  swapping the path between confirmation and write).

extractFlagMeta detects the *completableStringFlag wrapper explicitly
so its Usage, Default, Required, and Completions are captured —
previously the wrapper fell through to the generic default branch and
those fields were dropped.

Tests cover metadata extraction (including post-Run() state with
auto-injected help/completion subcommands filtered out), agent
parsing, install paths, generator content equivalence, the criteria
allowlist, the symlink rejection guard, the prompt flow
(yes/no/empty/EOF/non-TTY), --force overwrite, and the existing
structural CLI checks.
@yuanchen8911 yuanchen8911 force-pushed the feat/skill-command-fix branch from be016ed to 3af09fa Compare April 27, 2026 06:10
@yuanchen8911 yuanchen8911 merged commit 6593894 into NVIDIA:main Apr 27, 2026
32 checks passed
lockwobr pushed a commit that referenced this pull request Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants