Skip to content
rshadePublic

About

FinOps CLI for Pulumi — projected costs, actual spend tracking, budget enforcement, and cost optimization for cloud infrastructure

Topics

Resources

Contributing

Stars

10 stars

Watchers

0 watching

Forks

Latest commit

 

History

816 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FinFocus

Cloud cost analysis for Pulumi infrastructure

CI codecov Go Report Card Go Version Release License: Apache-2.0

Cloud cost analysis for Pulumi infrastructure - Calculate projected and actual infrastructure costs without modifying your Pulumi programs.

FinFocus is a CLI tool that analyzes Pulumi infrastructure definitions to provide accurate cost estimates, budget enforcement, and historical cost tracking through a flexible plugin-based architecture.

Why FinFocus?

Cloud cost surprises are the norm. Teams deploy infrastructure with Pulumi but have no visibility into what it will cost until the bill arrives. FinFocus closes that gap:

  • Shift-left on costs — See projected costs before you deploy, directly from pulumi preview output
  • No code changes required — Works with any existing Pulumi project via JSON export
  • Budget guardrails — Enforce spending limits in CI/CD pipelines with non-zero exit codes
  • Plugin architecture — Swap pricing sources without changing your workflow
  • Single dashboard — Interactive TUI combining actual spend, projected costs, drift analysis, and recommendations

Key Features

  • 🔭 Unified Overview: Interactive dashboard combining actual costs, projected costs, drift analysis, and recommendations in a single view
  • 📊 Projected Costs: Estimate monthly costs before deploying infrastructure
  • 💰 Budgets & Alerts: Hierarchical budgets (global, provider, tag, type) with CI/CD thresholds
  • 💡 Recommendations: Actionable cost optimization insights and savings opportunities
  • ♿ Accessibility: High-contrast, plain text, and adaptive terminal UI modes
  • 💰 Actual Costs: Track historical spending with detailed breakdowns
  • ☸️ Cluster Cost Allocation: Split Kubernetes cluster cost by namespace, controller, pod, node, or label with conservation guarantees
  • 🔌 Plugin-Based: Extensible architecture supporting multiple cost data sources
  • 🧪 E2E Testing: Comprehensive guide for validating infrastructure costs against real cloud resources
  • 📈 Advanced Analytics: Resource grouping, filtering, and aggregation
  • 📱 Multiple Formats: Table, JSON, and NDJSON output options
  • 🔍 Smart Filtering: Filter by resource type, tags, or custom expressions
  • 🏗️ No Code Changes: Works with existing Pulumi projects via JSON output

Quick Start

1. Installation

Install script (recommended) -- auto-detects OS/architecture and downloads the latest release:

curl -fsSL https://raw.githubusercontent.com/rshade/finfocus/main/scripts/install.sh | sh

Build from source:

git clone https://github.com/rshade/finfocus
cd finfocus
make build
./bin/finfocus --help
Manual download (pin to a specific version)
# Linux (amd64)
curl -L https://github.com/rshade/finfocus/releases/download/v0.3.3/finfocus-v0.3.3-linux-amd64.tar.gz -o finfocus.tar.gz
tar -xzf finfocus.tar.gz
chmod +x finfocus
sudo mv finfocus /usr/local/bin/

# macOS (Apple Silicon)
curl -L https://github.com/rshade/finfocus/releases/download/v0.3.3/finfocus-v0.3.3-macos-arm64.tar.gz -o finfocus.tar.gz
tar -xzf finfocus.tar.gz && chmod +x finfocus && sudo mv finfocus /usr/local/bin/

# macOS (Intel)
curl -L https://github.com/rshade/finfocus/releases/download/v0.3.3/finfocus-v0.3.3-macos-amd64.tar.gz -o finfocus.tar.gz
tar -xzf finfocus.tar.gz && chmod +x finfocus && sudo mv finfocus /usr/local/bin/
# Windows - installs to a user-local directory, no admin rights required
Invoke-WebRequest -Uri "https://github.com/rshade/finfocus/releases/download/v0.3.3/finfocus-v0.3.3-windows-amd64.zip" -OutFile finfocus.zip
Expand-Archive finfocus.zip -DestinationPath .
$installDir = "$env:LocalAppData\Programs\finfocus"
New-Item -ItemType Directory -Force -Path $installDir | Out-Null
Move-Item finfocus.exe "$installDir\finfocus.exe"
# Add to PATH for the current session (add to $PROFILE for a permanent effect)
$env:PATH = "$installDir;$env:PATH"

2. Generate Pulumi Plan

Export your infrastructure plan to JSON:

cd your-pulumi-project
pulumi preview --json > plan.json

3. Unified Overview

See all costs at a glance with the interactive dashboard. From inside any Pulumi project directory, just run finfocus with no arguments:

finfocus

Or invoke the subcommand directly:

finfocus overview

For CI/CD or when you manage the export step yourself:

# Pre-export state and plan
pulumi stack export > state.json
pulumi preview --json > plan.json

# Launch overview with pre-exported files
finfocus overview --pulumi-state state.json --pulumi-json plan.json --plain --yes

Example plain text output (--plain). Amounts are sample data:

RESOURCE     TYPE                      STATUS       ACTUAL(MTD)  PROJECTED   DELTA       DRIFT%  RECS  WARN
--------     ----                      ------       -----------  ---------   -----       ------  ----  ----
my-instance  aws:ec2/instance:Inst...  ✓ active     $12.40       $15.00      +$6.20      +18% ⚠  2     drift
my-bucket    aws:s3/bucket:Bucket      ✓ active     $0.83        $1.00       -           -       -     -
my-db        aws:rds/instance:Inst...  ✓ active     $48.20       $50.00      -$8.40      -15% ⚠  1     drift

SUMMARY      prod                      3 resources  $61.43 USD   $66.00 USD  -$2.20 USD

Full documentation: Overview command

Browser dashboard

Run from the folder containing your Pulumi program:

finfocus --web

FinFocus starts a local server, prints its session URL, and opens your browser. Use --no-browser on SSH or CI, and --port 8484 when you need a fixed port. The Overview, Cost, Recommendations, and Estimate views use the same Go engine and plugins as the CLI and TUI. Keyboard navigation, resource details, cluster expansion, and light/dark themes are available in the browser.

Sources follow finfocus overview: auto-detect the current Pulumi project and stack, or pass --pulumi-json plan.json / --pulumi-state state.json. --stack, --from, --to, --adapter, and --filter are also accepted. These source flags, --port, and --no-browser are root-local companions to --web; they are rejected without it. --web is mutually exclusive with --mcp. Terraform inputs are outside the web UI's current scope.

The Cost view's group selector and tag filter, and the Recommendations view's Include dismissed toggle, add browser controls for existing CLI flags. The TUI fixes grouping at launch and has no include-dismissed toggle. Estimate changes are temporary what-if calculations; the dashboard cannot change infrastructure or dismiss recommendations. Use Run preview for an on-demand Pulumi preview and restart the session to load fresh actual costs.

Keep the printed URL private: its token opens an authenticated local session. The server binds to loopback, replaces the token in the address bar with an HTTP-only session cookie, and checks request origins. Encrypted stacks use a masked browser passphrase prompt with retries. Stop the server with Ctrl+C; closing a browser tab leaves it running.

See the web UI guide for launch options, storage behavior, and browser test commands.

4. Calculate Costs

Projected Costs - Estimate costs before deployment:

finfocus cost projected --pulumi-json plan.json

Forecast - Project that monthly cost forward. Plugins report a growth model. --growth-rate 0.10 is 10% per month. The chart is plain text, and --output json returns the same points with timestamps.

finfocus cost forecast --pulumi-json plan.json --growth-type linear --growth-rate 0.10

Check Budget - Verify if plan fits within budget:

# Configure budget in ~/.finfocus/config.hujson (see Configuration section)
# Then check projected cost against budget
finfocus cost projected --pulumi-json plan.json

# Exit with non-zero code if budget exceeded (CI/CD integration)
finfocus cost projected --pulumi-json plan.json --exit-on-threshold

# Custom exit code (default: 1)
finfocus cost projected --pulumi-json plan.json --exit-on-threshold --exit-code 2

# Filter budget scope (global, provider:<name>, tag:<key>=<value>, type:<resource-type>)
finfocus cost projected --pulumi-json plan.json --budget-scope "provider:aws"

View Recommendations - Find savings opportunities:

finfocus cost recommendations --pulumi-json plan.json

Example Output

Projected Cost Analysis

$ finfocus cost projected --pulumi-json examples/plans/aws-simple-plan.json

Budget: $500.00 (75% used)
[=====================>......] $375.00 / $500.00

RESOURCE                          ADAPTER     MONTHLY   CURRENCY  NOTES
aws:ec2/instance:Instance         aws-spec    $375.00   USD       t3.xlarge
aws:s3/bucket:Bucket             none        $0.00     USD       No pricing info

Actual Cost Analysis

$ finfocus cost actual --pulumi-json plan.json --from 2025-01-01 --group-by type --output json
{
  "summary": {
    "totalMonthly": 45.67,
    "currency": "USD",
    "byProvider": {"aws": 45.67},
    "byService": {"ec2": 23.45, "s3": 12.22, "rds": 10.00}
  },
  "resources": [...]
}

Core Concepts

Resource Analysis Flow

  1. Export - Generate Pulumi plan JSON with pulumi preview --json
  2. Parse - Extract resource definitions and properties
  3. Query - Fetch cost data via plugins or local specifications
  4. Aggregate - Calculate totals with grouping and filtering options
  5. Output - Present results in table, JSON, or NDJSON format

Plugin Architecture

FinFocus uses plugins to fetch cost data from various sources:

  • Cost Plugins: Query cloud provider APIs (AWS Public Pricing, AWS Cost Explorer, Azure, etc.)
  • Spec Files: Local YAML/JSON pricing specifications as fallback
  • Plugin Discovery: Automatic detection from ~/.finfocus/plugins/

Configuration

FinFocus is configured via ~/.finfocus/config.hujson. Configuration files use Hujson format (JSON with // comments and trailing commas allowed). Legacy config.yaml files are automatically migrated to Hujson format on first read.

Budget Configuration

# yaml-language-server: $schema=https://rshade.github.io/finfocus/schemas/config.json
cost:
  budgets:
    amount: 500.00
    currency: USD
    alerts:
      - threshold: 80
        type: actual
      - threshold: 100
        type: forecasted

See Budget Guide for full configuration details.

Budget Notifications

Send a Slack message or a JSON event to an HTTPS webhook when an alert threshold is crossed. Add destinations to an alert in the global config:

{
  "cost": {
    "budgets": {
      "global": {
        "amount": 500,
        "currency": "USD",
        "alerts": [
          {
            "threshold": 80,
            "type": "actual",
            "notifications": [{"type": "slack", "url": "${FINFOCUS_NOTIFY_SLACK_URL}"}]
          }
        ]
      }
    }
  }
}

Notifications are opt-in per run (--notify or FINFOCUS_NOTIFY=true), never change the exit code, and only expand ${FINFOCUS_NOTIFY_*} variables from the global config. See Budget Notifications.

Environment Variables for Secrets

For sensitive values like API keys and credentials, use environment variables:

# AWS credentials (for aws-public and aws-ce plugins)
export FINFOCUS_PLUGIN_AWS_ACCESS_KEY_ID="your-access-key"
export FINFOCUS_PLUGIN_AWS_SECRET_ACCESS_KEY="your-secret-key"

# Azure credentials (for azure-public plugin)
export FINFOCUS_PLUGIN_AZURE_SUBSCRIPTION_ID="your-subscription-id"

The naming convention is: FINFOCUS_PLUGIN_<PLUGIN_NAME>_<KEY_NAME> in uppercase.

Cost Allocation Tags

For accurate month-long cost tracking — especially when resources are replaced or destroyed mid-month — FinFocus can query cloud billing APIs by resource tags. This requires your Pulumi-managed resources to carry consistent tags.

Why this matters: When a resource is replaced (e.g., EC2 instance swap), the old cloud ID disappears from Pulumi state. Without tags, FinFocus can only see costs for the current resource. With tags like pulumi:project on both the old and new resources, billing APIs return the full month's costs.

Important: Pulumi does not automatically tag cloud resources with pulumi:project or pulumi:stack. These are stack-level metadata only. You must explicitly configure resource tagging using one of the methods below.

AWS — Provider Default Tags

Option A: Stack configuration (static values)

# Pulumi.dev.yaml
config:
  aws:defaultTags:
    tags:
      pulumi:project: my-app
      pulumi:stack: dev
      Environment: development
      CostCenter: "12345"

Option B: Explicit provider in code (dynamic values)

TypeScript:

const provider = new aws.Provider("tagged", {
  defaultTags: {
    tags: {
      "pulumi:project": pulumi.getProject(),
      "pulumi:stack": pulumi.getStack(),
      "Environment": "dev",
    },
  },
});

// Use this provider for all resources
const bucket = new aws.s3.Bucket("data", {}, { provider });

Go:

provider, _ := aws.NewProvider(ctx, "tagged", &aws.ProviderArgs{
    DefaultTags: &aws.ProviderDefaultTagsArgs{
        Tags: pulumi.StringMap{
            "pulumi:project": pulumi.String(ctx.Project()),
            "pulumi:stack":   pulumi.String(ctx.Stack()),
            "Environment":    pulumi.String("dev"),
        },
    },
})

// Use this provider for all resources
bucket, _ := s3.NewBucket(ctx, "data", nil, pulumi.Provider(provider))

Python:

provider = aws.Provider("tagged", default_tags={
    "tags": {
        "pulumi:project": pulumi.get_project(),
        "pulumi:stack": pulumi.get_stack(),
        "Environment": "dev",
    },
})

# Use this provider for all resources
bucket = aws.s3.Bucket("data", opts=pulumi.ResourceOptions(provider=provider))

After tagging: Activate pulumi:project and pulumi:stack as Cost Allocation Tags in the AWS Billing Console. Tags take ~24 hours to appear in Cost Explorer.

GCP — Provider Default Labels

GCP labels must be lowercase with hyphens/underscores only (no colons). Use pulumi_project instead of pulumi:project.

Option A: Stack configuration

# Pulumi.dev.yaml
config:
  gcp:defaultLabels:
    pulumi_project: my-app
    pulumi_stack: dev
    environment: development
    cost_center: "12345"

Option B: Explicit provider in code

TypeScript:

const provider = new gcp.Provider("tagged", {
  defaultLabels: {
    pulumi_project: pulumi.getProject(),
    pulumi_stack: pulumi.getStack(),
    environment: "dev",
  },
});

Go:

provider, _ := gcp.NewProvider(ctx, "tagged", &gcp.ProviderArgs{
    DefaultLabels: pulumi.StringMap{
        "pulumi_project": pulumi.String(ctx.Project()),
        "pulumi_stack":   pulumi.String(ctx.Stack()),
        "environment":    pulumi.String("dev"),
    },
})

Python:

provider = gcp.Provider("tagged", default_labels={
    "pulumi_project": pulumi.get_project(),
    "pulumi_stack": pulumi.get_stack(),
    "environment": "dev",
})

Note: GCP v8.0+ automatically adds the goog-pulumi-provisioned label to all resources. Opt out with gcp:addPulumiAttributionLabel = false.

Azure — Stack Transformations

Azure Native does not have a provider-level defaultTags option. Use a stack transformation to inject tags into all taggable resources:

TypeScript:

pulumi.runtime.registerStackTransformation((args) => {
  if (args.props["tags"] !== undefined) {
    args.props["tags"] = {
      ...args.props["tags"],
      "pulumi:project": pulumi.getProject(),
      "pulumi:stack": pulumi.getStack(),
      "Environment": "dev",
    };
  }
  return { props: args.props, opts: args.opts };
});

Go:

ctx.RegisterStackTransformation(func(args *pulumi.ResourceTransformationArgs) *pulumi.ResourceTransformationResult {
    if tags, ok := args.Props["tags"]; ok {
        if tagMap, ok := tags.(pulumi.StringMap); ok {
            tagMap["pulumi:project"] = pulumi.String(ctx.Project())
            tagMap["pulumi:stack"] = pulumi.String(ctx.Stack())
            tagMap["Environment"] = pulumi.String("dev")
            args.Props["tags"] = tagMap
        }
    }
    return &pulumi.ResourceTransformationResult{Props: args.Props, Opts: args.Opts}
})

Python:

def auto_tags(args: pulumi.ResourceTransformationArgs):
    if "tags" in args.props:
        args.props["tags"] = {
            **args.props["tags"],
            "pulumi:project": pulumi.get_project(),
            "pulumi:stack": pulumi.get_stack(),
            "Environment": "dev",
        }
    return pulumi.ResourceTransformationResult(args.props, args.opts)

pulumi.runtime.register_stack_transformation(auto_tags)

FinFocus configuration for tag-based cost queries:

# ~/.finfocus/config.hujson
cost:
  allocation:
    enabled: true
    tags:
      - "pulumi:project"
      - "pulumi:stack"
      - "Environment"
      - "CostCenter"

Resource History

FinFocus maintains a resource history database (~/.finfocus/history/history.db) that tracks which cloud resource IDs existed over time. This enables accurate month-long cost queries even when resources are replaced or destroyed mid-month.

How it works: Every time FinFocus runs, it snapshots the current state of your resources. Over time, this builds a timeline of all cloud IDs each logical resource has had. When you query actual costs for a full month, FinFocus queries billing APIs for all historical IDs — not just the current one.

Important: Unlike the cache (cache.db), the history database is not safe to delete. Deleting it loses the resource identity timeline, reducing cost accuracy for past periods. Back up ~/.finfocus/history/ if you back up your infrastructure configuration.

# ~/.finfocus/config.hujson
cost:
  history:
    enabled: true          # default: true
    retention_days: 90     # how long to keep entries (default: 90)

Advanced Usage

Resource Filtering

# Filter by resource type
finfocus cost projected --pulumi-json plan.json --filter "type=aws:ec2/instance"

Output Formats

# Table format (default)
finfocus cost projected --pulumi-json plan.json --output table

# JSON for API integration
finfocus cost projected --pulumi-json plan.json --output json

# NDJSON for streaming/pipeline processing
finfocus cost projected --pulumi-json plan.json --output ndjson

Configuration Management

FinFocus provides commands to manage configuration:

# Initialize configuration (creates ~/.finfocus/config.hujson)
finfocus config init [--force]

# Set configuration values
finfocus config set cost.budgets.amount 500.00
finfocus config set output.format json

# Get configuration values
finfocus config get cost.budgets.amount

# List all configuration
finfocus config list [--as json|yaml]

# Validate configuration
finfocus config validate [--file path] [--output text|json] [--verbose]

# Inspect effective routing configuration
finfocus config routes list [--output table|json]

# Simulate plugin routing for a resource type
finfocus config routes test aws:ec2:Instance [region] [--output table|json]

Multi-Plugin Routing

FinFocus intelligently routes resources to appropriate plugins based on provider, resource patterns, and feature capabilities.

Automatic Routing (Zero Configuration)

Resources automatically route to plugins based on their supported providers:

# Install multiple plugins
finfocus plugin install aws-public
finfocus plugin install gcp-public

# View plugin capabilities
finfocus plugin list --verbose
# NAME        VERSION  PROVIDERS  CAPABILITIES                  SPEC    PATH
# aws-public  1.0.0    aws        ProjectedCosts, ActualCosts   0.5.5   ~/.finfocus/plugins/aws-public/1.0.0/...
# gcp-public  1.0.0    gcp        ProjectedCosts, ActualCosts   0.5.5   ~/.finfocus/plugins/gcp-public/1.0.0/...

# Cost calculation automatically routes resources
finfocus cost projected --pulumi-json plan.json
# AWS resources → aws-public
# GCP resources → gcp-public

Declarative Routing (Advanced Configuration)

For advanced control, configure plugin routing in ~/.finfocus/config.hujson:

routing:
  plugins:
    # Route recommendations to AWS Cost Explorer (higher accuracy)
    - name: aws-ce
      features:
        - Recommendations
      priority: 20
      fallback: true

    # Route projected costs to AWS Public (no credentials needed)
    - name: aws-public
      features:
        - ProjectedCosts
        - ActualCosts
      priority: 10
      fallback: true

    # Route EKS resources to specialized plugin (highest priority)
    - name: eks-costs
      patterns:
        - type: glob
          pattern: "aws:eks:*"
      priority: 30

Key Features:

  • Priority-Based Selection: Higher priority plugins are queried first (default: 0)
  • Automatic Fallback: If a plugin fails, automatically try the next priority
  • Pattern Matching: Use glob or regex patterns to route specific resource types
  • Feature Routing: Assign different plugins for different capabilities

Validate Routing Configuration

finfocus config validate [--file path] [--output text|json]

# Output (success):
# Configuration Validation
# Syntax valid
# Budget configuration valid
# Configuration is valid

--verbose prints loaded output, plugin, and routing settings after a valid text report.

See the Routing Configuration Guide for detailed examples and troubleshooting.

Plugin Management

List & Install Plugins

# List installed plugins
finfocus plugin list

# List with detailed capabilities
finfocus plugin list --verbose

# Install plugins
finfocus plugin install aws-public
finfocus plugin install vantage

# Inspect plugin capabilities
finfocus plugin inspect aws-public

# Validate plugin installation
finfocus plugin validate

Available Plugins

Plugin Status Description
aws-public Available AWS public pricing data
aws-ce In Development AWS Cost Explorer integration
azure-public In Development Azure public pricing data
opencost Available Kubernetes allocation cost from OpenCost or Kubecost
jev Available Opt-in recommendation scorer using TypeSafe AI's Jev model. Needs TYPESAFE_API_KEY and sends recommendation data (pseudonymized by default) to TypeSafe. See the plugin README and the scoring guide

Pulumi Analyzer Integration

FinFocus provides zero-click cost estimation during pulumi preview via the Pulumi Analyzer protocol:

# Start the analyzer server (prints port to stdout for Pulumi handshake)
finfocus analyzer serve [--debug]

When integrated with Pulumi, costs are automatically calculated and displayed as advisory diagnostics during preview, without modifying your Pulumi programs. The analyzer uses ADVISORY enforcement and never blocks deployments.

Debugging

Enable debug output for troubleshooting:

# Global debug flag
finfocus --debug cost projected --pulumi-json plan.json

# Environment variable
export FINFOCUS_LOG_LEVEL=debug
export FINFOCUS_LOG_FORMAT=json    # json or console

Agentic CLI Features

FinFocus supports agent and tooling integration through several features:

Global Flags

All commands support these global flags for programmatic integration:

  • --format json|human: Output format selection (JSON for machine consumption, human for terminal)
  • --dry-run: Preview changes without making them (affects: plugin install/update/remove, analyzer install/uninstall, config init/set, plugin upgrade, recommendation operations)
  • --yes: Skip all confirmation prompts (equivalent to approving interactive operations)
  • --idempotency-key: Opaque retry-deduplication key for distributed systems

Machine Discoverability

FinFocus can be introspected by agents and tools:

# Emit command schema in AX format (default)
finfocus __schema

# Emit command schema in MCP format
finfocus __schema --as=mcp

Use finfocus from an AI assistant (MCP)

FinFocus has a built-in Model Context Protocol (MCP) server. MCP clients such as Claude Code and Claude Desktop can call finfocus commands as tools, for example finfocus-cost-projected and finfocus-plugin-list. Tool calls return JSON.

# Serve over stdio (what MCP clients launch); the two forms are equivalent
finfocus --mcp
finfocus mcp-server

# Serve over HTTP (loopback-only by default)
finfocus mcp-server --transport=http --addr=127.0.0.1:8080

# Serve over HTTP from any address (requires explicit opt-in)
finfocus mcp-server --transport=http --addr=0.0.0.0:8080 --allow-non-loopback

Register it with Claude Code:

claude mcp add finfocus -- finfocus --mcp

Or add it to Claude Desktop's claude_desktop_config.json:

{
  "mcpServers": {
    "finfocus": { "command": "/path/to/finfocus", "args": ["--mcp"] }
  }
}

The built-in server replaces the standalone finfocus-mcp (formerly pulumicost-mcp) server. See the MCP guide for the tool list, output and safety arguments, and the mapping from the old server's tools.

Documentation

Complete documentation is available in the docs/ directory:

Quick Links:

Contributing

We welcome contributions! See our development documentation:

License

Apache-2.0 - See LICENSE for details.

Agent Skills

FinFocus ships agent skills for AI coding assistants (Claude Code, Gemini CLI, etc.) that automate common workflows:

Skill Description
finfocus-install Install CLI, detect providers, setup plugins and config
finfocus-analyzer-setup Configure Pulumi Analyzer for inline cost estimation
finfocus-routing Configure plugin routing with priority and fallback
finfocus-budget Configure budget thresholds, health, and CI exit codes
finfocus-diagnose Debug connectivity, config resolution, cache, and zero cost

See agent-skills/README.md for the full list and planned skills.

Related Projects


Getting Started: Try the examples directory for sample Pulumi plans and pricing specifications.

About

FinOps CLI for Pulumi — projected costs, actual spend tracking, budget enforcement, and cost optimization for cloud infrastructure

Topics

Resources

Contributing

Stars

10 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages