{
  "slug": "env-var-reference-extractor",
  "name": "gizza-ai/env-var-reference-extractor",
  "version": "0.1.0",
  "title": "Env Var Reference Extractor — Find Every $VAR, ${VAR} and %VAR% Used — gizza.ai",
  "description": "Paste a shell script, Dockerfile or config and list every environment variable it references, with line numbers, defaults and an undefined check. Runs in your browser.",
  "tags": [
    "environment variables",
    "env var extractor",
    "shell script",
    "dockerfile",
    "env example generator",
    "undefined variables"
  ],
  "category": "text",
  "urls": {
    "page": "https://gizza.ai/tools/env-var-reference-extractor/",
    "markdown": "https://gizza.ai/tools/env-var-reference-extractor/index.md",
    "descriptor": "https://gizza.ai/tools/env-var-reference-extractor/tool.json",
    "deep_link_example": "https://gizza.ai/tools/env-var-reference-extractor/?text=%23%21%2Fbin%2Fsh%0APORT%3D%24%7BPORT%3A-8080%7D%0Acurl%20%22%24API_URL%2Fhealth%22&syntax=auto&output=names&defined=PORT%3D8080%0AAPI_URL%3Dhttps%3A%2F%2Fapi.internal&include_defined_in_source=true&skip_comments=true&ignore=PATH%2C%20HOME%2C%20LC_%2A&only_undefined=true&sort=name"
  },
  "cli": "gizza tool env-var-reference-extractor '#!/bin/sh\nPORT=${PORT:-8080}\ncurl \"$API_URL/health\"'",
  "tool": {
    "description": "Scan a pasted shell script, Dockerfile, docker-compose/CI YAML, batch file or source file and report every environment variable it references, where each one is used, whether it carries a fallback default, and whether anything defines it. Recognises shell $VAR, ${VAR} and the parameter expansions ${VAR:-default}, ${VAR:=default}, ${VAR:?error}, ${VAR:+alt}, ${VAR#pattern}, ${#VAR} and ${!VAR}; Windows %VAR% and delayed-expansion !VAR!; and library accessors such as process.env.VAR, import.meta.env.VAR, os.environ[\"VAR\"], os.getenv(\"VAR\"), System.getenv(\"VAR\"), env::var(\"VAR\") and getenv(\"VAR\"). Escaped \\$ and $$ are skipped, and positional or special parameters ($1, $@, $?, $$) are never reported as variables. Definitions are picked up from shell assignments, Dockerfile ENV/ARG and Windows set/setx, and you can paste a .env body or name list to mark the rest as defined. Options: syntax (auto/shell/dockerfile/windows/code/all), output (names, table, json, markdown, csv, env-template that generates a .env.example, or stats), defined, include_defined_in_source, skip_comments, ignore with prefix wildcards, only_undefined, sort. This is a deterministic scanner, not a shell parser: single-quoted strings and here-doc bodies are still scanned even though a real shell would not expand them, bare names inside $(( )) arithmetic are not references, and a run is capped at 20,000 references.",
    "parameters": {
      "additionalProperties": false,
      "properties": {
        "defined": {
          "default": "",
          "description": "Optional list of variables you already provide, used to mark each reference defined or undefined. Accepts a .env body ('DB_HOST=db\\nAPI_KEY=secret'), export lines, or bare names separated by newlines, commas or spaces. Values are ignored — only the names matter. Default empty, in which case only definitions found inside the pasted text count.",
          "type": "string"
        },
        "ignore": {
          "default": "",
          "description": "Variable names to leave out of the report, separated by commas, spaces or newlines. A trailing '*' matches a prefix. Matching is case-sensitive. Example: 'PATH, HOME, LC_*' drops PATH, HOME and every LC_ locale variable. Default empty (report everything).",
          "type": "string"
        },
        "include_defined_in_source": {
          "default": true,
          "description": "Count assignments inside the pasted text as definitions, so a variable the script sets itself is reported as 'defined'. Recognises shell 'NAME=value' (with export/declare/readonly/local), Dockerfile ENV and ARG, and Windows set/setx. Default true; set false to treat every reference as external and list everything the input consumes.",
          "type": "boolean"
        },
        "only_undefined": {
          "default": false,
          "description": "Report only the variables nothing defines — neither the pasted text nor the 'defined' list. Default false. Turn this on to get the exact set of values a script still needs before it can run; the stats output always reports both totals.",
          "type": "boolean"
        },
        "output": {
          "default": "names",
          "description": "What to return. 'names' (default) = one variable name per line. 'table' = an aligned VARIABLE/USES/LINES/DEFAULT/STATUS table. 'json' = an array of {name, count, lines, forms, default, defined, defined_in, defined_at_line}. 'markdown' = the same columns as a Markdown table. 'csv' = a name,uses,lines,default,status sheet. 'env-template' = a ready-to-edit .env.example with a usage comment above each key. 'stats' = a summary of the detected syntax and reference counts.",
          "enum": [
            "names",
            "table",
            "json",
            "markdown",
            "csv",
            "env-template",
            "stats"
          ],
          "type": "string"
        },
        "skip_comments": {
          "default": true,
          "description": "Ignore references inside comments — a '#' at the start of a line or after whitespace, '//' line comments in code, and REM/:: lines in batch files. Default true. The '#' in an expansion such as ${PREFIX#/opt} is never treated as a comment. Set false to include commented-out references.",
          "type": "boolean"
        },
        "sort": {
          "default": "name",
          "description": "Row order. 'name' (default) = alphabetical. 'occurrences' = most-referenced first, ties broken alphabetically. 'first-seen' = the order the variables first appear in the input, which keeps a script's reading order.",
          "enum": [
            "name",
            "occurrences",
            "first-seen"
          ],
          "type": "string"
        },
        "syntax": {
          "default": "auto",
          "description": "Which reference family to look for. 'auto' (default) guesses from the input's shape. 'shell' = $VAR, ${VAR}, ${VAR:-default} and the other parameter expansions. 'dockerfile' = the same plus ENV/ARG lines counted as definitions. 'windows' = %VAR% and delayed-expansion !VAR!, plus set/setx definitions. 'code' = library accessors such as process.env.VAR, import.meta.env.VAR, os.environ[\"VAR\"], os.getenv(\"VAR\"), System.getenv(\"VAR\"), env::var(\"VAR\"), getenv(\"VAR\"). 'all' scans every family at once — useful for mixed inputs, at the cost of false positives such as a printf '%d%' being read as a Windows reference.",
          "enum": [
            "auto",
            "shell",
            "dockerfile",
            "windows",
            "code",
            "all"
          ],
          "type": "string"
        },
        "text": {
          "description": "The shell script, Dockerfile, docker-compose/CI YAML, batch file or source file to scan, pasted as text. Example: 'PORT=${PORT:-8080}\\ncurl \"$API_URL/health\"'.",
          "type": "string"
        }
      },
      "required": [
        "text"
      ],
      "type": "object"
    }
  }
}