Skip to content
This repository was archived by the owner on Feb 8, 2026. It is now read-only.

Fix invalid target path bug and add recursive dependency installation#10

Merged
EdwardIrby merged 7 commits intomainfrom
fix/issue-9
Jan 22, 2026
Merged

Fix invalid target path bug and add recursive dependency installation#10
EdwardIrby merged 7 commits intomainfrom
fix/issue-9

Conversation

@EdwardIrby
Copy link
Copy Markdown
Member

Summary

  • Fixes issue Error installing #9 where skills were skipped with "invalid target path" error during installation when using relative paths for skills_dir
  • Adds automatic recursive dependency installation that detects inherited skills referencing known projects and installs them from source

Changes

Bug Fix (Issue #9)

The path validation in validate_path_within_dir failed when skills_dir was relative because the code tried to navigate to the relative path from a different working directory. Fixed by resolving the dirname of target_path directly from the original working directory.

Recursive Dependency Installation

When installing a project like agent-eval-harness that contains inherited skills (e.g., typescript-lsp@plaited_development-skills), the installer now:

  1. Detects that the inherited skill references development-skills (a known project in projects.json)
  2. Automatically installs development-skills first as a dependency
  3. Skips the inherited copy to avoid duplicates

This works recursively for transitive dependencies.

Test plan

  • All 117 tests pass (14 new tests added)
  • Manual test: ./install.sh --agent claude --project agent-eval-harness should install without "invalid target path" errors
  • Verify skills directory contains expected files with correct scoping

🤖 Generated with Claude Code

EdwardIrby and others added 4 commits January 21, 2026 16:54
- Fix stale SHA256 checksum that was causing install errors
- Add GitHub Action to automatically regenerate checksum when
  projects.json changes on main branch

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add concurrency group to prevent race conditions
- Add explicit error handling for shasum command
- Add comment explaining workflow purpose

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes issue #9 where skills were skipped with "invalid target path" error
when skills_dir was a relative path. The path validation logic now resolves
paths from the original working directory.

Also adds recursive dependency installation:
- Detects when inherited skills reference known projects in projects.json
- Automatically installs dependency projects first
- Skips inherited skills that will be installed from their source project
- Tracks installed projects to prevent infinite loops

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude bot commented Jan 22, 2026

Pull Request Review - PR #10

Summary

This PR addresses issue #9 (invalid target path errors with relative paths) and adds automatic recursive dependency installation. The implementation is generally solid with good test coverage (14 new tests, 117 total passing), but there are several areas that need attention.


🔴 Critical Issues

1. Path Validation Logic Has a Flaw (install.sh:244)

The fixed path validation in validate_path_within_dir still has an edge case where if the target directory doesn't exist yet, target_dirname becomes empty, triggering the fallback without proper canonical resolution.

Recommendation: Ensure both paths use canonical resolution.

2. Infinite Loop Risk in Circular Dependencies (install.sh:679-720)

If a dependency fails to install (line 710), it continues without marking the failed project as installed. This could cause retry loops.

Recommendation: Mark failed projects to avoid retry loops.


⚠️ Security Concerns

3. Race Condition in GitHub Action (.github/workflows/update-sha256.yml)

The workflow has concurrency.cancel-in-progress: false which could allow two runs to generate different checksums.

Recommendation: Use cancel-in-progress: true or add file locking.

4. Checksum Update Bypasses CI

The [skip ci] means CI tests won't run after the checksum update, creating a blind spot.

Recommendation: Remove [skip ci] or add validation.


🟡 Code Quality Issues

5. Silent Dependency Installation Failures (install.sh:709-712)

Failed dependencies continue silently, creating degraded state. User sees "Installation Complete!" but skills are missing.

Recommendation: Track and report failed dependencies.

6. Missing Input Validation (install.sh:321-346)

get_skill_source_project extracts without validating scope format.

Recommendation: Add validation before extraction.


✅ Positives

  1. Excellent test coverage - 14 new tests
  2. Clear documentation - Good function comments
  3. Security-conscious - Path validation improvements
  4. Backward compatibility - Graceful handling of unknown sources
  5. Good error messages - Clear and actionable
  6. Atomic operations - Safe file handling

🎯 Priority

Must Fix Before Merge:

  1. Path validation edge case
  2. Infinite loop prevention
  3. GitHub Action race condition

Should Fix:
4. CI skip concerns
5. Failed dependency tracking


Overall Assessment

Well-implemented feature with solid testing, but critical issues need addressing. The dependency resolution logic is sound, but error handling needs refinement.

Recommendation: Request changes for critical issues, then approve after fixes.

@claude
Copy link
Copy Markdown

claude bot commented Jan 22, 2026

Pull Request Review

This PR addresses two important issues: (1) Bug Fix for issue #9 where skills failed with invalid target path error when using relative paths, and (2) Feature for recursive dependency installation for inherited skills.

Overall, this is a well-implemented fix with excellent test coverage (14 new tests added, bringing total to 117).

Strengths

Code Quality

  • Excellent documentation with clear comments
  • Good separation of concerns - dependency detection functions are logically grouped
  • Comprehensive test coverage: 784 lines of new tests
  • Clear function names like get_skill_source_project and install_project_with_dependencies

Bug Fix (install.sh:242-245)
The path validation fix is elegant - it resolves dirname from the original working directory where the relative path makes sense.

Security

  • Path validation still rejects traversal attempts (verified by tests)
  • No new security vulnerabilities
  • Maintains security check at install.sh:599

Potential Issues and Suggestions

1. Infinite Loop Protection (install.sh:304-320) - Severity: Medium
Uses space-separated string for tracking. If project name contains spaces or special regex characters, this could fail. Consider validating project names don't contain spaces.

2. Error Handling in get_project_dependencies (install.sh:350-379) - Severity: Low
sparse_path cat command has no error checking. If .sparse_path doesn't exist or is empty, fails silently. Add file existence check.

3. Circular Dependency Detection (install.sh:677-720) - Severity: Medium
No explicit detection/warning for circular dependencies. While infinite loops are prevented, circular relationships aren't reported to users.

4. Performance (install.sh:336) - Severity: Low
get_project_names is called for every scoped skill, parsing entire projects.json each time. Consider caching the result.

5. Test Coverage Gap - Severity: Low
Missing tests for: circular dependencies, missing .sparse_path file, full recursive chains (A to B to C).

Best Practices

Positive:

  • Atomic operations with proper cleanup
  • Informative user messages
  • Fail-safe approach on dependency failures
  • Tests use realistic scenarios

Could Improve:

  • Add --debug flag for dependency resolution tree
  • Document global variable lifecycle

Security Assessment

No security concerns. Changes maintain path validation, don't introduce new input vectors, don't modify permissions, and tests verify traversal attacks are blocked.

Performance

Overall good. Recursive resolution is depth-first (appropriate). Space: O(n), Time: O(n*m). Minor optimization: cache get_project_names.

Recommendations

Must Fix: None - code is functional and safe

Should Fix:

  1. Add error checking for missing .sparse_path file
  2. Add test coverage for edge cases
  3. Consider caching get_project_names

Future Enhancement:

  1. Debug flag for dependency resolution
  2. Explicit circular dependency detection
  3. Document global variables

Conclusion

This is a high-quality PR that successfully addresses the issues with proper testing. Recursive dependency resolution is well-designed and path validation fix is correct.

Recommendation: Approve with minor suggestions

Suggestions are optimizations and defensive programming enhancements, not blockers. Code is ready to merge, suggestions can be addressed in follow-up PRs.

Great work on comprehensive test coverage!

- Fix path validation to reject when target directory doesn't exist
- Add failed project tracking to prevent infinite retry loops
- Report failed dependencies at installation completion
- Fix GitHub Action race condition (cancel-in-progress: true)
- Add input validation in get_skill_source_project
- Add error checking for missing .sparse_path file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude bot commented Jan 22, 2026

Code Review - PR #10

Summary

This PR addresses issue #9 (invalid target path errors with relative paths) and adds automatic recursive dependency installation. Well-structured with comprehensive test coverage (117 total tests, 14 new).

Strengths ✅

Bug Fix Quality (install.sh:242-255)

  • Resolves dirname from original working directory (fixes relative path handling)
  • Properly handles both relative and absolute paths
  • Maintains security by rejecting non-existent parent directories

Test Coverage

Excellent additions covering path validation, traversal prevention, dependency detection, and inherited skills.

Dependency Management

Well-designed recursive system with loop prevention, failure tracking, and clear user feedback.


CRITICAL Security Issues 🔴

1. Unvalidated .sparse_path Input (lines 387, 595)

RISK: Command Injection/Path Traversal

Malicious .sparse_path could contain: "; rm -rf / #" or ../../../etc

FIX: Add validation after reading:

if [[ "$sparse_path" =~ [^a-zA-Z0-9._/-] ]] || [[ "$sparse_path" =~ \.\. ]]; then
  print_error "Invalid .sparse_path"
  return 0
fi

Note: safe_read_file() exists (lines 46-63) but is unused.

2. Path Traversal via .sparse_path (lines 395, 603)

FIX: Resolve and validate paths stay within project_temp


Other Issues 🟡

3. Silent Error Handling (lines 377-420)

get_project_dependencies() returns empty string on all errors. Add logging so failures are visible.

4. Return Code Inconsistency (lines 771-774, 824)

Function returns 0/1/2 but caller treats any non-zero as failure. Projects with failed deps are marked installed but skipped in count.

5. Unexplained Workflow Change

Why change cancel-in-progress to true? Not mentioned in PR description.


Code Quality 💡

  • install_project() is 132 lines (580-712). Consider extracting logic.
  • get_project_names() called repeatedly. Cache result at session start.
  • Test file is 2740 lines. Consider splitting.

Must Fix Before Merge 🔴

  1. Validate .sparse_path content (security)
  2. Prevent path traversal via .sparse_path (security)
  3. Fix or document return code 2 handling
  4. Explain workflow change or revert

Should Fix 🟡

  1. Add logging for silent failures
  2. Cache get_project_names() result

Assessment

Code Quality: Good
Bug Fix: Correct
Feature: Well-designed
Security: Critical issues need fixing

Recommendation: Request changes for security fixes.

Great work on test coverage and dependency design!

Security fixes:
- Add validate_sparse_path() to prevent command injection and path traversal
- Apply validation in get_project_dependencies() and install_project()
- Reject special shell characters ($, `, (), |, &, ;, etc.)

Code quality improvements:
- Fix return code 2 handling (partial success now counts as installed)
- Cache get_project_names() result for better performance
- Add logging for silent failures in get_project_dependencies()
- Add 6 new tests for sparse_path validation (123 total tests)

Workflow change explanation:
- Changed cancel-in-progress to true in update-sha256.yml to prevent race
  conditions where multiple concurrent runs could generate different checksums

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@EdwardIrby
Copy link
Copy Markdown
Member Author

Review Feedback Addressed

Critical Security Fixes ✅

  1. Unvalidated .sparse_path Input - Added validate_sparse_path() function that:

    • Rejects path traversal (..)
    • Rejects absolute paths (/)
    • Rejects shell special characters ($, `, (), |, &, ;, etc.)
    • Only allows safe characters: alphanumeric, dots, hyphens, underscores, forward slashes
  2. Path Traversal via .sparse_path - Validation applied in both get_project_dependencies() and install_project() before using the path

Code Quality Fixes ✅

  1. Return Code Inconsistency - Fixed do_install() to properly handle return code 2 (partial success - project installed but some deps failed). Projects with partial success are now counted as installed.

  2. Silent Error Handling - Added logging in get_project_dependencies() for missing .sparse_path file and missing skills directory

  3. Performance - Added caching for get_project_names() result via CACHED_PROJECT_NAMES variable

Workflow Change Explanation ✅

  1. cancel-in-progress: true in update-sha256.yml:
    • Why: Prevents race conditions where two concurrent pushes to main could trigger parallel workflow runs
    • Risk with false: Both runs generate checksums at different times, potentially creating inconsistent state
    • With true: Newer run cancels older one, ensuring only the latest projects.json gets its checksum generated

Test Coverage

  • Added 6 new tests for validate_sparse_path() security validation
  • Total: 123 tests passing

@claude
Copy link
Copy Markdown

claude bot commented Jan 22, 2026

Pull Request Review - PR #10

Summary

This PR addresses two key issues:

  1. Bug Fix (Issue Error installing #9): Fixes invalid target path errors when using relative paths for skills_dir
  2. Feature: Adds automatic recursive dependency installation for inherited skills

Overall Assessment

Verdict: Approve with Minor Suggestions

The PR demonstrates excellent engineering practices with strong security awareness, comprehensive test coverage (14 new tests), and thoughtful error handling.


Code Quality & Best Practices

Strengths ✅

  1. Security-First Design

    • Excellent input validation in validate_sparse_path() at install.sh:237-267
    • Path traversal protection with proper canonicalization
    • Command injection prevention with comprehensive character filtering
  2. Performance Optimization

    • Smart caching of project names to avoid repeated JSON parsing
    • Efficient regex-based validation patterns
  3. Error Handling

    • Graceful fallback when dependencies fail
    • Clear error messages with actionable feedback
    • Failed project tracking prevents infinite retry loops
  4. Test Coverage

    • 14 new comprehensive tests covering edge cases
    • Tests for security validation (path traversal, command injection)
    • Tests for dependency detection and deduplication

Potential Issues & Suggestions

1. Path Validation Logic (install.sh:290-303)

Severity: Medium ⚠️

The fix for Issue #9 requires comment clarification. The code rejects paths where the parent directory doesn't exist, which is intentional for security but could be clearer.

Suggestion: Enhance the comment to explain that this ensures we only operate on paths within existing directory structures.

2. Dependency Installation Return Code (install.sh:828-831)

Severity: Low ℹ️

Return code 2 means partial success but could be better documented. Consider adding a comment explaining the tri-state return convention (0=success, 1=failure, 2=partial).

3. Missing Validation Check

The get_project_dependencies() function reads from .sparse_path file at install.sh:436 but could benefit from using safe_read_file() for consistency.

4. Dependency Deduplication (install.sh:464-466)

Severity: Low ℹ️

The space-padding deduplication technique is correct but subtle. A comment would help maintainability.


Security Analysis

Excellent Security Practices ✅

  1. validate_sparse_path() - Comprehensive validation preventing path traversal, absolute paths, command injection
  2. validate_path_within_dir() - Prevents path traversal before rm -rf operations
  3. SHA-256 Checksum Verification - Mandatory verification for remote downloads

Test Coverage Analysis

Excellent Coverage ✅

The PR adds 861 lines of tests covering:

  • Issue Error installing #9 fix with relative path handling
  • Dependency detection and deduplication
  • Inherited skill skipping
  • Security validation (path traversal, command injection)

Minor Suggestion: Add a test for transitive dependencies (A→B→C).


Recommendations

Must Address

None - the code is production-ready

Should Consider

  1. Clarify path validation comment
  2. Document return code 2 meaning
  3. Add comment for deduplication technique
  4. Use safe_read_file() for .sparse_path reading

Nice to Have

  1. Add transitive dependency test
  2. Update README with dependency installation feature
  3. Add progress indicator for multi-project installs

Conclusion

This is high-quality work that significantly improves the installer. The bug fix is correct, the new feature is well-implemented, and the security considerations are exemplary.

Recommendation: Approve and Merge

The suggestions above are minor improvements that could be addressed in follow-up PRs. None are blockers.

Great work! 🎉


Reviewed by: Claude Sonnet 4.5 (AI Code Review)

@EdwardIrby EdwardIrby merged commit eafba3b into main Jan 22, 2026
2 checks passed
@EdwardIrby EdwardIrby deleted the fix/issue-9 branch January 22, 2026 01:53
@EdwardIrby EdwardIrby mentioned this pull request Jan 22, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant