An open API service indexing awesome lists of open source software.

https://github.com/camunda/c8ctl

a cli for Camunda 8 Cluster inspection, Process Management, and Dev-time support
https://github.com/camunda/c8ctl

ai-first-check camunda-8 camunda-bpm-platform camunda-engine cli zeebe

Last synced: about 1 month ago
JSON representation

a cli for Camunda 8 Cluster inspection, Process Management, and Dev-time support

Awesome Lists containing this project

README

          

# Cocktail (c8ctl) - Camunda 8 CLI

c8ctl (_pronounced: "cocktail"_) — a minimal-dependency CLI for Camunda 8 operations built on top of [`@camunda8/orchestration-cluster-api`](https://www.npmjs.com/package/@camunda8/orchestration-cluster-api).

## Features

- **Multi-Tenant Support**: Full support for multi-tenancy across all operations
- **Profile Management**: Store and manage multiple cluster configurations
- **Camunda Modeler Integration**: Automatically import and use profiles from Camunda Modeler
- **Identity Management**: Manage users, roles, groups, tenants, authorizations, and mapping rules
- **Plugin System**: Extend c8ctl with custom commands via npm packages
- **Local Cluster**: Run a local Camunda 8 instance directly — no Docker required
- **MCP Proxy**: Bridge local MCP clients to remote Camunda 8 for AI agent integration
- **Building Block Deployment**: Automatic prioritization of `*_bb-*` folders during deployment, marked with 🧱 in results
- **Process Application Support**: Resources in folders with `.process-application` file marked with 📦 in results
- **Enhanced Deployment Results**: Table view showing file paths, visual indicators, resource details, and versions
- **Watch Mode**: Monitors a folder for file changes and auto-redeploys (configurable extensions via `--extensions`)
- **`.c8ignore` Support**: Filter deploy/watch file scanning with `.gitignore`-style patterns; `node_modules/`, `target/`, `.git/` ignored by default
- **Open Applications**: Open Camunda web applications (Operate, Tasklist, Modeler, Optimize) in the browser directly from the CLI
- **Search**: Powerful search across process definitions, process instances, user tasks, incidents, jobs, and variables with filter, wildcard, and case-insensitive support
- **Flexible Output**: Switch between human-readable text and JSON output modes
- **Shell Completion**: Auto-install completions for bash, zsh, and fish with automatic refresh on upgrade
- **Agent Flags**: `--dry-run` to preview API requests and `--fields` to filter output columns for AI agents and scripts
- **Debug Mode**: Enable detailed logging to stderr with `DEBUG=1` or `C8CTL_DEBUG=true`

## Beware the 🤖

_Full transparency_:
this cli is also a pilot-coding experiment, practicing [Agentic Engineering](https://addyosmani.com/blog/agentic-engineering/).
Guided by humans, the codebase is (mostly) built by your friendly neighborhood LLM, fully dogfooding the Human-in-the-Loop pattern.

## Installation

### Requirements

- Node.js >= 22.18.0 (for native TypeScript support)

### Global Installation (Recommended)

```bash
npm install @camunda8/cli -g
```

After installation, the CLI is available as `c8ctl` (or its alias `c8`).

**Note**: The `c8` alias provides typing ergonomics for common keyboard layouts - the `c` key (left index finger) followed by `8` (right middle finger) makes for a comfortable typing experience on both QWERTY and QWERTZ keyboards.

## Usage

### Getting Help

```bash
# Show general help
c8ctl help

# Show detailed help for specific commands with all flags
c8ctl help list # Shows all list resources and their flags
c8ctl help get # Shows all get resources and their flags
c8ctl help create # Shows all create resources and their flags
c8ctl help complete # Shows all complete resources and their flags
c8ctl help await # Shows await command with all flags
c8ctl help search # Shows all search resources and their flags
c8ctl help deploy # Shows deploy command with all flags
c8ctl help run # Shows run command with all flags
c8ctl help watch # Shows watch command with all flags
c8ctl help open # Shows open command with all apps
c8ctl help cancel # Shows cancel command with all flags
c8ctl help resolve # Shows resolve command with all flags
c8ctl help fail # Shows fail command with all flags
c8ctl help activate # Shows activate command with all flags
c8ctl help publish # Shows publish command with all flags
c8ctl help correlate # Shows correlate command with all flags
c8ctl help cluster # Shows local cluster management help
c8ctl help profiles # Shows profile management help
c8ctl help plugin # Shows plugin management help

# Show version
c8ctl --version
```

### Default Extensions

When scanning directories, `deploy` and `watch` only include files with these extensions by default:

`.bpmn`, `.dmn`, `.form`

Explicitly named files bypass the extension allow-list (e.g. `c8 deploy my-doc.md`). Note that `.c8ignore` rules still apply.

Use `--extensions` to add more types during directory discovery (merged with defaults):

```bash
c8 deploy --extensions=.md,.txt
c8 watch --extensions=.md
```

Use `--all-extensions` to include all server-supported types (`.md`, `.txt`, `.xml`, `.rpa`, `.json`, `.config`, `.yml`, `.yaml`):

```bash
c8 deploy --all-extensions
```

Skipped files are logged to stderr with an actionable hint.

### Ignoring Files (`.c8ignore`)

When scanning directories for deployment artifacts, c8ctl automatically ignores:

- `node_modules/`
- `target/`
- `.git/`

Create a `.c8ignore` file in your project root to add custom patterns (`.gitignore` syntax):

```gitignore
# Ignore build output
dist/
build/

# Ignore draft processes
**/draft-*.bpmn

# But keep this specific one
!draft-approved.bpmn
```

`.c8ignore` rules apply to both `deploy` (directory scan) and `watch` (file monitoring).

For comprehensive examples of all commands and their flags, see [EXAMPLES.md](EXAMPLES.md).

### Shell Completion

c8ctl supports shell completion for `bash`, `zsh`, and `fish`.

#### Quick Install (recommended)

```bash
# Auto-detect your shell and install completions
c8ctl completion install

# Or specify a shell explicitly
c8ctl completion install --shell zsh
```

This writes a completion script to the c8ctl data directory and wires it into your shell config (RC file for bash/zsh; completions directory for fish). Completions are **automatically refreshed** when c8ctl is upgraded — no manual re-install needed.

#### Manual setup

If you prefer to manage the completion script yourself, generate it with
`c8ctl completion ` (where `` is `bash`, `zsh`, or `fish`),
then source or install it:

```bash
# Bash
c8ctl completion bash > ~/.c8ctl-completion.bash
echo 'source ~/.c8ctl-completion.bash' >> ~/.bashrc
source ~/.c8ctl-completion.bash

# Zsh
c8ctl completion zsh > ~/.c8ctl-completion.zsh
echo 'source ~/.c8ctl-completion.zsh' >> ~/.zshrc
source ~/.c8ctl-completion.zsh

# Fish (auto-loaded on next start)
c8ctl completion fish > ~/.config/fish/completions/c8ctl.fish
```

### Credential Resolution

Credentials are resolved in the following order:

1. `--profile` flag (one-off override)
2. Active profile from session state (⚠ warns if `CAMUNDA_*` env vars are also present)
3. Environment variables (`CAMUNDA_*`)
4. Default `local` profile (`http://localhost:8080/v2`)

**Note**: Credential configuration via environment variables follows the same conventions as the `@camunda8/orchestration-cluster-api` module.

```bash
# Using environment variables
export CAMUNDA_BASE_URL=https://camunda.example.com
export CAMUNDA_CLIENT_ID=your-client-id
export CAMUNDA_CLIENT_SECRET=your-client-secret
c8ctl list process-instances

# Create a profile from a .env file
c8ctl add profile staging --from-file .env.staging

# Create a profile from current environment variables
source .env.prod
c8ctl add profile prod --from-env

# Clear the active session profile (so env vars take effect)
c8ctl use profile --none

# Using profile override
c8ctl list process-instances --profile prod
```

### Tenant Resolution

Tenants are resolved in the following order:

1. Active tenant from session state
2. Default tenant from active profile
3. `CAMUNDA_DEFAULT_TENANT_ID` environment variable
4. `` tenant

```bash
# Set active tenant for the session
c8ctl use tenant my-tenant-id

# Now all commands use this tenant
c8ctl list process-instances
```

### Profile Management

c8ctl supports two types of profiles:

1. **c8ctl profiles**: Managed directly by c8ctl
2. **Camunda Modeler profiles**: Automatically imported from Camunda Modeler (with `modeler:` prefix)

For profile-related commands and flags, run:

```bash
c8ctl help profiles
```

```bash
# Add a c8ctl profile
c8 add profile prod --baseUrl=https://camunda.example.com --clientId=xxx --clientSecret=yyy

# List all profiles (includes both c8ctl and modeler profiles)
c8 list profiles

# Set active profile (works with both types)
c8 use profile prod
c8 use profile "modeler:Local Dev"

# Remove c8ctl profile (modeler profiles are read-only)
c8 remove profile prod
```

#### Camunda Modeler Integration

c8ctl automatically reads profiles from Camunda Modeler's `profiles.json` file. These profiles are:

- **Read-only**: Cannot be modified or deleted via c8ctl
- **Prefixed**: Always displayed with `modeler:` prefix (e.g., `modeler:Local Dev`)
- **Dynamic**: Loaded fresh on each command execution (no caching)
- **Platform-specific locations**:
- Linux: `~/.config/camunda-modeler/profiles.json`
- macOS: `~/Library/Application Support/camunda-modeler/profiles.json`
- Windows: `%APPDATA%\camunda-modeler\profiles.json`

**Using modeler profiles:**

```bash
# List includes modeler profiles with 'modeler:' prefix
c8 list profiles

# Use a modeler profile by name
c8 use profile modeler:Local Dev

# Use a modeler profile by cluster ID
c8 use profile modeler:abc123-def456

# One-off command with modeler profile
c8 list pi --profile=modeler:Cloud Cluster
```

**URL Construction:**

- **Self-managed** (localhost): Appends `/v2` to the URL (e.g., `http://localhost:8080/v2`)
- **Cloud**: Uses the cluster URL as-is (e.g., `https://abc123.region.zeebe.camunda.io`)
- **Any port**: Supports any port number in the URL

### Session Management

```bash
# Show current output mode
c8ctl output

# Switch to JSON output
c8ctl output json

# Switch back to text output
c8ctl output text
```

#### Per-invocation output override

The persisted output mode (set by `c8ctl output json|text`) can be overridden for a single invocation without mutating `session.json`. This is useful for scripts, agent integrations, and one-off JSON capture without flipping global state.

Precedence (highest first):

1. `--json` global flag — force JSON for this invocation only.
2. `C8CTL_OUTPUT_MODE` env var — accepts `json` or `text`. Other values (including unset or typos) fall through to the persisted mode without erroring.
3. Persisted `session.json` `outputMode`.

```bash
# Force JSON for one command — session.json is not touched
c8ctl --json list profile

# Same effect via env var (handy for scoped shells / CI steps)
C8CTL_OUTPUT_MODE=json c8ctl list profile

# --json wins over the env var
C8CTL_OUTPUT_MODE=text c8ctl --json list profile # → JSON
```

### Debug Mode

Enable debug logging to see detailed information about plugin loading and other internal operations:

```bash
# Enable debug mode with environment variable
DEBUG=1 c8

# Or use C8CTL_DEBUG
C8CTL_DEBUG=true c8

# Example: See plugin loading details
DEBUG=1 c8 list plugins
```

Debug output is written to stderr with timestamps and won't interfere with normal command output.

### Plugin Management

c8ctl supports a global plugin system that allows extending the CLI with custom commands via npm packages. Plugins are installed globally to a user-specific directory and tracked in a registry file.

**Plugin Storage Locations:**

The plugin system uses OS-specific directories:

| OS | Plugins Directory | Registry File |
|----|-------------------|---------------|
| **Linux** | `~/.config/c8ctl/plugins/node_modules` | `~/.config/c8ctl/plugins.json` |
| **macOS** | `~/Library/Application Support/c8ctl/plugins/node_modules` | `~/Library/Application Support/c8ctl/plugins.json` |
| **Windows** | `%APPDATA%\c8ctl\plugins\node_modules` | `%APPDATA%\c8ctl\plugins.json` |

> **Note:** You can override the data directory with the `C8CTL_DATA_DIR` environment variable.

```bash
# Create a new plugin from template
c8ctl init plugin my-plugin

# Load a plugin from npm registry
c8ctl load plugin

# Load a plugin from a URL (including file URLs)
c8ctl load plugin --from
c8ctl load plugin --from file:///path/to/plugin
c8ctl load plugin --from https://github.com/user/repo
c8ctl load plugin --from git://github.com/user/repo.git

# Upgrade a plugin to latest or specific version
c8ctl upgrade plugin
c8ctl upgrade plugin 1.2.3

# Downgrade a plugin to a specific version
c8ctl downgrade plugin 1.0.0

# Unload a plugin
c8ctl unload plugin

# List installed plugins (shows version and sync status)
c8ctl list plugins

# Synchronize plugins from registry
# - First tries npm rebuild for installed plugins
# - Falls back to fresh npm install if rebuild fails
c8ctl sync plugins

# View help including plugin commands
c8ctl help
```

**Global Plugin System:**

- Plugins are installed to a global directory (OS-specific, see table above)
- Plugin registry file (`plugins.json`) tracks all installed plugins
- No local `package.json` is required in your working directory
- Plugins are available globally from any directory
- The registry serves as the source of truth for installed plugins
- Default plugins are bundled with c8ctl and loaded automatically
- **Plugin commands cannot override built-in commands** - built-in commands always take precedence
- `c8ctl list plugins` shows plugin versions and sync status:
- `✓ Installed` - Plugin is in registry and installed
- `⚠ Not installed` - Plugin is in registry but not in global directory (run `sync`)
- `⚠ Not in registry` - Plugin is installed but not tracked in registry
- `c8ctl sync plugins` synchronizes plugins from the registry, rebuilding or reinstalling as needed
- `c8ctl upgrade plugin [version]` respects the plugin source from the registry:
- without `version`: reinstalls the registered source as-is
- npm package source with `version`: installs `@`
- URL/git source with `version`: installs `#`
- file source (`file://`) with `version`: version upgrade is not supported; use `load plugin --from` with the desired local plugin checkout
- `c8ctl downgrade plugin ` respects the plugin source from the registry:
- npm package source: installs `@`
- URL/git source: installs `#`
- file source (`file://`): version downgrade is not supported; use `load plugin --from` with the desired local plugin checkout

When plugins are loaded, their commands automatically appear in `c8ctl help` output.

For plugin development (scaffolding, runtime API, flags, TypeScript support), see [PLUGIN-HELP.md](PLUGIN-HELP.md).

---

## Agent Usage (AI / Programmatic Consumption)

c8ctl ships two flags designed specifically for AI agents and programmatic consumers.
They appear in their own clearly labelled section in `c8ctl help`.

> For a full machine-readable reference, see [`CONTEXT.md`](./CONTEXT.md).

### `--fields `

Filters output to only the specified field names. Applies to all `list`, `search`,
and `get` commands. Field matching is **case-insensitive**.

```bash
# Only return Key and State columns — reduces context window size
c8ctl list pi --fields Key,State
c8ctl search pd --fields Key,processDefinitionId,name

# Works in both text and JSON modes
c8ctl output json
c8ctl list pi --fields Key,State,processDefinitionId | jq .
```

### `--dry-run`

Previews the API request that **would** be sent without executing it.
Works on **all commands**: queries (`list`, `search`, `get`) and mutations
(`create`, `cancel`, `deploy`, `complete`, `fail`, `activate`, `resolve`,
`publish`, `correlate`).

Emits a JSON object to stdout and exits 0:
```json
{
"dryRun": true,
"command": "create process-instance",
"method": "POST",
"url": "http://localhost:8080/v2/process-instances",
"body": { "processDefinitionId": "my-process", "tenantId": "" }
}
```

**Recommended agent workflow for mutations:**
1. Run with `--dry-run` and show the user the would-be API call
2. Wait for user confirmation
3. Re-run without `--dry-run` to execute

```bash
# Preview before creating
c8ctl create pi --id=my-process --dry-run

# Preview a deployment
c8ctl deploy ./my-process.bpmn --dry-run

# Preview cancelling a process instance
c8ctl cancel pi 2251799813685249 --dry-run

# Debug a search query — see the filter body that would be sent
c8ctl search pi --state ACTIVE --between 2024-01-01..2024-12-31 --dry-run

# Inspect a list operation
c8ctl list pd --dry-run

# Preview a get request
c8ctl get pi 12345 --dry-run
```

### Machine-Readable Help (JSON Mode)

In JSON output mode, `c8ctl help` emits structured JSON containing the full
command tree, flags (with types), and agent flags:

```bash
c8ctl output json
c8ctl help # → JSON with commands[], globalFlags[], agentFlags[], resourceAliases
c8ctl help list # → JSON for specific command
```

---

### Local Cluster

c8ctl includes a built-in `cluster` command for managing a local Camunda 8 instance (powered by a default plugin). No Docker or docker-compose required — it downloads and runs Camunda directly.

```bash
# Start the latest stable version
c8ctl cluster start

# Start a specific version
c8ctl cluster start 8.9
c8ctl cluster start 8.9.0-alpha5

# Stop the running cluster
c8ctl cluster stop

# Check cluster status
c8ctl cluster status

# Stream cluster logs
c8ctl cluster logs

# List locally cached versions
c8ctl cluster list

# List available remote versions
c8ctl cluster list-remote

# Pre-download a version without starting it
c8ctl cluster install 8.9

# Remove a cached version
c8ctl cluster delete 8.9
```

#### Version Aliases

Instead of an exact version number, you can use:

- **`stable`** — the latest GA release (highest minor version that has shipped a `.0` release)
- **`alpha`** — the latest alpha-train release (highest minor version overall, which may only have alpha builds)
- **A major.minor pattern** like `8.9` — resolves to the latest patch/alpha within that minor

`c8ctl cluster start` with no version argument defaults to `stable`.

```bash
c8ctl cluster start stable
c8ctl cluster start alpha
c8ctl cluster start 8.9 # latest 8.9.x
```

#### Online vs Offline Behaviour

- **`cluster start`** prefers locally cached versions. If the requested version is already installed, it starts immediately without going online. A non-blocking background check runs to hint if a newer build is available, but never delays startup.
- **`cluster install`** always checks the remote download server for the latest build. If a newer ETag is detected for an already-installed version, it re-downloads.
- **`cluster list-remote`** fetches the full list of available versions from the download server.
- **Offline fallback**: if the network is unavailable, alias resolution falls back to a locally cached mapping, then to a hardcoded default.

Run `c8ctl help cluster` for full details. See [EXAMPLES.md](EXAMPLES.md#local-cluster) for a complete local development workflow.

---

### Command Structure

```shell
c8ctl [arguments] [flags]
```

**Verbs**:

- `list` - List resources (process, identity)
- `search` - Search resources with filters
- `get` - Get resource by key
- `create` - Create resource
- `delete` - Delete resource
- `cancel` - Cancel resource
- `await` - Create and await completion (alias for create --awaitCompletion)
- `complete` - Complete resource
- `fail` - Fail a job
- `activate` - Activate jobs by type
- `resolve` - Resolve incident
- `publish` - Publish message
- `correlate` - Correlate message
- `set` - Set variables on an element instance
- `deploy` - Deploy resources
- `run` - Deploy and start process
- `assign` - Assign resource to target
- `unassign` - Unassign resource from target
- `watch` (alias: `w`) - Watch files for changes and auto-deploy
- `open` - Open Camunda web application in browser
- `add` - Add a profile
- `remove` (alias: `rm`) - Remove a profile
- `load` - Load a c8ctl plugin
- `unload` (alias: `rm`) - Unload a c8ctl plugin
- `upgrade` - Upgrade a plugin
- `downgrade` - Downgrade a plugin to a specific version
- `sync` - Synchronize plugins
- `init` - Create a new plugin from TypeScript template
- `doctor` - Diagnose plugin loading state and collisions
- `use` - Set active profile or tenant
- `output` - Show or set output format
- `completion` - Generate shell completion script
- `mcp-proxy` - Start a STDIO to remote HTTP MCP proxy server
- `feedback` - Open the feedback page to report issues or request features
- `help` (alias: `menu`) - Show help
- `which` - Show active profile or output mode

**Resources**: authorization (auth), form, group, incident (inc), job, jobs, mapping-rule (mr), message (msg), plugin, process-definition (pd), process-instance (pi), profile, role, tenant, topology, user, user-task (ut), variable (var, vars)

**Tip**: Run `c8ctl help ` to see detailed help for specific commands with all available flags.

## Environment Variables

- `CAMUNDA_BASE_URL`: Cluster base URL
- `CAMUNDA_CLIENT_ID`: OAuth client ID
- `CAMUNDA_CLIENT_SECRET`: OAuth client secret
- `CAMUNDA_TOKEN_AUDIENCE`: OAuth token audience
- `CAMUNDA_OAUTH_URL`: OAuth token endpoint
- `CAMUNDA_DEFAULT_TENANT_ID`: Default tenant ID
- `C8CTL_OUTPUT_MODE`: Per-invocation output mode override (`json` or `text`); does not persist. Lower precedence than `--json`. See [Per-invocation output override](#per-invocation-output-override).
- `C8CTL_DATA_DIR`: Override the OS-default data directory for plugins and session state.
- `C8CTL_DEBUG` / `DEBUG`: Enable debug logging to stderr.

## Configuration Files

### c8ctl Configuration

Configuration is stored in platform-specific user data directories:

- **Linux**: `~/.config/c8ctl/`
- **macOS**: `~/Library/Application Support/c8ctl/`
- **Windows**: `%APPDATA%\c8ctl\`

Files:

- `profiles.json`: Saved cluster configurations
- `session.json`: Active profile, tenant, and output mode
- `plugins.json`: Plugin registry tracking installed plugins

### Camunda Modeler Configuration

c8ctl automatically reads profiles from Camunda Modeler (if installed):

- **Linux**: `~/.config/camunda-modeler/profiles.json`
- **macOS**: `~/Library/Application Support/camunda-modeler/profiles.json`
- **Windows**: `%APPDATA%\camunda-modeler\profiles.json`

Modeler profiles are:

- Read-only in c8ctl (managed via Camunda Modeler)
- Automatically loaded on each command execution
- Prefixed with `modeler:` when used in c8ctl
- Support both cloud and self-managed clusters

## Command Reference

### Global Flags

These flags are accepted by every command.

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--help` / `-h` | boolean | | Show help |
| `--version` / `-v` | string | | Show CLI version, or filter by process definition version on supported commands |
| `--profile` | string | | Use a specific profile |
| `--dry-run` | boolean | | Preview the API request without executing |
| `--verbose` | boolean | | Show verbose output |
| `--fields` | string | | Comma-separated list of fields to display |
| `--json` | boolean | | Force JSON output for this invocation (does not persist; overrides session state and C8CTL_OUTPUT_MODE) |

### Resource Aliases

| Alias | Resource |
|-------|----------|
| `auth` | `authorization` |
| `inc` | `incident` |
| `mr` | `mapping-rule` |
| `msg` | `message` |
| `pd` | `process-definition` |
| `pi` | `process-instance` |
| `ut` | `user-task` |
| `vars` | `variable` |
| `var` | `variable` |

### Search Flags

These flags are available on `list` and `search` commands.

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--sortBy` | string | | Sort results by field |
| `--asc` | boolean | | Sort ascending |
| `--desc` | boolean | | Sort descending |
| `--limit` | string | | Maximum number of results |
| `--between` | string | | Date range filter (e.g. 2024-01-01..2024-12-31, ..2024-12-31, 2024-01-01..) |
| `--dateField` | string | | Date field for --between filter |

### Commands

#### `list`

List resources

**Resources:** pi (process-instance), pd (process-definition), ut (user-task), inc (incident), jobs, profiles (profile), plugins (plugin), users (user), roles (role), groups (group), tenants (tenant), auth (authorization), mapping-rules (mapping-rule)

**Verb-level flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--all` | boolean | | List all (disable pagination limit) |

**Resource-specific flags:**

process-definition (pd)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--bpmnProcessId` | string | | Filter by BPMN process ID |
| `--id` | string | | Filter by BPMN process ID (alias) |
| `--processDefinitionId` | string | | Filter by process definition ID |
| `--name` | string | | Filter by name |
| `--key` | string | | Filter by key |
| `--iid` | string | | Case-insensitive filter by BPMN process ID |
| `--iname` | string | | Case-insensitive filter by name |

process-instance (pi)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--bpmnProcessId` | string | | Filter by BPMN process ID |
| `--id` | string | | Filter by BPMN process ID (alias) |
| `--processDefinitionId` | string | | Filter by process definition ID |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--state` | string | | Filter by state (ACTIVE, COMPLETED, etc) |
| `--key` | string | | Filter by key |
| `--parentProcessInstanceKey` | string | | Filter by parent process instance key |
| `--iid` | string | | Case-insensitive filter by BPMN process ID |

user-task (ut)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--state` | string | | Filter by state |
| `--assignee` | string | | Filter by assignee |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--elementId` | string | | Filter by element ID |
| `--iassignee` | string | | Case-insensitive filter by assignee |

incident (inc)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--state` | string | | Filter by state |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--bpmnProcessId` | string | | Filter by BPMN process ID |
| `--id` | string | | Filter by BPMN process ID (alias) |
| `--processDefinitionId` | string | | Filter by process definition ID |
| `--errorType` | string | | Filter by error type |
| `--errorMessage` | string | | Filter by error message |
| `--ierrorMessage` | string | | Case-insensitive filter by error message |
| `--iid` | string | | Case-insensitive filter by BPMN process ID |

jobs

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--state` | string | | Filter by state |
| `--type` | string | | Filter by job type |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--itype` | string | | Case-insensitive filter by job type |

user

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--username` | string | | Filter by username |
| `--name` | string | | Filter by name |
| `--email` | string | | Filter by email |

role

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--roleId` | string | | Filter by role ID |
| `--name` | string | | Filter by name |

group

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--groupId` | string | | Filter by group ID |
| `--name` | string | | Filter by name |

tenant

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--tenantId` | string | | Filter by tenant ID |
| `--name` | string | | Filter by name |

authorization (auth)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--ownerId` | string | | Filter by owner ID |
| `--ownerType` | string | | Filter by owner type |
| `--resourceType` | string | | Filter by resource type |
| `--resourceId` | string | | Filter by resource ID |

mapping-rule (mr)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--mappingRuleId` | string | | Filter by mapping rule ID |
| `--name` | string | | Filter by name |
| `--claimName` | string | | Filter by claim name |
| `--claimValue` | string | | Filter by claim value |

**Examples:**

```bash
c8ctl list pi # List process instances
c8ctl list pd # List process definitions
c8ctl list users # List users
```

---

#### `search`

Search resources with filters (wildcards, date ranges, case-insensitive)

**Resources:** pi (process-instance), pd (process-definition), ut (user-task), inc (incident), jobs, vars (variable), users (user), roles (role), groups (group), tenants (tenant), auth (authorization), mapping-rules (mapping-rule)

**Resource-specific flags:**

process-definition (pd)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--bpmnProcessId` | string | | Filter by BPMN process ID |
| `--id` | string | | Filter by BPMN process ID (alias) |
| `--processDefinitionId` | string | | Filter by process definition ID |
| `--name` | string | | Filter by name |
| `--key` | string | | Filter by key |
| `--iid` | string | | Case-insensitive filter by BPMN process ID |
| `--iname` | string | | Case-insensitive filter by name |

process-instance (pi)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--bpmnProcessId` | string | | Filter by BPMN process ID |
| `--id` | string | | Filter by BPMN process ID (alias) |
| `--processDefinitionId` | string | | Filter by process definition ID |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--state` | string | | Filter by state (ACTIVE, COMPLETED, etc) |
| `--key` | string | | Filter by key |
| `--parentProcessInstanceKey` | string | | Filter by parent process instance key |
| `--iid` | string | | Case-insensitive filter by BPMN process ID |

user-task (ut)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--state` | string | | Filter by state |
| `--assignee` | string | | Filter by assignee |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--elementId` | string | | Filter by element ID |
| `--iassignee` | string | | Case-insensitive filter by assignee |

incident (inc)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--state` | string | | Filter by state |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--bpmnProcessId` | string | | Filter by BPMN process ID |
| `--id` | string | | Filter by BPMN process ID (alias) |
| `--processDefinitionId` | string | | Filter by process definition ID |
| `--errorType` | string | | Filter by error type |
| `--errorMessage` | string | | Filter by error message |
| `--ierrorMessage` | string | | Case-insensitive filter by error message |
| `--iid` | string | | Case-insensitive filter by BPMN process ID |

jobs

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--state` | string | | Filter by state |
| `--type` | string | | Filter by job type |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--processDefinitionKey` | string | | Filter by process definition key |
| `--itype` | string | | Case-insensitive filter by job type |

variable (var, vars)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--name` | string | | Filter by variable name |
| `--value` | string | | Filter by value |
| `--processInstanceKey` | string | | Filter by process instance key |
| `--scopeKey` | string | | Filter by scope key |
| `--fullValue` | boolean | | Return full variable values (not truncated) |
| `--iname` | string | | Case-insensitive filter by name |
| `--ivalue` | string | | Case-insensitive filter by value |

user

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--username` | string | | Filter by username |
| `--name` | string | | Filter by name |
| `--email` | string | | Filter by email |

role

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--roleId` | string | | Filter by role ID |
| `--name` | string | | Filter by name |

group

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--groupId` | string | | Filter by group ID |
| `--name` | string | | Filter by name |

tenant

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--tenantId` | string | | Filter by tenant ID |
| `--name` | string | | Filter by name |

authorization (auth)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--ownerId` | string | | Filter by owner ID |
| `--ownerType` | string | | Filter by owner type |
| `--resourceType` | string | | Filter by resource type |
| `--resourceId` | string | | Filter by resource ID |

mapping-rule (mr)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--mappingRuleId` | string | | Filter by mapping rule ID |
| `--name` | string | | Filter by name |
| `--claimName` | string | | Filter by claim name |
| `--claimValue` | string | | Filter by claim value |

**Examples:**

```bash
c8ctl search pi --state=ACTIVE # Search for active process instances
c8ctl search pd --bpmnProcessId=myProcess # Search process definitions by ID
c8ctl search pd --name='*main*' # Search process definitions with wildcard
c8ctl search ut --assignee=john # Search user tasks assigned to john
c8ctl search inc --state=ACTIVE # Search for active incidents
c8ctl search jobs --type=myJobType # Search jobs by type
c8ctl search jobs --type='*service*' # Search jobs with type containing "service"
c8ctl search variables --name=myVar # Search for variables by name
c8ctl search variables --value=foo # Search for variables by value
c8ctl search variables --processInstanceKey=123 --fullValue # Search variables with full values
c8ctl search pd --iname='*order*' # Case-insensitive search by name
c8ctl search ut --iassignee=John # Case-insensitive search by assignee
```

---

#### `get`

Get a resource by key

**Resources:** pi (process-instance), pd (process-definition), inc (incident), topology, form, user, role, group, tenant, auth (authorization), mapping-rule

**Positional arguments:**

- **process-definition:** `` (required)
- **process-instance:** `` (required)
- **incident:** `` (required)
- **user:** `` (required)
- **role:** `` (required)
- **group:** `` (required)
- **tenant:** `` (required)
- **authorization:** `` (required)
- **mapping-rule:** `` (required)
- **form:** `` (required)

**Resource-specific flags:**

process-definition (pd)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--xml` | boolean | | Get BPMN XML (process definitions) |

form

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--userTask` | boolean | | Get form for user task |
| `--ut` | boolean | | Alias for --userTask |
| `--processDefinition` | boolean | | Get form for process definition |
| `--pd` | boolean | | Alias for --processDefinition |

process-instance (pi)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--variables` | boolean | | Include variables in output |

**Examples:**

```bash
c8ctl get pi 123456 # Get process instance by key
c8ctl get pi 123456 --variables # Get process instance with variables
c8ctl get pd 123456 # Get process definition by key
c8ctl get pd 123456 --xml # Get process definition XML
c8ctl get form 123456 # Get form (searches both user task and process definition)
c8ctl get form 123456 --ut # Get form for user task only
c8ctl get form 123456 --pd # Get start form for process definition only
c8ctl get user john # Get user by username
```

---

#### `create`

Create a resource (process instance, identity)

**Resources:** pi (process-instance), user, role, group, tenant, auth (authorization), mapping-rule

**Verb-level flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--processDefinitionId` | string | | Process definition ID (BPMN process ID) |
| `--id` | string | | Process definition ID (alias for --processDefinitionId) |
| `--bpmnProcessId` | string | | BPMN process ID (alias for --processDefinitionId) |
| `--variables` | string | | JSON variables |
| `--awaitCompletion` | boolean | | Wait for process to complete |
| `--fetchVariables` | boolean | | Fetch result variables on completion |
| `--requestTimeout` | string | | Await timeout in milliseconds |
| `--username` | string | | Username |
| `--name` | string | | Display name |
| `--email` | string | | Email address |
| `--password` | string | | Password |
| `--roleId` | string | | Role ID |
| `--groupId` | string | | Group ID |
| `--tenantId` | string | | Tenant ID |
| `--mappingRuleId` | string | | Mapping rule ID |
| `--claimName` | string | | Claim name |
| `--claimValue` | string | | Claim value |

**Resource-specific flags:**

authorization (auth)

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--ownerId` | string | Yes | Authorization owner ID |
| `--ownerType` | string | Yes | Authorization owner type |
| `--resourceType` | string | Yes | Authorization resource type |
| `--resourceId` | string | Yes | Authorization resource ID |
| `--permissions` | string | Yes | Comma-separated permissions |

**Examples:**

```bash
c8ctl create pi --id=myProcess # Create a process instance
c8ctl create pi --id=myProcess --awaitCompletion # Create and await completion
c8ctl create user --username=john --name='John Doe' --email=john@example.com --password=secret # Create a user
```

---

#### `delete`

Delete a resource by key

**Usage:** `c8ctl delete `

**Resources:** user, role, group, tenant, auth (authorization), mapping-rule

**Positional arguments:**

- **user:** `` (required)
- **role:** `` (required)
- **group:** `` (required)
- **tenant:** `` (required)
- **authorization:** `` (required)
- **mapping-rule:** `` (required)

**Examples:**

```bash
c8ctl delete user john # Delete user
```

---

#### `cancel`

Cancel a process instance

**Usage:** `c8ctl cancel `

**Resources:** pi (process-instance)

**Positional arguments:**

- **process-instance:** `` (required)

---

#### `await`

Create and await process instance completion (server-side waiting)

**Usage:** `c8ctl await `

**Resources:** pi (process-instance)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--processDefinitionId` | string | | Process definition ID (BPMN process ID) |
| `--id` | string | | Process definition ID (alias for --processDefinitionId) |
| `--bpmnProcessId` | string | | BPMN process ID (alias for --processDefinitionId) |
| `--variables` | string | | JSON variables |
| `--fetchVariables` | boolean | | Fetch result variables on completion |
| `--requestTimeout` | string | | Await timeout in milliseconds |

**Examples:**

```bash
c8ctl await pi --id=myProcess # Create and wait for completion
```

---

#### `complete`

Complete a user task or job

**Usage:** `c8ctl complete `

**Resources:** ut (user-task), job

**Positional arguments:**

- **user-task:** `` (required)
- **job:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--variables` | string | | JSON variables |

---

#### `fail`

Mark a job as failed with optional error message and retry count

**Resources:** job

**Positional arguments:**

- **job:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--retries` | string | | Remaining retries |
| `--errorMessage` | string | | Error message |

---

#### `activate`

Activate jobs of a specific type for processing

**Resources:** jobs

**Positional arguments:**

- **jobs:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--maxJobsToActivate` | string | | Maximum number of jobs to activate |
| `--timeout` | string | | Job timeout in milliseconds |
| `--worker` | string | | Worker name |

---

#### `resolve`

Resolve an incident (marks resolved, allows process to continue)

**Resources:** inc (incident)

**Positional arguments:**

- **incident:** `` (required)

---

#### `publish`

Publish a message for message correlation

**Resources:** msg (message)

**Positional arguments:**

- **message:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--correlationKey` | string | | Correlation key |
| `--variables` | string | | JSON variables |
| `--timeToLive` | string | | Time to live in milliseconds |

---

#### `correlate`

Correlate a message to a specific process instance

**Resources:** msg (message)

**Positional arguments:**

- **message:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--correlationKey` | string | Yes | Correlation key |
| `--variables` | string | | JSON variables |
| `--timeToLive` | string | | Time to live in milliseconds |

---

#### `set`

Set variables on an element instance (process instance or flow element scope). Variables are propagated to the outermost scope by default; use --local to restrict to the specified scope.

**Usage:** `c8ctl set variable `

**Resources:** variable

**Positional arguments:**

- **variable:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--variables` | string | Yes | JSON object of variables to set (required) |
| `--local` | boolean | | Set variables in local scope only (default: propagate to outermost scope) |

**Examples:**

```bash
c8ctl set variable 2251799813685249 --variables='{"status":"approved"}' # Set variables on a process instance
c8ctl set variable 2251799813685249 --variables='{"x":1}' --local # Set variables in local scope only
```

---

#### `deploy`

Deploy files to Camunda (auto-discovers deployable files in directories). When deploying a directory that is inside a process application (a parent directory contains a .process-application marker), the entire application root is deployed. Explicit file paths are not expanded.

**Usage:** `c8ctl deploy [path...]`

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--force` | boolean | | Deploy any file type, ignoring the default extension allow-list |
| `--extensions` | string | | Comma-separated list of additional file extensions to include when scanning directories (e.g. .md,.txt). Explicit file paths bypass the extension allow-list. |
| `--all-extensions` | boolean | | Include all server-supported file extensions during directory discovery |

**Examples:**

```bash
c8ctl deploy ./my-process.bpmn # Deploy a BPMN file
c8ctl deploy # Deploy from current directory (detects process application root)
```

---

#### `run`

Deploy and start a process instance from a BPMN file

**Usage:** `c8ctl run `

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--variables` | string | | JSON variables |
| `--force` | boolean | | Deploy any file type, ignoring the default extension allow-list |

**Examples:**

```bash
c8ctl run ./my-process.bpmn # Deploy and start process
```

---

#### `assign`

Assign a resource to a target (--to-user, --to-group, etc.)

**Usage:** `c8ctl assign `

**Resources:** role, user, group, mapping-rule

**Positional arguments:**

- **role:** `` (required)
- **user:** `` (required)
- **group:** `` (required)
- **mapping-rule:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--to-user` | string | | Target user ID |
| `--to-group` | string | | Target group ID |
| `--to-tenant` | string | | Target tenant ID |
| `--to-mapping-rule` | string | | Target mapping rule ID |

**Examples:**

```bash
c8ctl assign role admin --to-user=john # Assign role to user
```

---

#### `unassign`

Unassign a resource from a target (--from-user, --from-group, etc.)

**Usage:** `c8ctl unassign `

**Resources:** role, user, group, mapping-rule

**Positional arguments:**

- **role:** `` (required)
- **user:** `` (required)
- **group:** `` (required)
- **mapping-rule:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--from-user` | string | | Source user ID |
| `--from-group` | string | | Source group ID |
| `--from-tenant` | string | | Source tenant ID |
| `--from-mapping-rule` | string | | Source mapping rule ID |

**Examples:**

```bash
c8ctl unassign role admin --from-user=john # Unassign role from user
```

---

#### `watch`

Watch files for changes and auto-deploy

**Usage:** `c8ctl watch [path...]`

**Aliases:** `w`

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--force` | boolean | | Continue watching after all deployment errors |
| `--extensions` | string | | Comma-separated list of additional file extensions to watch (merged with defaults, e.g. .md,.txt) |
| `--all-extensions` | boolean | | Watch all server-supported file extensions |
| `--process-application` | boolean | | Watch and deploy the entire process application (requires .process-application marker) |
| `--pa` | boolean | | Alias for --process-application |

**Examples:**

```bash
c8ctl watch ./src # Watch directory for changes
```

---

#### `open`

Open Camunda web app in browser

**Usage:** `c8ctl open `

**Resources:** operate, tasklist, modeler, optimize

**Examples:**

```bash
c8ctl open operate # Open Camunda Operate in browser
c8ctl open tasklist # Open Camunda Tasklist in browser
c8ctl open operate --profile=prod # Open Operate using a specific profile
```

---

#### `add`

Add a profile

**Resources:** profile

**Positional arguments:**

- **profile:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--baseUrl` | string | | Cluster base URL |
| `--clientId` | string | | OAuth client ID |
| `--clientSecret` | string | | OAuth client secret |
| `--audience` | string | | OAuth audience |
| `--oAuthUrl` | string | | OAuth token URL |
| `--defaultTenantId` | string | | Default tenant ID |
| `--username` | string | | Basic auth username |
| `--password` | string | | Basic auth password |
| `--from-file` | string | | Import from .env file |
| `--from-env` | boolean | | Import from environment variables |

---

#### `remove`

Remove a profile (alias: rm)

**Usage:** `c8ctl remove profile `

**Aliases:** `rm`

**Resources:** profile

**Positional arguments:**

- **profile:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--none` | boolean | | Clear active profile |

---

#### `load`

Load a c8ctl plugin (npm registry or URL)

**Usage:** `c8ctl load plugin [name|--from url]`

**Resources:** plugin

**Positional arguments:**

- **plugin:** `` (optional)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--from` | string | | Load plugin from URL |

**Examples:**

```bash
c8ctl load plugin my-plugin # Load plugin from npm registry
c8ctl load plugin --from https://github.com/org/plugin # Load plugin from URL
```

---

#### `unload`

Unload a c8ctl plugin (npm uninstall wrapper)

**Usage:** `c8ctl unload plugin `

**Aliases:** `rm`

**Resources:** plugin

**Positional arguments:**

- **plugin:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--force` | boolean | | Force unload without confirmation |

---

#### `upgrade`

Upgrade a plugin (respects source type)

**Usage:** `c8ctl upgrade plugin [version]`

**Resources:** plugin

**Positional arguments:**

- **plugin:** `` (required), `` (optional)

**Examples:**

```bash
c8ctl upgrade plugin my-plugin # Upgrade plugin to latest version
c8ctl upgrade plugin my-plugin 1.2.3 # Upgrade plugin to a specific version (source-aware)
```

---

#### `downgrade`

Downgrade a plugin to a specific version

**Usage:** `c8ctl downgrade plugin `

**Resources:** plugin

**Positional arguments:**

- **plugin:** `` (required), `` (required)

---

#### `sync`

Synchronize plugins from registry (rebuild/reinstall)

**Resources:** plugin

**Examples:**

```bash
c8ctl sync plugin # Synchronize plugins
```

---

#### `init`

Create a new plugin from TypeScript template

**Resources:** plugin

**Positional arguments:**

- **plugin:** `` (optional)

**Examples:**

```bash
c8ctl init plugin my-plugin # Create new plugin from template (c8ctl-plugin-my-plugin)
```

---

#### `doctor`

Surface plugin-loading collisions detected at startup (#363). Reports loaded plugins with their command names, and any first-registration-wins drops (plugin-name or command-name).

**Resources:** plugin

**Examples:**

```bash
c8ctl doctor plugin # List loaded plugins and any load-time collisions
c8ctl doctor plugin --json # Machine-readable doctor output
```

---

#### `use`

Set active profile or tenant

**Usage:** `c8ctl use profile|tenant`

**Resources:** profile, tenant

**Positional arguments:**

- **profile:** `` (optional)
- **tenant:** `` (required)

**Flags:**

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--none` | boolean | | Clear active profile/tenant |

**Examples:**

```bash
c8ctl use profile prod # Set active profile
```

---

#### `output`

Show or set output format

**Usage:** `c8ctl output [json|text]`

**Resources:** json, text

**Examples:**

```bash
c8ctl output json # Switch to JSON output
```

---

#### `completion`

Generate shell completion script

**Usage:** `c8ctl completion bash|zsh|fish|install`

**Resources:** bash, zsh, fish, install

**Resource-specific flags:**

install

| Flag | Type | Required | Description |
|------|------|----------|-------------|
| `--shell` | string | | Shell to install completions for (bash, zsh, fish) |

**Examples:**

```bash
c8ctl completion bash # Generate bash completion script
c8ctl completion install # Auto-detect shell and install completions (auto-refreshes on upgrade)
c8ctl completion install --shell zsh # Install completions for a specific shell
```

---

#### `mcp-proxy`

Start a STDIO MCP proxy (bridges local MCP clients to remote Camunda 8)

**Usage:** `c8ctl mcp-proxy [mcp-path]`

---

#### `feedback`

Open the feedback page to report issues or request features

---

#### `help`

Show help (run 'c8ctl help \' for details)

**Usage:** `c8ctl help [command]`

**Aliases:** `menu`

---

#### `which`

Show active profile or output mode

**Resources:** profile, output

**Examples:**

```bash
c8ctl which profile # Show currently active profile
c8ctl which output # Show current output mode
```

## License

Apache 2.0 - see LICENSE.md

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, testing, project structure, and how to add new commands. See [AGENTS.md](AGENTS.md) for commit conventions and coding standards.