RunWhen Local

repository·main·Indexed 41 days ago

https://github.com/runwhen-contrib/runwhen-local

A discovery and automation engine that indexes cloud and Kubernetes infrastructure to generate tailored 'Skills' (SLXs) for AI agents and production runtimes. It features platform-specific indexers for AWS, GCP, Azure, and Kubernetes, and utilizes a Level of Detail (LOD) mechanism to control the depth of resource discovery.

Tokens
186.5K
Snippets
262
Records
424
Agent score
50%

What's inside RunWhen Local

  1. What is RunWhen Local?

    main

    RunWhen Local is a tool that discovers cloud and Kubernetes infrastructure and transforms it into tailored, AI-agent-ready Skills. It operates in two modes:

    1. Standalone Mode: Runs on your local machine via Docker. It is used for free, local exploration. It includes a built-in Model Context Protocol (MCP) server that allows AI agents (like Claude Code, Cursor, or Claude Desktop) to search, browse, and read your environment's tailored Skills. Note that standalone MCP is currently read-only (search, browse, and preview).
    2. Connected Mode: Deployed via Helm into a Kubernetes cluster. It connects to the RunWhen Platform to provide managed, production-grade execution, including RBAC, scheduling, secret management, and auditing.

    The discovery engine and generated Skills are identical in both modes; only the consumption and execution methods differ.

  2. Overview of RunWhen Local features

    main

    RunWhen Local is an open-source tool designed to provide tailored troubleshooting capabilities for Kubernetes and cloud environments. Key features include:

    • Tailored troubleshooting commands: Provides curated commands specific to your environment.
    • Workspace Builder pipeline: A composable pipeline for discovery, enrichment, and rendering, accessible via a REST API or the ./run.sh script.
    • Agentic access via MCP: Includes a built-in Model Context Protocol (MCP) server, allowing AI agents (like Claude Code, Cursor, or Claude Desktop) to search and read generated Skills.
    • Copy-paste friendly output: Generated SLX configurations and command lists are saved to /shared/output for easy terminal use or upload to the RunWhen Platform.
    • Extensibility: Users can contribute to development or add custom troubleshooting commands to public or private CodeCollections.
  3. Understand the RunWhen Local architecture

    main

    RunWhen Local is composed of several key components that work together to transform cloud state into an agent-ready workspace. The core pipeline involves:

    1. Indexers: Platform-specific components (AWS, GCP, Azure, Kubernetes) that pull state from cloud providers.
    2. Resource Store: An intermediate datastore that acts as the bridge between indexers and renderers.
    3. Workspace Assembly: The process of combining indexed resources and rendered components into a final workspace.
    4. Agentic Surface: An MCP (Model Context Protocol) server that exposes the indexed resources and rendered Skills to AI agents.

    Depending on your deployment, the architecture follows either a disconnected (standalone) model or a connected (self-hosted runner) model.

  4. Overview of the MCP Server design

    main

    The Model Context Protocol (MCP) server in runwhen-local provides a read-only interface for agentic clients (like Claude Code) to access your indexed environment. It acts as a thin wrapper over the existing SQLite resource store, exposing discovered resources and rendered Skills via the MCP protocol.

    Key Characteristics:

    • Read-Only: The current version (v1) is strictly read-only to ensure safety. Execution of actions happens on the RunWhen Platform, not locally.
    • Context-Aware: Content is automatically clipped to MAX_CONTENT_CHARS = 32_000 per artifact to prevent overwhelming agent context windows.
    • Tool-Based: It exposes 12 specialized tools for searching and inspecting resources and skills.
    • Prompt-Driven: It includes canned investigation prompts that agents can use to orchestrate complex workflows.
  5. What is the RunWhen Local MCP server?

    main

    RunWhen Local includes a built-in Model Context Protocol (MCP) server that provides AI agents (like Claude Code, Cursor, or Claude Desktop) with read-only access to your discovered environment Skills.

    It allows agents to search, browse, and read the Skills generated by the workspace-builder for your specific environment. This enables agents to ground their reasoning in your actual resources (Kubernetes, Azure, AWS, GCP) without needing to execute commands directly (v1 is read-only).

    Key characteristics:

    • Read-only: Tools perform SELECT queries against the local SQLite resource store.
    • Consistency: The agent sees the same data as a human using the /explorer/ UI.
    • No Execution: The server provides Skill data (YAML + Markdown) and invocation previews, but does not execute them. Execution is handled by the RunWhen Platform or a future local micro-runtime.
  6. How Kubernetes Level of Detail (LOD) is determined

    main

    RunWhen Local determines the Level of Detail (LOD) for each Kubernetes namespace using a hierarchical priority system. When discovering namespaces, the system checks for configuration in a specific order, stopping at the first match found. This allows you to set broad defaults while providing granular overrides for specific namespaces or clusters.

    The determination follows this priority order:

    1. Namespace Annotations: The highest priority. If a namespace has the runwhen.com/lod annotation, it overrides all other configurations.
    2. Context-Specific namespaceLODs: If no annotation exists, the system checks the specific context configuration for a mapping of that namespace to an LOD.
    3. Global namespaceLODs: If no context-specific mapping is found, the system checks the global namespaceLODs configuration.
    4. Context defaultNamespaceLOD: If no specific namespace mapping is found, the system uses the default LOD defined for that specific context.
    5. Global defaultLOD: The final fallback if no other settings are found.
    Priority Hierarchy:
    1. Namespace Annotations (runwhen.com/lod)
    2. Context-Specific namespaceLODs
    3. Global namespaceLODs
    4. Context defaultNamespaceLOD
    5. Global defaultLOD
  7. How Kubernetes Config Reload works

    main

    When RunWhen Local runs in Kubernetes with continuous discovery enabled (AUTORUN_WORKSPACE_BUILDER_INTERVAL), it automatically restarts the pod when a mounted ConfigMap or Secret changes. This is necessary because Kubernetes subPath volume mounts (used for files like /shared/workspaceInfo.yaml) are never updated in-place; the file inside the pod remains stale until the pod is recreated.

    Mechanism:

    1. The config_reloader.py process runs in the background.
    2. It discovers mounted ConfigMaps and Secrets by reading the pod's spec.volumes.
    3. It watches these objects via the Kubernetes API.
    4. When a change is detected, the reloader signals the entrypoint via SIGUSR1 and exits.
    5. The entrypoint terminates with exit code 1, triggering the Kubernetes Deployment controller to start a new pod with fresh mounts.
    sequenceDiagram
        participant Admin
        participant API as Kubernetes API
        participant Reloader as config_reloader.py
        participant Entry as entrypoint.sh
        participant Kubelet
    
        Admin->>API: Update ConfigMap / Secret
        API-->>Reloader: MODIFIED watch event
        Reloader->>Reloader: Compare .data fingerprint
        Reloader->>Entry: exit 0
        Entry->>Entry: exit 1
        Kubelet->>Kubelet: Restart pod with fresh mounts
  8. Understand resourcePath computation

    main

    The resourcePath is never explicitly set in templates. It is automatically derived at render time by the compute_resource_path_from_hierarchy() function in src/renderers/render_output_items.py using the following logic:

    1. It reads the hierarchy list from spec.additionalContext.hierarchy.
    2. It builds a lookup from spec.tags (mapping tag name to its first value).
    3. It walks the hierarchy in order, collecting each tag's value.
    4. It joins these values with / to form the final resourcePath.

    Important: Do not attempt to add resourcePath or qualified_name logic to your templates. The hierarchy is the single source of truth for path construction.

  9. How resource-type matching works in RunWhen Local

    main

    RunWhen Local matches resources to generation rules using a resourceTypes list in the rule specification.

    Historically, matching required an exact string match between the name requested in a rule and the name stored by the indexer. The system has transitioned to an alias-aware, registry-driven matching model to support both legacy and canonical names.

    The Matching Mechanism

    1. Requested Name: A rule (e.g., in a rw-cli-codecollection) requests a type like azure_compute_virtual_machines.
    2. Resolver: The PlatformHandler.get_resources method uses a resolver to map the requested name to an accepted-name set (match_names) within the resource Registry.
    3. Union Matching: A resource matches a rule if the rule's requested type exists anywhere within that resource's match_names set, regardless of which specific name the indexer used for storage.

    Fallback Behavior

    For platforms not in a cloud registry (e.g., Kubernetes custom resources or the azure_devops platform), the system falls back to exact-string equality matching.

    spec:
      platform: azure
      generationRules:
        - resourceTypes: [azure_compute_virtual_machines]
          matchRules: [...]
          slxs: [...]
  10. Use GCP Secret Patterns in Robot Framework

    main

    RunWhen Local provides specialized secret patterns for Robot Framework to handle GCP authentication and GKE kubeconfig generation automatically.

    Service Account Patterns

    • CLI Authentication: gcp:sa@cli
    • Kubeconfig Generation: gcp:sa@kubeconfig:CLUSTER_NAME/ZONE_OR_REGION (supports both zonal and regional patterns)

    Application Default Credentials (ADC) Patterns

    • CLI Authentication: gcp:adc@cli
    • Kubeconfig Generation: gcp:adc@kubeconfig:CLUSTER_NAME/ZONE_OR_REGION
    *** Settings ***
    Library    RW.Core
    
    *** Test Cases ***
    GCP Service Account Example
        Import Secret    gcp_projectId
        Import Secret    gcp_serviceAccountKey
        Import Secret    my_gke_kubeconfig
        Shell    kubectl get nodes
    
    Multi Environment Example
        # Production environment
        Import Secret    prod_gke_kubeconfig     # gcp:sa@kubeconfig:prod-cluster/us-east1
        
        # Staging environment  
        Import Secret    staging_gke_kubeconfig  # gcp:sa@kubeconfig:staging-cluster/us-west1
        
        Shell    kubectl --kubeconfig=${prod_gke_kubeconfig} get nodes
  11. Match Azure resources using built-in properties

    main

    Every Azure resource indexed by RunWhen includes a set of default properties that can be used in matchRules.

    Default properties:

    • name: The resource name.
    • tags, tag-keys, tag-values: The Azure tags associated with the resource.
    • resource_group: The name of the parent resource group.
    • location: The Azure region.

    Accessing raw JSON fields: To access deep fields within the resource payload (for typed resources), use the resource/<path> syntax. For example:

    • resource/properties/storageProfile/osDisk/osType
    • resource/properties/vaultUri

    Note that properties are only available for typed resources. Generic resources only support the default properties listed above.