# Config reference

A `cockpit.yaml` lives at the root of your project. The cockpit reads it on startup, auto-migrates older `version:` to the current `CONFIG_VERSION`, and seeds the store from it.

## Top-level keys

| Key | Type | Required | Notes |
|---|---|---|---|
| `version` | number | yes | Current schema version is `2`. Older versions migrate in memory (with a stderr warning); run `dev-cockpit migrate-config` to persist. |
| `appName` | string | yes | State-dir name (`$XDG_STATE_HOME/<appName>/<workspace-hash>/`) + OS-notification title prefix. |
| `processes` | array | no | Long-running commands streamed into the Output pane. See `processes:` below. |
| `repos` | array | no | Code-side rows in the Targets pane. |
| `docker` | object | no | `composeFile` + `services[]`. Omit on plain-Node projects. |
| `highlights` | array | no | Regex patterns applied to all output streams (process + docker). Each can carry an explicit `severity:` (else inferred). |
| `health` | array | no | Health check declarations — see `health:` below. |
| `actions` | array | no | Named, optionally key-bound shell commands surfaced via the `:` palette and the Targets pane. |
| `mount` | object | no | `overlayPath`, `manifestFile` overrides. Defaults: `docker-compose.dev-cockpit.yml`, `mount.manifest.json`. |
| `mounts` | array | no | Explicit `{hostPath, containerPath, meta?}` entries for `dev-cockpit mount`. |
| `help` | object | no | Extra `sources[]` + `defaultPage`. |
| `notifications` | object | no | `enabled`, `onTransitionTo[]`, `exclude[]`. |
| `defaultPane` | enum | no | `repos` (default) \| `output` \| `health` \| `help`. Falls back to Output when the requested tab is hidden. |
| `profile` | object | no | Namespace for profile-specific extension keys (`profile.<appName>: { ... }`). Each profile validates its block via its `configSchemaExt` (see [ADR 0005](../adr/0005-strict-profile-namespace.md)). |

## `processes:`

```yaml
processes:
  - id: vite               # required, stable identifier; used as Output source tag and Targets row id
    label: Vite dev        # optional, displayed in Targets / Output
    command: npm run dev   # shell command; runs via sh -c (cmd /c on Windows)
    cwd: ./apps/web        # optional; relative to workspaceRoot
    env:                   # optional; merged on top of process.env
      DEBUG: '1'
```

Each process gets:
- A row in the Targets pane (kind: `process`) with a built-in `[r] Restart <id>` action (kill via SIGTERM, respawn) backed by the tagged-spawn lookup.
- Output lines tagged by `label` or `id`.
- Highlight matching against `config.highlights[]` — matched lines use the configured severity (overriding the default `info` for stdout / `warn` for stderr).

## `actions:`

```yaml
actions:
  - id: test                    # required, unique
    label: Run tests            # required, shown in the `:` palette + Targets action panel
    command: npm test           # required for YAML; profiles can supply `invoke:` instead (TS-only)
    cwd: ./api                  # optional
    scope: global               # 'global' | 'repos' | 'repos:<rowId>'  (default: 'global')
    key: t                      # optional single keystroke; fires within scope (in addition to `:`)
```

Scope semantics:
- `global` — `:` palette only.
- `repos` — `:` palette AND fires on any selected Targets row when the keystroke matches.
- `repos:<id>` — fires only when that specific row is selected.

Built-in actions are synthesized automatically:
- Each docker service: `__builtin:restart-docker:<svc>` with `scope: repos:<svc>`, `key: r`.
- Each process: `__builtin:restart-process:<id>` with `scope: repos:<id>`, `key: r`.

User-declared actions with the same `(scope, key)` shadow the built-in.

## `health:`

See [health.md](./health.md). Brief shape:

```yaml
health:
  - id: app-up
    label: app responsive
    type: http-ok            # container-running | port-open | http-ok | file-exists | exec-zero
    url: http://localhost:3000/health   # type-specific args
    severity: error                     # ok | warn | error
    triggers: [startup, fsevent]        # optional; defaults to ['startup']
    notify: { onTransitionTo: ['error'] }  # optional per-check override
    remediation:
      key: R
      label: restart app
      command: docker compose restart app
      cwd: .                              # optional
```

## `mount:` + `mounts:`

```yaml
mount:                                                # path overrides
  overlayPath: docker-compose.dev-cockpit.yml         # workspace-relative
  manifestFile: mount.manifest.json                   # basename within stateDir

mounts:                                               # explicit candidates
  - hostPath: ./packages/api
    containerPath: /srv/api
    meta:                                             # opaque to dev-cockpit; profile hooks read it
      name: api
```

Full mount story: [mount.md](./mount.md).

## `notifications:`

```yaml
notifications:
  enabled: true
  onTransitionTo: []   # restrict to specific destination states; empty = all transitions
  exclude: []          # `NotifiableEvent` strings to suppress
```

See [notifications.md](./notifications.md).

## `help:`

```yaml
help:
  sources:
    - ./docs            # directory tree of markdown pages
  defaultPage: getting-started
```

Profiles can contribute their own `helpSources` that layer over the generic docs.

## Example

A fully-commented example lives at `examples/cockpit.yaml` in the dev-cockpit package. Copy it as a starting point and trim what doesn't apply.
