{"version":3,"term":{"cols":120,"rows":36,"type":"xterm-256color"},"timestamp":1788976485,"title":"Hooks: custom command hook contract","env":{"COLORTERM":"truecolor","SHELL":"/bin/zsh"}}
[0.006240291,"o","\u001b[1;38;2;0;163;224m\u003e \u001b[0m\u001b[?25h"]
[0.351071584,"o","\u001b[38;2;73;85;104m"]
[0.036061375,"o","#"]
[0.040297708,"o"," "]
[0.097366125,"o","i"]
[0.03269125,"o","n"]
[0.039743375,"o","s"]
[0.043814292,"o","p"]
[0.031623166,"o","e"]
[0.0347765,"o","c"]
[0.043017959,"o","t"]
[0.046830375,"o"," "]
[0.090567666,"o","t"]
[0.041567334,"o","h"]
[0.03450975,"o","e"]
[0.030429416,"o"," "]
[0.100310667,"o","h"]
[0.044566458,"o","o"]
[0.036819625,"o","o"]
[0.03343025,"o","k"]
[0.032382042,"o"," "]
[0.096322542,"o","a"]
[0.040196791,"o","t"]
[0.043365459,"o","t"]
[0.047323625,"o","a"]
[0.03240225,"o","c"]
[0.042624291,"o","h"]
[0.047259334,"o","e"]
[0.032040875,"o","d"]
[0.036123375,"o"," "]
[0.057688916,"o","t"]
[0.038223792,"o","o"]
[0.041888333,"o"," "]
[0.067435917,"o","t"]
[0.033270917,"o","h"]
[0.048957458,"o","e"]
[0.0449135,"o"," "]
[0.075481292,"o","d"]
[0.036766833,"o","e"]
[0.032719,"o","m"]
[0.0358975,"o","o"]
[0.031829167,"o"," "]
[0.050405083,"o","c"]
[0.035745208,"o","o"]
[0.041845084,"o","m"]
[0.046861833,"o","p"]
[0.034700042,"o","o"]
[0.038518291,"o","n"]
[0.044917417,"o","e"]
[0.030593333,"o","n"]
[0.037619542,"o","t"]
[0.000014792,"o","\u001b[0m"]
[0.55098125,"o","\n"]
[0.000191458,"o","\u001b[1;38;2;0;163;224m\u003e \u001b[0m\u001b[?25h"]
[0.351125625,"o","\u001b[38;2;255;255;255m"]
[0.035358958,"o","a"]
[0.038253709,"o","t"]
[0.042806125,"o","m"]
[0.028441958,"o","o"]
[0.0378135,"o","s"]
[0.041805417,"o"," "]
[0.044637166,"o","d"]
[0.031676875,"o","e"]
[0.039948584,"o","s"]
[0.043861666,"o","c"]
[0.041892334,"o","r"]
[0.039002416,"o","i"]
[0.035379792,"o","b"]
[0.03157175,"o","e"]
[0.027713083,"o"," "]
[0.086038209,"o","c"]
[0.037527,"o","o"]
[0.033786208,"o","m"]
[0.037198125,"o","p"]
[0.033579417,"o","o"]
[0.044360583,"o","n"]
[0.030546917,"o","e"]
[0.036078208,"o","n"]
[0.040566417,"o","t"]
[0.041502625,"o"," "]
[0.043471666,"o","d"]
[0.034236542,"o","e"]
[0.037936333,"o","m"]
[0.032309834,"o","o"]
[0.035546791,"o"," "]
[0.045685917,"o","-"]
[0.042249875,"o","s"]
[0.037141542,"o"," "]
[0.054000208,"o","t"]
[0.030565958,"o","e"]
[0.026718625,"o","s"]
[0.038538584,"o","t"]
[0.03450925,"o"," "]
[0.059732125,"o","-"]
[0.030202208,"o","-"]
[0.029961542,"o","f"]
[0.033683583,"o","o"]
[0.037355958,"o","r"]
[0.041055625,"o","m"]
[0.043797167,"o","a"]
[0.030920625,"o","t"]
[0.034657917,"o"," "]
[0.077108916,"o","y"]
[0.035018875,"o","a"]
[0.0404775,"o","m"]
[0.031694959,"o","l"]
[0.028083208,"o"," "]
[0.08218675,"o","-"]
[0.038576542,"o","q"]
[0.028947541,"o"," "]
[0.086255084,"o","."]
[0.043339291,"o","h"]
[0.03536125,"o","o"]
[0.036453292,"o","o"]
[0.033214625,"o","k"]
[0.032833333,"o","s"]
[0.000012334,"o","\u001b[0m"]
[0.551042791,"o","\n"]
[4.561821917,"o","\u001b[38;5;212mnotify\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m  \u001b[0m\u001b[38;5;212margs\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m    \u001b[0m\u001b[38;5;231m- \u001b[0m\u001b[38;5;231m$ATMOS_COMPONENT_PATH/../../../scripts/notify.py\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m  \u001b[0m\u001b[38;5;212mcommand\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m \u001b[0m\u001b[38;5;231mpython3\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m  \u001b[0m\u001b[38;5;212mevents\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m    \u001b[0m\u001b[38;5;231m- \u001b[0m\u001b[38;5;231mafter.terraform.plan\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m  \u001b[0m\u001b[38;5;212mformat\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m \u001b[0m\u001b[38;5;231mmarkdown\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m  \u001b[0m\u001b[38;5;212mkind\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m \u001b[0m\u001b[38;5;231mcommand\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[0.012,"o","\u001b[38;5;231m  \u001b[0m\u001b[38;5;212mon_failure\u001b[0m\u001b[38;5;231m:\u001b[0m\u001b[38;5;231m \u001b[0m\u001b[38;5;231mwarn\u001b[0m\u001b[38;5;231m\u001b[0m\n"]
[1.420372583,"o","\u001b[1;38;2;0;163;224m\u003e \u001b[0m\u001b[?25h"]
[0.35111275,"o","\u001b[38;2;73;85;104m"]
[0.044061459,"o","#"]
[0.039993666,"o"," "]
[0.061408792,"o","t"]
[0.031039792,"o","h"]
[0.047079208,"o","e"]
[0.04299825,"o"," "]
[0.072021708,"o","h"]
[0.034862834,"o","o"]
[0.030796333,"o","o"]
[0.046352958,"o","k"]
[0.046231459,"o"," "]
[0.049106416,"o","s"]
[0.038095792,"o","c"]
[0.042172917,"o","r"]
[0.043221291,"o","i"]
[0.047298625,"o","p"]
[0.034598917,"o","t"]
[0.03915175,"o"," "]
[0.054650292,"o","w"]
[0.037053458,"o","r"]
[0.043383958,"o","i"]
[0.040291625,"o","t"]
[0.036231334,"o","e"]
[0.031465875,"o","s"]
[0.047380875,"o"," "]
[0.083343416,"o","m"]
[0.039140917,"o","a"]
[0.035188125,"o","r"]
[0.038345667,"o","k"]
[0.034290208,"o","d"]
[0.042644292,"o","o"]
[0.045764125,"o","w"]
[0.031504,"o","n"]
[0.035577083,"o"," "]
[0.090622,"o","t"]
[0.0301485,"o","o"]
[0.034375,"o"," "]
[0.068605417,"o","t"]
[0.03664025,"o","h"]
[0.040686166,"o","e"]
[0.040773167,"o"," "]
[0.063933583,"o","A"]
[0.048904209,"o","t"]
[0.044839083,"o","m"]
[0.03776825,"o","o"]
[0.033693292,"o","s"]
[0.045923875,"o"," "]
[0.07892775,"o","o"]
[0.034766541,"o","u"]
[0.030717125,"o","t"]
[0.034127125,"o","p"]
[0.038192209,"o","u"]
[0.045288166,"o","t"]
[0.029289,"o"," "]
[0.065539584,"o","f"]
[0.041201,"o","i"]
[0.048272958,"o","l"]
[0.033071125,"o","e"]
[0.000016792,"o","\u001b[0m"]
[0.551043208,"o","\n"]
[0.00022,"o","\u001b[1;38;2;0;163;224m\u003e \u001b[0m\u001b[?25h"]
[0.351142375,"o","\u001b[38;2;255;255;255m"]
[0.035519875,"o","s"]
[0.031824917,"o","e"]
[0.028121083,"o","d"]
[0.041964917,"o"," "]
[0.072199875,"o","-"]
[0.034563583,"o","n"]
[0.030872958,"o"," "]
[0.092531167,"o","'"]
[0.030055292,"o","1"]
[0.043871416,"o",","]
[0.07387925,"o","9"]
[0.030414917,"o","0"]
[0.036608833,"o","p"]
[0.040541959,"o","'"]
[0.041495583,"o"," "]
[0.043928333,"o","s"]
[0.034098709,"o","c"]
[0.037616958,"o","r"]
[0.03875825,"o","i"]
[0.042183458,"o","p"]
[0.038089709,"o","t"]
[0.03449725,"o","s"]
[0.031002041,"o","/"]
[0.074926417,"o","n"]
[0.040917375,"o","o"]
[0.037225042,"o","t"]
[0.033517916,"o","i"]
[0.028868875,"o","f"]
[0.043572125,"o","y"]
[0.039967,"o","."]
[0.03661575,"o","p"]
[0.040312334,"o","y"]
[0.000014208,"o","\u001b[0m"]
[0.550247958,"o","\n"]
[0.003483042,"o","#!/usr/bin/env python3\n"]
[0.012,"o","\"\"\"\n"]
[0.012,"o","notify.py — example custom hook command.\n"]
[0.012,"o","\n"]
[0.012,"o","Atmos exports a small env-var contract to every hook subprocess:\n"]
[0.012,"o","\n"]
[0.012,"o","    ATMOS_COMPONENT_PATH  — on-disk path to the terraform module\n"]
[0.012,"o","    ATMOS_STACK           — stack name (e.g., \"prod\")\n"]
[0.012,"o","    ATMOS_COMPONENT       — component name (e.g., \"vpc\")\n"]
[0.012,"o","    ATMOS_OUTPUT_FILE     — temp file path the hook should write\n"]
[0.012,"o","                             structured output to (consumed by the\n"]
[0.012,"o","                             kind's ResultHandler if any)\n"]
[0.012,"o","    ATMOS_OUTPUT_DIR      — directory containing ATMOS_OUTPUT_FILE\n"]
[0.012,"o","\n"]
[0.012,"o","This script demonstrates the pattern by writing a markdown summary to\n"]
[0.012,"o","ATMOS_OUTPUT_FILE. With `format: markdown` declared on the hook (see\n"]
[0.012,"o","the stack manifest), Atmos renders that summary to the terminal —\n"]
[0.012,"o","nothing else required.\n"]
[0.012,"o","\n"]
[0.012,"o","The script is intentionally minimal: real-world custom commands here\n"]
[0.012,"o","might post a Slack/Teams notification, file a Jira ticket, append to a\n"]
[0.012,"o","deployment log, or trigger an internal compliance webhook.\n"]
[0.012,"o","\"\"\"\n"]
[0.012,"o","\n"]
[0.012,"o","from __future__ import annotations\n"]
[0.012,"o","\n"]
[0.012,"o","import datetime\n"]
[0.012,"o","import os\n"]
[0.012,"o","import sys\n"]
[0.012,"o","\n"]
[0.012,"o","\n"]
[0.012,"o","def env(name: str, default: str = \"(unset)\") -\u003e str:\n"]
[0.012,"o","    \"\"\"Read an Atmos env var with a visible placeholder when unset.\"\"\"\n"]
[0.012,"o","    return os.environ.get(name, default)\n"]
[0.012,"o","\n"]
[0.012,"o","\n"]
[0.012,"o","def main() -\u003e int:\n"]
[0.012,"o","    out = env(\"ATMOS_OUTPUT_FILE\")\n"]
[0.012,"o","    if not out:\n"]
[0.012,"o","        # Without an output file we have nowhere to put the markdown.\n"]
[0.012,"o","        # Atmos doesn't require us to write one; the kind: command engine\n"]
[0.012,"o","        # will just have an empty Artifact if we skip this. But for the\n"]
[0.012,"o","        # demo to render something, we need the file set.\n"]
[0.012,"o","        print(\"notify.py: ATMOS_OUTPUT_FILE not set; nothing to render\",\n"]
[0.012,"o","              file=sys.stderr)\n"]
[0.012,"o","        return 0\n"]
[0.012,"o","\n"]
[0.012,"o","    body = f\"\"\"## custom-command demo\n"]
[0.012,"o","\n"]
[0.012,"o","Hook fired for **{env(\"ATMOS_COMPONENT\")}** in **{env(\"ATMOS_STACK\")}**.\n"]
[0.012,"o","\n"]
[0.012,"o","| Field | Value |\n"]
[0.012,"o","|---|---|\n"]
[0.012,"o","| Component path | `{env(\"ATMOS_COMPONENT_PATH\")}` |\n"]
[0.012,"o","| Output file | `{env(\"ATMOS_OUTPUT_FILE\")}` |\n"]
[0.012,"o","| Output dir | `{env(\"ATMOS_OUTPUT_DIR\")}` |\n"]
[0.012,"o","| Timestamp (UTC) | `{datetime.datetime.now(datetime.timezone.utc).isoformat()}` |\n"]
[0.012,"o","\n"]
[0.012,"o","This markdown body is what Atmos rendered to your terminal via\n"]
[0.012,"o","`ui.MarkdownMessage`. The same bytes would flow to Atmos Pro (when\n"]
[0.012,"o","connected) and to PR comments — _format symmetry_ across every consumer.\n"]
[0.012,"o","\"\"\"\n"]
[0.012,"o","\n"]
[0.012,"o","    with open(out, \"w\", encoding=\"utf-8\") as fp:\n"]
[0.012,"o","        fp.write(body)\n"]
[0.012,"o","\n"]
[0.012,"o","    # Stay silent here — Atmos streams the subprocess stdout straight to\n"]
[0.012,"o","    # the terminal, so any \"wrote file\" diagnostic is noise that sits\n"]
[0.012,"o","    # awkwardly between the styled \"Running hooks\" log line and the\n"]
[0.012,"o","    # rendered markdown that follows. The markdown body IS the message.\n"]
[0.012,"o","    return 0\n"]
[0.012,"o","\n"]
[0.012,"o","\n"]
[0.012,"o","if __name__ == \"__main__\":\n"]
[0.012,"o","    raise SystemExit(main())\n"]
[0,"o","\u001b[1;38;2;0;163;224m\u003e \u001b[0m\u001b[?25h"]
