Skip to content

Feat/dart native skills install#481

Open
Pratikdate wants to merge 11 commits into
StacDev:devfrom
Pratikdate:feat/dart-native-skills-install
Open

Feat/dart native skills install#481
Pratikdate wants to merge 11 commits into
StacDev:devfrom
Pratikdate:feat/dart-native-skills-install

Conversation

@Pratikdate
Copy link
Copy Markdown

@Pratikdate Pratikdate commented Jun 6, 2026

Description

This PR implements a Dart/Flutter-native path for installing Stac skills without requiring Node, npm, or npx, addressing issue #479 (or the relevant issue ID). It adds a new stac skills add CLI command and integrates it into the stac init flow.

Key Changes

  • New Command (stac skills add):
    • Download and extraction of repository ZIP archive using dio and archive.
    • Parses skills/catalog.json from the repository root to find registered skills.
    • Copies specific skill directories to .agents/skills relative to the target directory.
    • Cleans up all downloaded temporary files reliably.
  • Enhanced Security:
    • Prevents path-traversal attacks by validating skillName and skillPath against patterns like .., absolute paths, and backslashes, ensuring all extractions stay within boundaries.
  • Project Initialization Integration:
    • stac init now prompts the user to optionally install Stac agent skills as part of the setup flow.
  • Tests & Documentation:
    • Added unit tests verifying command registration, subcommand registration, and AddCommand attributes.
    • Updated docs/skills.mdx to prioritize the native CLI pathway over npx.

Related Issues

Closes #479 (or insert the correct issue number here)

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Code refactor
  • Build configuration change
  • Documentation
  • Chore

Summary by CodeRabbit

  • New Features

    • Added a new "skills" command group with an "add" subcommand to install Stac AI agent skills into projects.
    • Project initialization now prompts users to install skills during setup.
  • Documentation

    • Updated installation instructions to show the native CLI install and an alternative npx-based method.
  • Tests

    • Added CLI and file-utility tests, including safety checks and cleanup validation.

Pratikdate and others added 10 commits April 3, 2026 17:19
- Add SkillsCommand with 'stac skills add' subcommand
- AddCommand fetches repo ZIP, parses skills/catalog.json,
  and copies skill dirs into .agents/skills/ — no Node/npm required
- Prompt users in 'stac init' to optionally install agent skills
- Register SkillsCommand in the CLI runner
- Add archive: ^4.0.9 dependency for ZIP extraction
- Update docs/skills.mdx to show Dart-native path first,
  keeping npx as an alternative
- Add tests for SkillsCommand and AddCommand (7 tests pass)

Closes StacDev#480
- Move tempDir cleanup into finally block so temp files are always
  removed even on early return or exception
- Validate skillName and skillPath from catalog.json to prevent
  path-traversal attacks (reject '..', absolute paths, backslashes,
  and enforce canonical boundary checks)
- Accept optional targetDirectory in AddCommand so stac init installs
  skills into the correct project directory, not Directory.current
- Handle non-zero exit from AddCommand in init with a warning instead
  of silently printing success
- Assert non-null and correct type before casting in test to give
  cleaner failure output
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

Need the big picture first? Review this PR in Change Stack to see what changed before going file by file.

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 257106a6-c5f3-4f04-895e-4a6aaf4c7f60

📥 Commits

Reviewing files that changed from the base of the PR and between 30d4eb6 and 533b66c.

📒 Files selected for processing (2)
  • packages/stac_cli/lib/src/commands/skills/add_command.dart
  • packages/stac_cli/test/commands/cli_commands_test.dart
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stac_cli/lib/src/commands/skills/add_command.dart

📝 Walkthrough

Walkthrough

This PR introduces a new stac skills add CLI command for downloading and installing AI agent skills from a GitHub repository. The command validates paths to prevent directory traversal attacks, manages the .agents/skills/ installation directory, and integrates an interactive prompt into the initialization workflow. Tests validate command registration and file utility operations. Documentation is updated to reflect the native CLI installation method.

Changes

Skills Installation Feature

Layer / File(s) Summary
AddCommand and helpers
packages/stac_cli/lib/src/commands/skills/add_command.dart
AddCommand downloads HEAD.zip from a GitHub repo, extracts it, parses skills/catalog.json, validates catalog entries (traversal and canonical-boundary checks), and recursively copies skill directories into <target>/.agents/skills/. Includes containsPathTraversal and _copyDirectory.
SkillsCommand group & dependency
packages/stac_cli/lib/src/commands/skills_command.dart, packages/stac_cli/pubspec.yaml
Adds SkillsCommand (registers AddCommand) and adds archive: ^4.0.9 dependency.
CLI entrypoint registration
packages/stac_cli/bin/stac_cli.dart
Imports and registers SkillsCommand on the main stac CommandRunner, exposing stac skills add.
Init workflow integration
packages/stac_cli/lib/src/commands/init_command.dart
Prompts user during stac init to install skills and runs AddCommand in the project target directory, warning if installation exits non-zero.
CLI & AddCommand tests
packages/stac_cli/test/commands/cli_commands_test.dart
Tests verify CLI command registration (skills / add), AddCommand metadata (name, description, requiresAuth), path-traversal detection, and temporary directory cleanup after a failing run.
FileUtils tests
packages/stac_cli/test/utils/file_utils_test.dart
Unit and integration tests for FileUtils.homeDirectory, configDirectory, ensureConfigDirectory, and file I/O helpers with temp sandbox cleanup.
Docs update
docs/skills.mdx
Replaces prior single npx-centric install framing with native stac skills add as primary installation and keeps an npx alternative.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AddCommand
  participant GitHub
  participant FileSystem
  Client->>AddCommand: execute(repoUrl?)
  AddCommand->>GitHub: GET /archive/HEAD.zip
  GitHub-->>AddCommand: ZIP archive
  AddCommand->>FileSystem: extract ZIP to tempDir
  AddCommand->>FileSystem: read skills/catalog.json
  AddCommand->>AddCommand: validate entries (containsPathTraversal, canonical checks)
  AddCommand->>FileSystem: copy skill dirs -> <target>/.agents/skills/
  AddCommand->>FileSystem: remove tempDir
  AddCommand-->>Client: exit code (0/1)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • StacDev/stac#446: Earlier edits to docs/skills.mdx that introduced the initial skills documentation and npx install instructions; this PR updates that same documentation to prefer the native CLI flow.

Suggested reviewers

  • Potatomonsta

Poem

🐰 A skills command hops in with archive in paw,
Downloads and validates with meticulous care,
Path traversal thwarted—no escaping allowed,
Init prompts softly: "Shall I fetch skills here?"
CLI, tests, and docs together—fluffy and fair.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR objectives describe implementing a stac skills add command and integrating it into stac init, but the linked issue #479 focuses on a stac dev local development workflow with no mention of skills installation. Verify that this PR is linked to the correct issue. If #479 is incorrect, link it to an issue that describes the skills installation feature.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'Feat/dart native skills install' directly describes the main change: adding a Dart-native CLI command (stac skills add) to install Stac skills, replacing the prior npx-based approach.
Out of Scope Changes check ✅ Passed The PR changes are focused on skills installation (new SkillsCommand, AddCommand, documentation updates) and align with PR objectives, with no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/stac_cli/test/commands/cli_commands_test.dart (1)

76-87: 🏗️ Heavy lift

Behavior-critical AddCommand paths still need focused tests.

Current tests validate metadata only. Please add cases for traversal rejection, invalid catalog entries, and temp-dir cleanup in finally so regressions in install safety are caught.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/stac_cli/test/commands/cli_commands_test.dart` around lines 76 - 87,
Add focused unit tests in packages/stac_cli/test/commands/cli_commands_test.dart
for AddCommand that exercise its runtime behavior (not just metadata): add a
test that simulates filesystem traversal attempting to escape the target
directory and assert the command rejects it (reference AddCommand's
traversal/validation logic), add a test that supplies invalid/malformed catalog
entries and asserts the command fails with the expected error handling path
(reference the parsing/validation routine used by AddCommand), and add a test
that forces an error during install to verify the temporary directory is always
deleted in the finally/cleanup block (assert temp-dir does not remain after
failure). Ensure each test constructs AddCommand, invokes the same execution
method used by the CLI (e.g., run/execute), stubs/mocks IO as needed, and
asserts both the failure mode and that cleanup code ran.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/stac_cli/lib/src/commands/skills/add_command.dart`:
- Around line 111-120: The loop that reads catalog entries uses skill['name']
and skill['path'] without type-checking and then casts to String for
_containsPathTraversal, which can throw on non-string values; update the loop in
add_command.dart to first check that skillName and skillPath are Strings (e.g.,
skill['name'] is String and skill['path'] is String) before calling
_containsPathTraversal or casting, and if either is not a String skip the entry
(log a warning via ConsoleLogger.warning mentioning the malformed entry) so a
single bad catalog item cannot abort the install flow.
- Around line 130-137: Replace the fragile prefix check on canonicalized paths
(sourceCanonical.startsWith(repoRootCanonical)) with a robust containment test
using path.isWithin(repoRootCanonical, sourceCanonical) or equality check to
ensure the source is either equal to or strictly inside the repo root; update
the same logic where target/skill paths are validated. In addition, harden
_copyDirectory to avoid symlink traversal by calling Directory.list(...,
followLinks: false) and explicitly handling Link/File/Directory entities
(resolving or skipping links) so you never recursively follow symlinks that
could escape repo/target boundaries; ensure any copied path is re-canonicalized
and validated with path.isWithin before writing to the destination.

---

Nitpick comments:
In `@packages/stac_cli/test/commands/cli_commands_test.dart`:
- Around line 76-87: Add focused unit tests in
packages/stac_cli/test/commands/cli_commands_test.dart for AddCommand that
exercise its runtime behavior (not just metadata): add a test that simulates
filesystem traversal attempting to escape the target directory and assert the
command rejects it (reference AddCommand's traversal/validation logic), add a
test that supplies invalid/malformed catalog entries and asserts the command
fails with the expected error handling path (reference the parsing/validation
routine used by AddCommand), and add a test that forces an error during install
to verify the temporary directory is always deleted in the finally/cleanup block
(assert temp-dir does not remain after failure). Ensure each test constructs
AddCommand, invokes the same execution method used by the CLI (e.g.,
run/execute), stubs/mocks IO as needed, and asserts both the failure mode and
that cleanup code ran.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: c18dbf50-3131-4008-9aa7-9e634c67460b

📥 Commits

Reviewing files that changed from the base of the PR and between 29491d8 and 30d4eb6.

⛔ Files ignored due to path filters (1)
  • packages/stac_cli/pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • docs/skills.mdx
  • packages/stac_cli/bin/stac_cli.dart
  • packages/stac_cli/lib/src/commands/init_command.dart
  • packages/stac_cli/lib/src/commands/skills/add_command.dart
  • packages/stac_cli/lib/src/commands/skills_command.dart
  • packages/stac_cli/pubspec.yaml
  • packages/stac_cli/test/commands/cli_commands_test.dart
  • packages/stac_cli/test/utils/file_utils_test.dart

Comment thread packages/stac_cli/lib/src/commands/skills/add_command.dart
Comment thread packages/stac_cli/lib/src/commands/skills/add_command.dart
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.

2 participants