README
¶
intropy CLI
intropy is the command-line interface for working with Intropy integrations
and agent skills. It does two things:
- Scaffolds integrations from the official Intropy template library hosted at
integrio-intropy/intropy-templates. - Manages agent skills as OCI artifacts — adding, listing, updating, and
publishing skills (individually or as curated collections) against any OCI
registry. The skills subsystem implements the
Agent Skills OCI Artifacts Spec,
so artifacts published with
intropy skills publishinteroperate with any other spec-compliant tooling.
Install
Homebrew (macOS)
Distributed as a Homebrew cask (macOS only):
brew tap integrio-intropy/tap
brew trust --tap integrio-intropy/tap
brew install intropy
The brew trust step is required when HOMEBREW_REQUIRE_TAP_TRUST is set —
the default on current Homebrew (6.x+). On older versions without that
requirement you can skip it.
On Linux, use the quick install script below or download a binary from the releases page.
Quick install (macOS / Linux)
curl -fsSL https://github.com/integrio-intropy/intropy-cli/releases/latest/download/install.sh | sh
With options:
# Install to a custom prefix
curl -fsSL https://github.com/integrio-intropy/intropy-cli/releases/latest/download/install.sh | sh -s -- --prefix ~/.local
# Install a specific version
curl -fsSL https://github.com/integrio-intropy/intropy-cli/releases/latest/download/install.sh | sh -s -- --version v1.0.0
The script detects your OS and architecture, downloads the matching release archive, verifies the SHA256 checksum, optionally verifies the cosign signature, and installs the binary and shell completions.
Docker
Multi-arch images (linux/amd64, linux/arm64) are published to GHCR on every
release, built on distroless/static and running as a non-root user.
docker pull ghcr.io/integrio-intropy/intropy-cli:latest
# Scaffolding writes into the working directory: mount your project at /work
# and match your uid so files aren't owned by the container user
docker run --rm -v "$PWD:/work" --user "$(id -u):$(id -g)" \
ghcr.io/integrio-intropy/intropy-cli int create hello-world --name Orders
The image contains no shell — the binary is the entrypoint. Images are signed with cosign; verify with:
cosign verify \
--certificate-identity-regexp="https://github.com/integrio-intropy/intropy-cli" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/integrio-intropy/intropy-cli:latest
From source
Requires Go 1.26+.
git clone https://github.com/integrio-intropy/intropy-cli.git
cd intropy-cli
make build
Or manually:
go build -o bin/intropy ./cmd/intropy
Add bin/ to your PATH, or move the binary somewhere on your PATH.
Verifying signatures
Release binaries are signed with cosign using
keyless signing via GitHub Actions OIDC. Each release includes .sig and
.pem files for every archive.
# Download the archive, its .sig, and its .pem from the GitHub release
cosign verify-blob \
--certificate intropy_Darwin_arm64.tar.gz.pem \
--signature intropy_Darwin_arm64.tar.gz.sig \
--certificate-identity-regexp="https://github.com/integrio-intropy/intropy-cli" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
intropy_Darwin_arm64.tar.gz
Windows
Windows is not a supported native target. Install and run intropy inside
WSL 2 using the Linux
instructions above. The CLI relies on Unix path conventions and signal handling
that are not tested on Windows.
Version stamping
Version, commit, and build date are injected via -ldflags at release time:
go build -ldflags "\
-X main.version=$(git describe --tags --always) \
-X main.commit=$(git rev-parse --short HEAD) \
-X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o bin/intropy ./cmd/intropy
Check what you have with:
intropy version
Quickstart
Scaffold your first integration
# Inspect a template before you scaffold it
intropy int describe hello-world
# Render it into a new directory
intropy int create hello-world -o ./my-integration
Install a skill from a collection
# Register a collection (one-time)
intropy skills collection add --name intropy --ref harbor.intropy.io/skills/index:latest
# Install a skill by name
intropy skills add --name intropy-getting-started
# List what you have installed
intropy skills list
Command overview
intropy
├── int Manage integrations
│ ├── create <template> Scaffold a new integration from a template
│ ├── describe <template> Print a template's manifest and parameter schema
│ └── list [dir] List scaffolded integrations under a directory
├── manifests Manage deployment manifests
│ └── create Generate Kubernetes manifests for a scaffolded integration
├── skills Manage Intropy skills
│ ├── add [ref] Add and install a skill from an OCI registry
│ ├── list List installed skills
│ ├── update [name] Reconcile an installed skill against its collection
│ ├── publish Publish a skill directory to an OCI registry
│ └── collection Manage registered skill collections
│ ├── add Register a collection in skills.json
│ ├── update <alias> Refresh or bump a registered collection
│ └── publish <spec> <ref> Publish a collection as an OCI Image Index
└── version Print version information
Run any command with --help for full flag documentation.
Integrations (intropy int)
Describe a template
Inspect what parameters a template accepts before scaffolding it:
intropy int describe hello-world
intropy int describe hello-world --version v1.2.0
intropy int describe hello-world -o json # machine-readable; same schema Backstage renders
Without --version, the latest GitHub release is used.
Create an integration
intropy int create hello-world --output ./my-integration
Name the integration and scaffold it in one step. -n/--name sets the template's
name parameter (so you're not prompted for it) and, unless -o is given, becomes
the output directory:
# scaffolds into ./orders and sets name=orders
intropy int create hello-world -n orders
# -o still overrides the output directory
intropy int create hello-world -n orders -o ./my-integration
Provide parameter values inline, from files, or interactively:
# inline
intropy int create hello-world -o ./out --set name=orders --set owner=team-x
# from a values file (repeatable; use - for stdin)
intropy int create hello-world -o ./out -f values.yaml
# disable interactive prompts (fail fast on missing required values)
intropy int create hello-world -o ./out --no-input -f values.yaml
# write a machine-readable result document (consumed by chained scaffolders)
intropy int create hello-world -o ./out --output-json result.json
Use --force to render into a non-empty directory.
After scaffolding, int create offers to install the Intropy agent skills
collection (harbor.intropy.io/skills/index:latest) into the new
integration's .agents/skills/ — a [Y/n] prompt in interactive sessions,
skipped under --no-input or when stdin is not a terminal. For CI and other
non-interactive runs, --install-skills installs without prompting;
--skip-install-skills suppresses the prompt and the install entirely:
intropy int create hello-world -n orders --no-input --install-skills -f values.yaml
intropy int create hello-world -n orders --skip-install-skills
Set INTROPY_SKILLS_COLLECTION to point the install at a different
collection ref (e.g. a local registry when testing).
int create also writes a scaffold record to .intropy/scaffold.json inside
the new integration — the template name, the exact release version, and the
resolved parameter values. Commit it: later commands (like
intropy manifests create) read it to reproduce decisions made at scaffold
time.
List scaffolded integrations
Discover every integration under a directory tree — each project is
identified by its committed .intropy/scaffold.json record:
# walk down from the current directory
intropy int list
# or from an explicit root
intropy int list ~/dev/integrations
# machine-readable, including the pinned source and scaffold values
intropy int list -o json
The walk skips .git, node_modules, bin and dist, and doesn't descend
into a project once matched (projects don't nest). Projects with an unreadable
record are reported as warnings on stderr without hiding the rest.
Deployment manifests (intropy manifests)
Generate Kubernetes manifests
Run inside a scaffolded integration (any subdirectory works — the command
walks up to find .intropy/scaffold.json):
intropy manifests create
This re-fetches the template at the exact version pinned in
.intropy/scaffold.json and renders its manifests/ templates into a
kustomize tree:
deploy/
├── base/ Deployment + Service with Dapr sidecar annotations
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/
├── dev/ Dapr components for local-style backends
└── prod/ Real-broker placeholders, secrets via secretKeyRef
Values recorded at scaffold time (like name and appPort) pre-fill the
matching manifest parameters, so you're only asked for what's new — typically
the container image:
# inline
intropy manifests create --set imageRepository=ghcr.io/acme/orders --set imageTag=1.0.0
# non-interactive (fail fast on missing required values)
intropy manifests create --no-input -f deploy-values.yaml
# elsewhere than deploy/, or on top of existing files
intropy manifests create -o ./k8s --force
# newer template release than the one pinned at scaffold time
intropy manifests create --version v1.5.0
# machine-readable result document (consumed by chained tooling)
intropy manifests create --output-json -
Projects scaffolded before .intropy/scaffold.json existed get an error
explaining how to add the file by hand; templates whose pinned release
predates manifests/ templates are told to pass --version with a newer
tag.
Validate the result with kustomize build deploy/overlays/dev (or point your
GitOps tooling at an overlay directly).
Skills (intropy skills)
Skills are stored as OCI artifacts following the Agent Skills OCI Artifacts Spec — config schema, layer layout, and annotations all conform to it, so anything the CLI publishes can be consumed by other spec-compliant clients (and vice-versa). The CLI maintains two files at the project root:
skills.json— declares registered collections and installed skills (committed).skills.lock.json— pins resolved digests and install paths (committed).
Skills install into .agents/skills/<name>/ (the canonical layout from §9 of
the spec). Additional install locations can be configured per skill via
--also-install-to.
Add a skill
By full OCI reference:
intropy skills add harbor.intropy.io/skills/intropy-pipeline:0.1.0
By name, resolved through a registered collection:
intropy skills add --name intropy-pipeline
intropy skills add --name intropy-pipeline --collection intropy # disambiguate
If no skills.json exists in the working directory or any parent, an empty one
is created in the current directory.
List installed skills
intropy skills list
intropy skills list -o json # machine-readable output
Update a skill
update reconciles an installed skill against the ref currently pinned by its
collection's cached index. If the collection upstream has been republished, run
intropy skills collection update <alias> first to refresh the cache.
intropy skills update intropy-pipeline
intropy skills update --all
intropy skills update --all -o json # machine-readable results
Publish a skill
Package a skill directory as an OCI artifact and push it:
intropy skills publish \
--path ./skills/intropy-pipeline \
--ref harbor.intropy.io/skills/intropy-pipeline \
--tag 0.1.0
Use --force to overwrite an existing tag, and --sign to sign the artifact
with cosign after publishing (requires cosign on PATH).
Collections
A collection is an OCI Image Index that pins a curated set of skills by digest. Registering a collection lets you install its skills by name.
Register a collection
intropy skills collection add \
--name intropy \
--ref harbor.intropy.io/skills/index:latest
intropy skills collection add \
--name intropy \
--ref harbor.intropy.io/skills/index:latest \
-o json # machine-readable confirmation
The collection's index is fetched and cached under
.intropy/collections/<alias>.json for offline name lookups.
Refresh or bump a collection
Re-pull in place (useful when the upstream tag is moving, e.g. :latest):
intropy skills collection update intropy
Replace the registered ref with a new value (e.g. bump to a new release tag):
intropy skills collection update intropy --ref harbor.intropy.io/skills/index:2026.07
Publish a collection
Write a YAML spec listing the skills to include, then publish:
# intropy-skills.yaml
name: intropy-skills
description: Curated Intropy skills
skills:
- ref: harbor.intropy.io/skills/intropy-pipeline:0.1.0
- ref: harbor.intropy.io/skills/intropy-blocks:0.1.0
intropy skills collection publish intropy-skills.yaml harbor.intropy.io/skills/index:latest
Each referenced skill is resolved to its current digest at publish time, so the collection pins exact content even if upstream tags later move.
Authentication
OCI operations use the standard Docker credential chain — log in once with
docker login, gh auth login (for ghcr.io), or your registry-specific
tooling, and the CLI will pick up the credentials transparently.
Project layout
cmd/intropy/ Cobra command wiring (one file per command)
internal/blueprint/ Template download, validation, describe, render
internal/skill/ skills.json/lockfile, install/update/add, collection cache
internal/skill/oci/ OCI client wrappers, pack/push/pull, references
Exit codes
0— success1— runtime error2— usage error (unknown command, missing required flag, bad argument)
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
intropy int create fails with "template not found" |
The template name is misspelled or does not exist in the library. | Run intropy int describe <name> to verify the template exists. Check spelling and case. |
intropy skills add fails with "unauthorized" |
Missing or expired registry credentials. | Run docker login <registry> or gh auth login (for ghcr.io) and retry. |
intropy skills add --name <skill> fails with "not found" |
The skill name is not in any registered collection, or the collection cache is stale. | Run intropy skills collection update <alias> to refresh the cache, or install by full OCI ref. |
skills.json merge conflicts |
Multiple contributors edited skills.json or skills.lock.json simultaneously. |
Resolve the conflict manually (both files are plain JSON), then run intropy skills list to verify. |
| Windows native errors | Running the Linux binary directly on Windows without WSL. | Use WSL 2 — native Windows is not supported. |
For issues not listed here, run the failing command with --help to verify flag usage, or open an issue with the output of intropy version and the exact command you ran.
Contributing
See CONTRIBUTING.md for build instructions, code standards, and the pull request workflow.
References
- Agent Skills OCI Artifacts Spec
— the packaging, distribution, signing, and tracking spec the
skillssubsystem implements. integrio-intropy/intropy-templates— the template libraryintropy int createandintropy int describedownload from by default.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
intropy
command
|
|
|
internal
|
|
|
deploy
Package deploy generates Kubernetes deployment manifests (a kustomize base + overlays tree) for a previously scaffolded integration.
|
Package deploy generates Kubernetes deployment manifests (a kustomize base + overlays tree) for a previously scaffolded integration. |
|
template
Package template downloads, validates, describes, and renders Intropy scaffolding templates.
|
Package template downloads, validates, describes, and renders Intropy scaffolding templates. |