port-cli

module
v0.3.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: MIT

README ΒΆ

Port CLI

A modular command-line interface for Port that enables data import/export, organization migration, and API operations using a pluggable module architecture.

Features

  • πŸ“€ Export: Backup Port data (blueprints, entities, scorecards, actions, teams, automations, pages, integrations)
  • πŸ“₯ Import: Restore data from backups
  • πŸ”„ Migrate: Transfer data between Port organizations
  • πŸ” Compare: Diff two Port organizations and generate reports (text, JSON, HTML)
  • πŸ—‘οΈ Clear: Bulk-delete org resources (blueprints, entities, actions, scorecards, automations, pages)
  • πŸ”Œ API Operations: Direct CRUD operations on Port resources
  • πŸ€– Skills: Sync AI skills from Port into your local AI coding tools (Cursor, Claude Code, Gemini CLI, OpenAI Codex, Windsurf, GitHub Copilot)

Installation

Through npm

Global installation:

npm install -g @port-experimental/port-cli

Use with npx (no installation needed):

npx @port-experimental/port-cli --version

Local installation in your project:

npm install @port-experimental/port-cli
Quick Install Script

Linux/macOS:

curl -fsSL https://raw.githubusercontent.com/port-experimental/port-cli/main/scripts/install.sh | bash

This will download and install the latest release binary to /usr/local/bin (or ~/.local/bin if you don't have write permissions).

Verify installation:

port --version
Binary Releases

Download pre-built binaries for your platform from GitHub Releases.

Docker

Build the image:

docker build -t port-cli .

Run a command:

docker run --rm \
  -e PORT_CLIENT_ID="your-client-id" \
  -e PORT_CLIENT_SECRET="your-client-secret" \
  port-cli --help

Export with output written to the host:

docker run --rm \
  -e PORT_CLIENT_ID="your-client-id" \
  -e PORT_CLIENT_SECRET="your-client-secret" \
  -v $(pwd)/output:/data \
  port-cli export --output /data/backup.tar.gz
Build from Source

For development or if you need the latest unreleased code:

git clone https://github.com/port-experimental/port-cli.git
cd port-cli
make build
./bin/port --help

Note: When building from source, use ./bin/port instead of port in commands. For installed binaries, use port directly.

See INSTALL.md for detailed installation instructions.

Quick Start

1. Configure Credentials

Run port config --init to create a configuration file at ~/.port/config.yaml:

default_org: production

organizations:
  production:
    client_id: your-client-id
    client_secret: your-client-secret
    api_url: https://api.getport.io/v1

Or use environment variables:

export PORT_CLIENT_ID="your-client-id"
export PORT_CLIENT_SECRET="your-client-secret"
export PORT_API_URL="https://api.getport.io/v1"
2. Run Commands
# Export data
port export --output backup.tar.gz

# Import data
port import --input backup.tar.gz

# Compare organizations
port compare --source staging --target production

# Migrate between organizations
port migrate --source-org prod --target-org staging

# Clear org resources (destructive β€” see Clear Organization Resources below)
port clear --entities --blueprint service --force

# API operations
port api blueprints list

# Install AI skill hooks (one-time setup)
port skills init

Note: If you built from source instead of installing, use ./bin/port instead of port in the commands above.

Commands

  • port export - Export data from Port
  • port import - Import data to Port
  • port compare - Compare two Port organizations
  • port migrate - Migrate data between organizations
  • port clear - Delete org resources in bulk (blueprints, entities, actions, etc.)
  • port api - Direct API operations (blueprints, entities)
  • port skills - Manage Port AI skill hooks and local skill sync
  • port cache - Manage locally cached Port CLI data (e.g. port cache clear β€” local only, not org resources)
  • port config - Manage configuration
  • port version - Show version

Development

Go CLI Development
# Build
make build

# Run tests
make test

# Format code
make format

# Lint
make lint

Project Structure

port-cli/
β”œβ”€β”€ cmd/port/              # Go CLI entry point
β”œβ”€β”€ internal/              # Go implementation
β”‚   β”œβ”€β”€ api/              # API client
β”‚   β”œβ”€β”€ config/           # Configuration management
β”‚   β”œβ”€β”€ commands/         # CLI commands
β”‚   β”œβ”€β”€ modules/          # Business logic modules
β”‚   └── output/           # Output formatters
β”œβ”€β”€ go.mod                # Go dependencies
└── Makefile              # Go build

Configuration

Configuration File

Create ~/.port/config.yaml:

default_org: production

organizations:
  production:
    client_id: your-client-id
    client_secret: your-client-secret
    api_url: https://api.getport.io/v1
    
  staging:
    client_id: staging-client-id
    client_secret: staging-client-secret
    api_url: https://api.getport.io/v1
Environment Variables
PORT_CLIENT_ID          # Port API client ID
PORT_CLIENT_SECRET      # Port API client secret  
PORT_API_URL            # Port API URL (optional, default https://api.getport.io/v1)
PORT_CONFIG_FILE        # Path to config file
PORT_DEFAULT_ORG        # Default organization name
PORT_DEBUG              # Enable debug mode

Precedence: CLI args > env vars > config file > defaults

The CLI also loads ~/.port/.env (and a .env file in the current directory) at startup. Existing shell environment variables are not overridden.

Non-interactive and CI usage

For scripts, CI, and local development without a browser, use machine credentials (Port application client_id + client_secret) instead of port auth login. The login flow stores an OAuth token in ~/.port/creds.json; most commands work with either method (OAuth from port auth login or client_id / client_secret from config or flags).

Option A β€” environment variables (good for CI and one-off shells):

export PORT_CLIENT_ID="your-client-id"
export PORT_CLIENT_SECRET="your-client-secret"
export PORT_API_URL="https://api.getport.io/v1"   # or http://localhost:3000/v1

port export --output backup.tar.gz
port skills list
port skills upload ./my-skill --publish --location global

Option B β€” ~/.port/.env (persistent on your machine, same variable names):

# ~/.port/.env
PORT_CLIENT_ID=your-client-id
PORT_CLIENT_SECRET=your-client-secret
PORT_API_URL=http://localhost:3000/v1

Option C β€” config file (port config --init, then edit ~/.port/config.yaml):

default_org: default

organizations:
  default:
    client_id: your-client-id
    client_secret: your-client-secret
    api_url: https://api.getport.io/v1

Option D β€” per-command flags (highest precedence):

port api blueprints list \
  --client-id your-client-id \
  --client-secret your-client-secret \
  --api-url https://api.getport.io/v1

Use the Client ID and Client Secret from your Port application settings, not the organization ID. For EU/US regions, set api_url to the matching Port API base (see port auth login --region).

Non-interactive command flags: many subcommands accept flags instead of prompts (for example port skills init --tool Cursor --select-all-ungrouped, port skills init --install-hooks for session hooks, port skills upload … --identifier … --publish). Use port --yes / -y to skip confirmation prompts where supported.

See docs/skills-setup.md for skills-specific setup and docs/api/CLI_API_COMMANDS.md for global flags on port api commands.

Examples

Automated Backups
#!/bin/bash
DATE=$(date +%Y%m%d)
./bin/port export --output "backups/port-backup-$DATE.tar.gz"

# Keep only last 30 days
find backups/ -name "port-backup-*.tar.gz" -mtime +30 -delete
Compare Organizations

By default, port compare compares all resource types (blueprints, actions, scorecards, pages, integrations, teams, users). Use --include to narrow the comparison to specific types.

# Compare two configured organizations (all resource types)
port compare --source staging --target production

# Compare with verbose output (show identifiers)
port compare --source staging --target production --verbose

# Compare with full field-level diff
port compare --source staging --target production --full

# Compare only pages
port compare --source staging --target production --include pages

# Compare pages and blueprints together
port compare --source staging --target production --include pages,blueprints

# Compare export files
port compare --source ./staging-backup.tar.gz --target ./prod-backup.tar.gz

# Compare only pages between export files
port compare --source ./staging-backup.tar.gz --target ./prod-backup.tar.gz --include pages

# Output as JSON (for scripting)
port compare --source staging --target production --output json

# Generate interactive HTML report
port compare --source staging --target production --output html --html-file report.html

# CI/CD mode: exit code 1 if differences found
port compare --source staging --target production --fail-on-diff

# CI/CD mode scoped to pages only
port compare --source staging --target production --include pages --fail-on-diff

Valid --include values: blueprints, actions, scorecards, pages, integrations, teams, users.

Clear Organization Resources

port clear deletes resources from a Port organization in bulk. It complements upsert-only import and migrate β€” use it when you need to remove drift or rebuild a sandbox to a known state.

Do not confuse with other "clear" commands:

Command Scope
port clear Port org resources (API deletes)
port cache clear Local CLI hooks, skills, and config
port skills clear Local synced skill files only

At least one resource-type flag is required: --entities, --actions, --scorecards, --automations, --pages, or --blueprints. When multiple types are selected, dependents are deleted before parents: entities β†’ actions β†’ scorecards β†’ automations β†’ pages β†’ blueprints.

Use --blueprint (repeatable) to scope --entities, --actions, --scorecards, and --blueprints to specific blueprints. Use --jq to filter which entities are deleted (e.g. --jq '.properties.state == "archived"').

System blueprints (identifiers starting with _, such as _user and _team) are always skipped for --blueprints. Their entities, actions, and scorecards are also skipped unless you pass --include-system-blueprints. Root pages and folders whose identifiers start with _ are skipped unless you pass --delete-protected-pages.

By default, port clear prompts for confirmation. Pass --force to skip the prompt (recommended in scripts). Use --org to target a specific organization.

Limitations:

  • Does not delete teams, users, integrations, or permissions
  • --pages deletes root sidebar pages and folders only (not nested children)
  • Not a full idempotent apply on its own β€” pair with import or compare
# Delete all entities for a specific blueprint
port clear --entities --blueprint service --force

# JQ-filtered entity delete
port clear --entities --blueprint aiSpec --jq '.properties.organization == "example-org"' --force

# Full sandbox reset (supported config types), then re-import
port clear --entities --actions --scorecards --automations --pages --blueprints --force --org sandbox
port import --input ./config.tar.gz --org sandbox

# Verify convergence
port compare --source ./config.tar.gz --target sandbox --fail-on-diff

Common workflows:

  • Sandbox rebuild: clear (supported types) β†’ import β†’ compare --fail-on-diff
  • Drift remediation: compare --output json to find extras, delete via scoped clear or port api, then import
  • Stage/prod: prefer import/migrate + compare for gating; avoid blanket clear
User Import

Users are imported as STAGED (pending activation) rather than being sent an invitation email. Existing users are updated with source data as-is.

Use --users-as-disabled to set non-admin new users to DISABLED instead (admin users are always staged):

# Import users as disabled (non-admins only)
port import --input backup.tar.gz --users-as-disabled

# Migrate users as disabled
port migrate --source-org prod --target-org staging --users-as-disabled
Pre-Production Testing
# Export from production
./bin/port export --output prod.tar.gz --org production

# Import to staging
./bin/port import --input prod.tar.gz --org staging

# Compare to verify changes
./bin/port compare --source prod.tar.gz --target staging --verbose

# Test changes in staging...

# When ready, migrate back
./bin/port migrate --source-org staging --target-org production

To rebuild a sandbox org to match a known config (when import alone cannot remove extra resources), clear supported types first, then import and verify:

./bin/port clear --entities --actions --scorecards --automations --pages --blueprints --force --org sandbox
./bin/port import --input ./config.tar.gz --org sandbox
./bin/port compare --source ./config.tar.gz --target sandbox --fail-on-diff
Docker
# Export to a local directory
docker run --rm \
  -e PORT_CLIENT_ID="your-client-id" \
  -e PORT_CLIENT_SECRET="your-client-secret" \
  -v $(pwd)/output:/data \
  port-cli export --output /data/backup.tar.gz

# Import from a local file
docker run --rm \
  -e PORT_CLIENT_ID="your-client-id" \
  -e PORT_CLIENT_SECRET="your-client-secret" \
  -v $(pwd)/output:/data \
  port-cli import --input /data/backup.tar.gz

# Compare two organizations
docker run --rm \
  -e PORT_CLIENT_ID="source-client-id" \
  -e PORT_CLIENT_SECRET="source-client-secret" \
  -e PORT_TARGET_CLIENT_ID="target-client-id" \
  -e PORT_TARGET_CLIENT_SECRET="target-client-secret" \
  port-cli compare --fail-on-diff
AI Skill Hooks

Automatically sync skills from your Port organization into local AI coding tools (Cursor, Claude Code, Gemini CLI, OpenAI Codex, Windsurf, GitHub Copilot).

# One-time setup: choose tools and skill selection (saved to ~/.port/config.yaml)
port skills init

# Download skills to disk (after init, or pass --tool for a one-off sync)
port skills sync
port skills sync --tool Cursor --group operations
port skills sync --tool Cursor --tool "Claude Code" --tool Windsurf

# Scripts/CI: explicit flags or -y to select every option without prompts
port skills init -y
port skills init --tool Cursor --select-all-groups --select-all-ungrouped
port skills add --group my-group --skill my-skill --tool Cursor
port skills add integrations-overview
port skills add -y
port skills remove integrations-overview
port skills remove --tool Windsurf

# Check what's configured
port skills status

# Delete locally synced skill files only (hooks remain; skills re-sync on next session)
port skills clear

# Full cleanup: remove hooks, skill files, and config β€” everything Port CLI installed
port cache clear

See docs/skills-setup.md for full setup instructions.

Contributing

See CONTRIBUTING.md for development guidelines.

Release Process

See RELEASE.md for release procedures.

License

MIT License - see LICENSE

References

Directories ΒΆ

Path Synopsis
cmd
port command
internal
api
modules/compare
Package compare provides functionality for comparing two Port organizations.
Package compare provides functionality for comparing two Port organizations.
modules/skills
Package skills syncs Port catalog skills to local AI tool directories.
Package skills syncs Port catalog skills to local AI tool directories.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL