Manage Apple Reminders via the `remindctl` CLI on macOS (list, add, edit, complete, delete)....
npx skills add earthly/skills --skill "lunar-collector"
Install specific skill from multi-skill repository
# Description
Create Lunar collector plugins that gather SDLC metadata for guardrail enforcement. Use when building collectors (Bash scripts) that collect data from repositories, CI pipelines, or external APIs and write to the Component JSON. Covers hook types (code, cron, ci-after-command), the `lunar collect` command, plugin structure, containerization, and best practices.
# SKILL.md
name: lunar-collector
description: Create Lunar collector plugins that gather SDLC metadata for guardrail enforcement. Use when building collectors (Bash scripts) that collect data from repositories, CI pipelines, or external APIs and write to the Component JSON. Covers hook types (code, cron, ci-after-command), the lunar collect command, plugin structure, containerization, and best practices.
Lunar Collector Skill
Create collector plugins for Earthly LunarβBash scripts that gather SDLC metadata and write it to the Component JSON for policy evaluation.
Quick Start
- Read about-lunar.md for platform overview
- Read core-concepts.md for architecture and key entities
- Read collector-reference.md for comprehensive collector documentation
Collector Basics
A collector is a Bash script that:
1. Gathers data (from files, CI artifacts, external APIs)
2. Writes to the Component JSON using lunar collect
#!/bin/bash
set -e
if [ -f ./README.md ]; then
lunar collect -j ".repo.readme_exists" true \
".repo.readme_num_lines" "$(wc -l < ./README.md)"
else
lunar collect -j ".repo.readme_exists" false
fi
Plugin Structure
my-collector/
βββ lunar-collector.yml # Required: plugin config
βββ main.sh # Main script
βββ Dockerfile # Optional: for containerization
βββ README.md # Documentation
βββ install.sh # Optional: install dependencies
lunar-collector.yml:
version: 0
name: my-collector
description: Collects X data
author: [email protected]
default_image: earthly/lunar-scripts:1.0.0
collectors:
- name: my-collector
mainBash: main.sh
hook:
type: code # or: cron, ci-after-command, ci-after-job, etc.
inputs:
threshold:
description: Minimum threshold
default: "10"
Hook Types
| Hook | Trigger | Use Case |
|---|---|---|
code |
Git push | File analysis, config parsing |
cron |
Schedule | External API queries |
ci-after-command |
After CI command | Capture test coverage, scan results |
ci-after-job |
After CI job | Job-level artifact collection |
The lunar collect Command
# String value
lunar collect ".repo.language" "go"
# JSON values (use -j)
lunar collect -j ".repo.readme_exists" true
lunar collect -j ".coverage.percentage" 85.5
# Multiple values
lunar collect -j ".repo.readme_exists" true ".repo.readme_lines" 150
# Pipe JSON from stdin
cat results.json | lunar collect -j ".test.results" -
Environment Variables
| Variable | Description |
|---|---|
LUNAR_COMPONENT_ID |
Component identifier |
LUNAR_COMPONENT_PR |
PR number (if in PR context) |
LUNAR_COMPONENT_GIT_SHA |
Git SHA being evaluated |
LUNAR_PLUGIN_ROOT |
Plugin root directory |
LUNAR_SECRET_<NAME> |
Secrets |
Inputs are available as uppercase environment variables (e.g., THRESHOLD for input threshold).
Reference Documentation
For detailed information, read these files in the references/ directory:
| File | Content |
|---|---|
| about-lunar.md | Platform overview, why Lunar exists |
| core-concepts.md | Architecture, Component JSON, hooks, enforcement levels |
| collector-reference.md | Complete collector guide - hooks, environment variables, patterns |
| component-json/conventions.md | Component JSON schema design principles, presence detection, source metadata |
| component-json/structure.md | Component JSON schema categories (.repo, .k8s, .sca, etc.) with examples |
| strategies.md | Implementation strategies (CI detection, file parsing, API integration) |
| collector-README-template.md | README template for collector plugins |
Full Lunar Documentation
For the complete Lunar platform documentation including installation, configuration, CLI reference, and SDK details, see docs/SUMMARY.md.
Local Development & Testing
Run collectors locally to test before deploying. Commands must be run from a directory containing lunar-config.yml.
Prerequisites:
- Set LUNAR_HUB_TOKEN environment variable for authentication
- Be in a directory with a valid lunar-config.yml
Run a collector against a remote component:
lunar collector dev <collector-name> --verbose --component github.com/org/repo
Run a collector against a local directory:
lunar collector dev <collector-name> --verbose --component-dir ../path/to/local/repo
Test a CI collector with a fake command:
lunar collector dev <collector-name> --fake-ci-cmd "npm test" --component github.com/org/repo
Collector names are dot-separated (e.g., k8s.yaml-collection, dockerfile.base-images).
The command outputs the resulting Component JSON to stdout, which can be piped to lunar policy dev for end-to-end testing:
lunar collector dev my-collector --component github.com/org/repo | \
lunar policy dev my-policy --component-json -
Best Practices
- Always use
set -e- Exit on errors - Use structured JSON - Group related data together
- Include source metadata - Tool name, version, integration type
- Document Component JSON paths - In README.md
- Use
earthly/lunar-scripts:1.0.0- Official base image for containerized collectors - Handle missing data gracefully - Check file existence before processing
Common Patterns
File parsing with find command input:
inputs:
find_command:
description: Command to find files
default: "find . -type f -name '*.yaml'"
CI artifact collection:
# Hook: ci-after-command with pattern: ^go test.*
if [ -f coverage.out ]; then
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | tr -d '%')
lunar collect -j ".testing.coverage.percentage" "$COVERAGE"
fi
External API query:
RESPONSE=$(curl -fsS -H "Authorization: Bearer $LUNAR_SECRET_API_TOKEN" \
"https://api.example.com/repos/$LUNAR_COMPONENT_ID/status")
echo "$RESPONSE" | lunar collect -j ".external.status" -
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.