name: port-forward
description: Establish local connections to cluster services like databases, brokers, and APIs. Use when asked about "port-forward", "connect to database", "local connection", "tunnel", "forward port", "access service locally". TRIGGER when: user asks "port-forward to X", "connect to database locally", "tunnel to service", "forward port", "access service locally", "open local connection to X". SKIP: checking service health (use service-status); running queries (use db-query).
allowed-tools: Bash AskUserQuestion
argument-hint: "[service] [environment]"
model: haiku
Step 0 — Load configuration
Check if /tmp/ops-suite-session/config.json exists:
- If yes, read it (pre-parsed by session-start hook).
- If no, read
${XDG_CONFIG_HOME:-$HOME/.config}/ops-suite/config.yaml (preferred) or the plugin's config.yaml (legacy), parse it, and write to /tmp/ops-suite-session/config.json for other skills to reuse.
If neither exists, tell the user to run /ops-suite:configure (or copy config.example.yaml to ~/.config/ops-suite/config.yaml and fill in their values). Stop here.
Extract:
orchestrator — determines which adapter to load
environments — available environments and their connection details
service_registry — known services with their ports and namespaces
deploy.local_ports — preferred local port mappings
Step 1 — Load adapter
Read the adapter file at adapters/{orchestrator}.md (in this skill's directory).
If the adapter does not exist, tell the user that the orchestrator {orchestrator} is not yet supported and stop.
Step 2 — Determine target environment and service
If $ARGUMENTS contains an environment name, use it. Otherwise ask the user.
If $ARGUMENTS contains a service name, check it against service_registry.
If the service is found in service_registry, use its predefined configuration:
namespace, service, port, verify
If the service is NOT in the registry:
- Use the adapter's "search services" command to find matching services
- Ask the user to confirm the target and port
Step 3 — Resolve local port
Determine the local port:
- If the service is a database and
deploy.local_ports.{env} is defined, use that
- If the service_registry entry has a port, use the same port locally
- Otherwise, pick a sensible default and confirm with the user
Check for port conflicts using the adapter's "check port" command. If the port is in use, suggest an alternative.
Step 4 — Establish connection
Run the adapter's "port-forward" command in the background.
Wait briefly and verify the connection using:
- The
verify command from service_registry (if defined)
- Or a basic TCP connection check
Step 5 — Provide connection details
Display to the user:
Port-forward active:
Service: {service_name}
Remote: {remote_host}:{remote_port}
Local: localhost:{local_port}
Namespace: {namespace}
Connection string: {connection_string_if_applicable}
To stop: kill the background process or press Ctrl+C
PID: {pid}
Step 6 — Credentials (if needed)
If the service requires credentials (e.g., database):
- Never hardcode credentials
- Use the adapter's "retrieve secret" command if available
- Otherwise, ask the user to provide credentials
- Display the connection string with credential placeholders
Important notes
- Always check for existing port-forwards to avoid conflicts
- Always provide cleanup instructions
- Never log or display passwords in plain text