Skip to content

Feat/dart native skills install#481

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

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

Conversation

@Pratikdate

@Pratikdate Pratikdate commented Jun 6, 2026

Copy link
Copy Markdown

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

    • Introduced the stac skills add command to simplify installation of Stac AI agent skills into your projects
    • Project initialization workflow now includes a guided prompt to install skills during setup
  • Documentation

    • Updated installation instructions to showcase the native Stac CLI installation method with npx as an alternative approach

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

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: 034988e8-3f08-4f93-b04a-88e32289c910

📥 Commits

Reviewing files that changed from the base of the PR and between 35a4a5f and 617e321.

⛔ Files ignored due to path filters (4)
  • examples/counter_example/pubspec.lock is excluded by !**/*.lock
  • examples/movie_app/pubspec.lock is excluded by !**/*.lock
  • examples/stac_gallery/pubspec.lock is excluded by !**/*.lock
  • packages/stac_cli/pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • 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
✅ Files skipped from review due to trivial changes (1)
  • docs/skills.mdx
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/stac_cli/bin/stac_cli.dart
  • packages/stac_cli/lib/src/commands/skills_command.dart
  • packages/stac_cli/lib/src/commands/skills/add_command.dart

📝 Walkthrough

Walkthrough

Adds a new stac skills add CLI command implemented in AddCommand, which downloads a GitHub repository ZIP, parses skills/catalog.json, validates entries with path-traversal checks and canonical-boundary enforcement, and copies skill directories into <target>/.agents/skills. A SkillsCommand group registers the subcommand and is wired into the main CLI runner. InitCommand gains an interactive skills-install prompt. The archive package dependency is added, and docs/skills.mdx is updated to reflect the native install path.

Changes

Skills Installation Feature

Layer / File(s) Summary
AddCommand implementation and archive dependency
packages/stac_cli/pubspec.yaml, packages/stac_cli/lib/src/commands/skills/add_command.dart
AddCommand downloads HEAD.zip from a GitHub repo, extracts it, reads skills/catalog.json, validates each entry via containsPathTraversal and canonical path boundary checks, recursively copies skill directories into <target>/.agents/skills using _copyDirectory, cleans up the temp directory in a finally block, and returns 0/1. archive ^4.0.9 added to pubspec.
SkillsCommand group and CLI registration
packages/stac_cli/lib/src/commands/skills_command.dart, packages/stac_cli/bin/stac_cli.dart
SkillsCommand defines the skills command group and registers AddCommand as a subcommand. The main stac CLI runner imports and registers SkillsCommand alongside existing commands.
Init workflow integration
packages/stac_cli/lib/src/commands/init_command.dart
InitCommand imports AddCommand, prompts the user to install agent skills after project initialization, executes AddCommand in the target directory, and logs a warning on a non-zero exit code.
Documentation update
docs/skills.mdx
Installation instructions updated to show stac skills add as the primary method and npx as an alternative.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • StacDev/stac#446: Both this PR and #446 modify docs/skills.mdx installation instructions for Stac Skills.

Suggested reviewers

  • Potatomonsta

Poem

🐇 Hippity-hop, a skill download drops,
From GitHub's ZIP through traversal-check stops,
The catalog parsed, each path safely bound,
.agents/skills where new helpers are found,
stac skills add — the command resounds!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements native Stac CLI skills installation, but linked issue #479 specifies objectives for a local dev workflow with screens/themes testing, API configuration, and file watching—entirely different in scope and objectives. This PR should be linked to a different issue tracking skills installation features (if one exists), or the linked issue should be corrected to reflect the actual PR scope.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/dart native skills install' clearly and concisely describes the main change: implementing a native Dart/CLI-based pathway for installing Stac skills without Node/npm dependencies.
Out of Scope Changes check ✅ Passed All changes cohesively implement the skills installation feature: CLI command registration, skill discovery/installation logic, integration with project init, documentation updates, and dependency management.
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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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
@Potatomonsta

Copy link
Copy Markdown
Contributor

Hey @Pratikdate
I noticed this PR includes quite a few commits from the unit-tests PR (8f8f208, 4db325e, etc.).
Can you please drop those from this branch so this PR only contains the skills install changes?

@Pratikdate

Copy link
Copy Markdown
Author

Thanks for catching that. Those commits were pulled in accidentally when I branched off the wrong base.

I'll clean up the branch and remove the unit-tests commits (8f8f208, 4db325e, etc.) so the PR only contains the skills install changes. I'll update the PR shortly.

- 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
@Pratikdate Pratikdate force-pushed the feat/dart-native-skills-install branch from 35a4a5f to 617e321 Compare June 15, 2026 15:56
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