
  Usage: gina connector:<action> [options]

  Actions:

    list                         List every connector declared by every
                                 registered project.
    list @<project>              List every connector for one project
                                 (shared + all bundles).
    list <bundle> @<project>     List the merged shared+bundle view that
                                 <bundle> sees at runtime.
    add <name> @<project>        Add a connector entry to
                                 shared/config/connectors.json.
    add <name> <bundle> @<project>
                                 Add a connector entry to the bundle's
                                 config/connectors.json.
    rm <name> @<project>         Remove a connector entry from
                                 shared/config/connectors.json.
    rm <name> <bundle> @<project>
                                 Remove a connector entry from the bundle's
                                 config/connectors.json.
    remove                       Alias for rm.
    migrate @<project>           Scan every connectors.json (shared + all
                                 bundles) for known issues. Dry run by
                                 default.
    migrate <bundle> @<project>  Scan just the bundle's connectors.json.
    help                         Show this message.

  Options (list):

    --format=json                Emit machine-readable JSON instead of the
                                 human-readable text table.

  Options (add):

    --connector=<type>           Driver type. One of: couchbase, mysql,
                                 postgresql, sqlite, redis, ai. Inferred
                                 from <name> when <name> matches one of
                                 those values.
    --driver=<type>              Synonym for --connector=.
    --protocol=<uri>             Connection protocol URI scheme
                                 (e.g. couchbase://, anthropic://).
                                 Required for ai connectors.
    --host=<host>                Hostname or IP. Comma-separated for
                                 clusters (e.g. db1.example.com,db2.example.com).
    --connector-port=<port>      Server port. Numeric when possible. Named
                                 `--connector-port=` (not `--port=`) because
                                 the framework reserves `--port=` for its own
                                 socket port. Written to the connector entry
                                 under the `port` key.
    --database=<name>            Database, bucket, or keyspace name.
    --username=<name>            Authentication username.
    --password=<value>           Authentication password. Supports
                                 \${ENV_VAR} interpolation.
    --scope=<scope>              Data isolation scope. One of: local,
                                 beta, production, testing.
    --model=<id>                 AI connector only. Default model id.
    --api-key=<value>            AI connector only. API key. Supports
                                 \${ENV_VAR} interpolation.
    --base-url=<url>             AI connector only. Override the provider
                                 base URL (OpenAI-compatible providers).
    --driver-version=<range>     Optional semver range to pin the driver
                                 install (e.g. ^5.0.0, >=5.3.0 <6.0.0).
                                 Named `--driver-version=` (not `--version=`)
                                 because the framework reserves the bare
                                 `--version` flag (maps to GINA_VERSION and
                                 triggers a framework migration). Written to
                                 the connector entry under the `version` key.
    --force                      Overwrite an existing entry with the
                                 same <name>.
    --install                    After writing the entry, run the detected
                                 package manager's install command for the
                                 resolved driver+range. Opt-in; default is
                                 "write entry, print hint".
                                 Package manager is detected by probing
                                 lockfiles in this order: bun.lockb →
                                 pnpm-lock.yaml → yarn.lock →
                                 package-lock.json. npm is the fallback
                                 when no lockfile is present.
                                 Install range resolution order:
                                 --driver-version= → project package.json
                                 dep → framework's built-in driver range.
                                 sqlite short-circuits (built-in); AI
                                 connectors with missing/unknown protocol
                                 exit 1 with guidance.

  Options (rm):

    --dry-run                    Print what would be removed without
                                 touching any file. Includes the sibling-
                                 usage hint.
    --force                      Skip the project-level guard that refuses
                                 to remove a shared connector while other
                                 bundles still reference it.

  Options (migrate):

    --fix                        Apply auto-fixable issues to disk. Without
                                 it, `connector:migrate` is a read-only
                                 dry run.
    --format=json                Emit machine-readable JSON instead of the
                                 human-readable text summary.

  Output columns (list, text mode):

    [ ok ]  driver installed, or built-in (node:sqlite).
    [ ?! ]  driver declared but not found at <project>/node_modules/<driver>.
    [ ?? ]  unknown connector type or missing/unrecognised `ai` protocol.
    [ !! ]  version-pin disagreement — two bundles pin the same driver at
            different versions; the first `npm install` wins.

    Row shape:
      <status> <name> <connector> [<source>] (<driver info>)

    Source label:
      [shared]                    Declared only in shared/config/connectors.json.
      [<bundle>]                  Declared only in <bundle>/config/connectors.json.
      [<bundle> override]         Declared in shared AND overridden by <bundle>.

  Notes:

    `connector:list` is read-only and offline — it does not contact the
    framework socket and makes no network calls. It scans:

      <project>/manifest.json            (bundle discovery)
      <project>/shared/config/connectors.json
      <project>/<bundle>/config/connectors.json    (per manifest)
      <project>/node_modules/<driver>/package.json (install check)

    `connector:add` writes the file at:

      <project>/shared/config/connectors.json      (no <bundle> passed)
      <project>/<bundle-src>/config/connectors.json (with <bundle>)

    After writing, `connector:add` prints the exact
    `npm install <driver>@"<range>"` command. The resolved range comes
    from `--version=` when supplied, otherwise from the framework's
    built-in driver range table.

    `connector:rm` writes to the same two targets (shared vs bundle) per
    positional-absence. It never uninstalls the npm driver — another
    bundle may still need it. After removal, `connector:rm` prints a
    driver-retention hint naming any siblings that still reference the
    same driver.

    Project-level `connector:rm` (no <bundle>) refuses to proceed when
    any bundle still declares the same logical name — pass --force to
    remove anyway. Bundle-level `connector:rm` always proceeds and
    leaves shared untouched.

    `connector:migrate` lints connectors.json for two issues:

      missing-schema             Top-level `$schema` key absent. Auto-
                                 fixable — injects
                                 "$schema": "https://gina.io/schema/connectors.json"
                                 at the top of the object.
      bare-key-no-connector      Entry has no `connector` field and its
                                 key is not in the built-in enum
                                 (couchbase, mysql, postgresql, sqlite,
                                 redis, ai). Warn only — the fix cannot
                                 be inferred. Re-declare via
                                 `gina connector:add <name> @<project>
                                 --connector=<type> --force`.

    `connector:migrate` is explicit and opt-in — the framework does NOT
    auto-migrate connectors.json at bundle boot. Run it in CI or before
    committing.

    `connectors.json` files are parsed with `//` and `/* */` comment
    tolerance. `connector:add`, `connector:rm`, and `connector:migrate`
    preserve any comment header above the first `{`, but mid-body
    comments are lost on rewrite.

    Driver resolution uses the framework's built-in driver range table
    (see `lib/cmd/connector/add.js` DRIVER_MAP):

      couchbase     → couchbase            >= 3.0.0
      redis         → ioredis              >= 5.0.0
      mysql         → mysql2               >= 2.0.0
      postgresql    → pg                   >= 8.0.0
      mongodb       → mongodb              >= 7.0.0
      scylladb      → cassandra-driver     >= 4.0.0
      sqlite        → built-in (node:sqlite, Node >= 22.5.0)
      ai            → resolved from `protocol` (anthropic:// → @anthropic-ai/sdk,
                                                openai://, deepseek://, …  → openai)

  Examples:

    gina connector:list                                                Every project, every connector
    gina connector:list @myproject                                     One project, all bundles + shared
    gina connector:list admin @myproject                               What `admin` sees at runtime
    gina connector:list --format=json                                  JSON output for scripting

    gina connector:add redis @myproject --host=127.0.0.1 --connector-port=6379
                                                                       Shared Redis, type inferred from name
    gina connector:add session @myproject --connector=redis --host=127.0.0.1 --connector-port=6379
                                                                       Shared Redis under a custom name
    gina connector:add mydb api @myproject --connector=mysql --database=mydb --username=root
                                                                       Bundle-scoped MySQL entry
    gina connector:add claude @myproject --connector=ai --protocol=anthropic:// --api-key=\${ANTHROPIC_API_KEY}
                                                                       AI connector with env-var secret
    gina connector:add session @myproject --connector=redis --driver-version=^5.0.0 --force
                                                                       Pin driver version, overwrite existing
    gina connector:add redis @myproject --install
                                                                       Write entry AND run `npm install ioredis@<range>` (lockfile-detected PM)

    gina connector:rm session @myproject                               Remove shared entry (fails if any bundle uses it)
    gina connector:rm session api @myproject                           Remove from api bundle only
    gina connector:rm session @myproject --dry-run                     Preview removal + usage warnings
    gina connector:rm session @myproject --force                       Remove shared entry even if bundles still use it

    gina connector:migrate @myproject                                  Dry-run lint across shared + all bundles
    gina connector:migrate api @myproject                              Dry-run lint of the api bundle only
    gina connector:migrate @myproject --fix                            Apply auto-fixable issues (inject $schema)
    gina connector:migrate @myproject --format=json                    JSON report for scripting / CI

