[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-novu-human-cli":3,"mdc-tnj4kt-key":51,"related-org-novu-human-cli":1125,"related-repo-novu-human-cli":1241},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":46,"sourceUrl":49,"mdContent":50},"human-cli","request human approval via CLI","Reach the actual human you're working for via the `human` CLI (ask\u002Fapprove\u002Fchoose\u002Ftell) when you need a decision, approval, or notification and no one is watching this terminal right now. Use for background\u002Fautonomous\u002Fscheduled runs, risky or irreversible actions, and genuine multi-way ambiguity — not for routine questions the current chat user can just answer next turn.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"novu","Novu","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fnovu.png","novuhq",[13,17,20,23],{"name":14,"slug":15,"type":16},"Productivity","productivity","tag",{"name":18,"slug":19,"type":16},"Automation","automation",{"name":21,"slug":22,"type":16},"CLI","cli",{"name":24,"slug":25,"type":16},"Approvals","approvals",39301,"https:\u002F\u002Fgithub.com\u002Fnovuhq\u002Fnovu","2026-08-24T03:57:02.354272",null,4357,[32,33,34,35,36,37,38,39,8,40,41,42,43,44,45],"agents","communication","email","inbox","infrastructure","nodejs","notification-center","notifications","push-notifications","react","reactjs","sms","transactional","typescript",{"repoUrl":27,"stars":26,"forks":30,"topics":47,"description":48},[32,33,34,35,36,37,38,39,8,40,41,42,43,44,45],"The open-source communication infrastructure for agents and products","https:\u002F\u002Fgithub.com\u002Fnovuhq\u002Fnovu\u002Ftree\u002FHEAD\u002Fpackages\u002Fhuman\u002Fsrc\u002Fskills\u002Fcontent\u002Fhuman-cli","---\nname: human-cli\ndescription: Reach the actual human you're working for via the `human` CLI (ask\u002Fapprove\u002Fchoose\u002Ftell) when you need a decision, approval, or notification and no one is watching this terminal right now. Use for background\u002Fautonomous\u002Fscheduled runs, risky or irreversible actions, and genuine multi-way ambiguity — not for routine questions the current chat user can just answer next turn.\ntriggers:\n  - human ask\n  - human approve\n  - human cli\n  - ask the human\n  - need approval before deploying\n  - notify when done\n  - no one is watching this session\n---\n\n# The `human` CLI — reaching your human when you need one\n\n`human` (package `@novu\u002Fhuman`) is a small CLI whose only job is getting a\nreal decision from a real person: `ask` a question, `approve` an action,\n`choose` between options, or `tell` them something — over Telegram, Slack, or\nemail, wherever they set it up to reach them. Each blocking command waits\nuntil they respond (or it times out) and then your process continues.\n\n## When to reach for this vs. just asking in chat\n\nIf the person you're working for is actively watching this conversation and\ncan answer your next message, **just ask them normally** — don't shell out to\n`human` for routine back-and-forth. Reach for `human` when:\n\n- **You're running unattended** — a background task, a scheduled\u002Fcron job, an\n  autonomous loop, a CI step, or any context where there's no live chat to\n  post a question into and get an answer back.\n- **The action is risky or irreversible** — deleting data, deploying to\n  production, spending money, sending something externally-visible. Even in\n  an interactive session, get an explicit `human approve` before doing these,\n  so there's a real audit trail of who approved what and when.\n- **There's a genuine multi-way decision** and guessing wrong is expensive —\n  use `choose` instead of picking silently or asking a rhetorical question\n  nobody will answer.\n- **You finished something long-running and want to tell someone**, without\n  blocking on a reply — use `tell`.\n\nDon't use it as a crutch to avoid making reasonable calls you're equipped to\nmake yourself, and don't use it to relay simple status updates the calling\nprocess\u002Flogs already surface.\n\n## Before you rely on it: check it's set up\n\n`human` needs one-time setup by the actual human (`npx @novu\u002Fhuman setup`).\nIf it isn't configured on this machine yet, every command exits 1 with:\n\n```\nNo human connected yet. Ask your human to run: npx @novu\u002Fhuman setup\n```\n\nTreat that message as the actual next step: surface it to whoever *is*\nreachable (chat, PR description, logs) rather than silently giving up or\nlooping. Never attempt to configure it on the human's behalf — you don't have\ntheir Telegram\u002FSlack\u002Femail credentials, and setup is interactive by design.\n\n## The four commands\n\n```bash\nhuman ask \"Which environment should I target: staging or prod?\"\nhuman approve \"Delete 342 rows flagged as stale from the orders table?\"\nhuman choose \"Pick a rollout strategy\" --option canary --option \"blue-green\" --option \"all at once\"\nhuman tell \"Nightly build finished — 0 failures, deployed to staging.\"\n```\n\n- `ask` \u002F `choose` return the human's answer as plain text on stdout.\n- `approve` \u002F `choose` deliver buttons; the human taps one.\n- `choose` renders each option's full text in the message and labels the\n  buttons themselves just A\u002FB\u002FC (chat button UIs, Telegram especially,\n  truncate or wrap long button labels badly). Write full, descriptive\n  `--option` values — don't shorten them to fit a button, that's handled for\n  you. Cap it at 10 options (A–J); past that, ask a plain question instead.\n- `tell` is one-way — it returns as soon as it's delivered, never blocks.\n\n## Exit codes — branch on these, don't parse prose\n\n| Code | Meaning |\n|---|---|\n| `0` | answered \u002F approved \u002F chosen \u002F delivered |\n| `10` | denied |\n| `11` | timed out waiting — still pending, resumable |\n| `12` | expired or canceled |\n| `1` | error (not set up, bad input, network) |\n\n```bash\nif human approve \"Deploy to production?\"; then\n  echo \"approved, proceeding\"\nelse\n  code=$?\n  if [ \"$code\" -eq 10 ]; then echo \"denied, stopping\"; exit 1; fi\n  if [ \"$code\" -eq 11 ]; then echo \"no answer yet, will resume: human wait \u003Cid>\"; fi\nfi\n```\n\nAdd `--json` to any command to get the full interaction object (id, status,\nresponse, timestamps) instead of prose — parse that when you need structured\ndata rather than scraping stdout text.\n\n## Waiting behavior\n\nCommands block by default and print a live spinner (on stderr, so stdout stays\nclean for scripts) until the human answers. Two flags change that:\n\n- `--timeout 10m` — give up waiting after this long. On timeout the command\n  prints the interaction id and exits `11`; resume later with\n  `human wait \u003Cid>`.\n- `--async` — don't block at all; print the id immediately and check back\n  with `human wait \u003Cid>` or `human list`.\n\nUse `--timeout` for anything inside a larger workflow that shouldn't hang\nforever waiting on a human who might be asleep; use `--async` when you have\nother useful work to do while you wait.\n\n## Useful flags\n\n- `--from \"deploy-bot\"` — label shown to the human so they know which agent\n  is asking. Set this whenever you have a stable identity (skip it for\n  one-off ad hoc runs).\n- `--to \u003ChumanId>` \u002F `--via \u003Ctelegram|slack|email>` — only needed for\n  multi-human or multi-channel setups; the default human and channel from\n  `human setup` are almost always right. Don't guess a channel — if you\n  need a specific one, pass `--via`; the API errors if that channel is not\n  linked yet (`human setup \u003Cchannel>`).\n- `--ttl 2h` — how long the request stays answerable before it expires\n  (default 24h, max 72h). Shorten this for anything time-sensitive so a\n  stale approval can't be actioned days later.\n\n## Checking in without asking something new\n\n- `human list` — see pending\u002Frecent interactions (useful before creating a\n  duplicate ask).\n- `human wait \u003Cid>` — resume blocking on something you created with\n  `--async` or that previously timed out.\n- `human cancel \u003Cid>` — withdraw a pending request you no longer need\n  answered (e.g. you found another way forward).\n",{"data":52,"body":61},{"name":4,"description":6,"triggers":53},[54,55,56,57,58,59,60],"human ask","human approve","human cli","ask the human","need approval before deploying","notify when done","no one is watching this session",{"type":62,"children":63},"root",[64,82,133,140,167,233,238,244,262,274,287,293,458,522,528,641,902,915,921,926,979,999,1005,1072,1078,1119],{"type":65,"tag":66,"props":67,"children":69},"element","h1",{"id":68},"the-human-cli-reaching-your-human-when-you-need-one",[70,73,80],{"type":71,"value":72},"text","The ",{"type":65,"tag":74,"props":75,"children":77},"code",{"className":76},[],[78],{"type":71,"value":79},"human",{"type":71,"value":81}," CLI — reaching your human when you need one",{"type":65,"tag":83,"props":84,"children":85},"p",{},[86,91,93,99,101,107,109,115,117,123,125,131],{"type":65,"tag":74,"props":87,"children":89},{"className":88},[],[90],{"type":71,"value":79},{"type":71,"value":92}," (package ",{"type":65,"tag":74,"props":94,"children":96},{"className":95},[],[97],{"type":71,"value":98},"@novu\u002Fhuman",{"type":71,"value":100},") is a small CLI whose only job is getting a\nreal decision from a real person: ",{"type":65,"tag":74,"props":102,"children":104},{"className":103},[],[105],{"type":71,"value":106},"ask",{"type":71,"value":108}," a question, ",{"type":65,"tag":74,"props":110,"children":112},{"className":111},[],[113],{"type":71,"value":114},"approve",{"type":71,"value":116}," an action,\n",{"type":65,"tag":74,"props":118,"children":120},{"className":119},[],[121],{"type":71,"value":122},"choose",{"type":71,"value":124}," between options, or ",{"type":65,"tag":74,"props":126,"children":128},{"className":127},[],[129],{"type":71,"value":130},"tell",{"type":71,"value":132}," them something — over Telegram, Slack, or\nemail, wherever they set it up to reach them. Each blocking command waits\nuntil they respond (or it times out) and then your process continues.",{"type":65,"tag":134,"props":135,"children":137},"h2",{"id":136},"when-to-reach-for-this-vs-just-asking-in-chat",[138],{"type":71,"value":139},"When to reach for this vs. just asking in chat",{"type":65,"tag":83,"props":141,"children":142},{},[143,145,151,153,158,160,165],{"type":71,"value":144},"If the person you're working for is actively watching this conversation and\ncan answer your next message, ",{"type":65,"tag":146,"props":147,"children":148},"strong",{},[149],{"type":71,"value":150},"just ask them normally",{"type":71,"value":152}," — don't shell out to\n",{"type":65,"tag":74,"props":154,"children":156},{"className":155},[],[157],{"type":71,"value":79},{"type":71,"value":159}," for routine back-and-forth. Reach for ",{"type":65,"tag":74,"props":161,"children":163},{"className":162},[],[164],{"type":71,"value":79},{"type":71,"value":166}," when:",{"type":65,"tag":168,"props":169,"children":170},"ul",{},[171,182,199,216],{"type":65,"tag":172,"props":173,"children":174},"li",{},[175,180],{"type":65,"tag":146,"props":176,"children":177},{},[178],{"type":71,"value":179},"You're running unattended",{"type":71,"value":181}," — a background task, a scheduled\u002Fcron job, an\nautonomous loop, a CI step, or any context where there's no live chat to\npost a question into and get an answer back.",{"type":65,"tag":172,"props":183,"children":184},{},[185,190,192,197],{"type":65,"tag":146,"props":186,"children":187},{},[188],{"type":71,"value":189},"The action is risky or irreversible",{"type":71,"value":191}," — deleting data, deploying to\nproduction, spending money, sending something externally-visible. Even in\nan interactive session, get an explicit ",{"type":65,"tag":74,"props":193,"children":195},{"className":194},[],[196],{"type":71,"value":55},{"type":71,"value":198}," before doing these,\nso there's a real audit trail of who approved what and when.",{"type":65,"tag":172,"props":200,"children":201},{},[202,207,209,214],{"type":65,"tag":146,"props":203,"children":204},{},[205],{"type":71,"value":206},"There's a genuine multi-way decision",{"type":71,"value":208}," and guessing wrong is expensive —\nuse ",{"type":65,"tag":74,"props":210,"children":212},{"className":211},[],[213],{"type":71,"value":122},{"type":71,"value":215}," instead of picking silently or asking a rhetorical question\nnobody will answer.",{"type":65,"tag":172,"props":217,"children":218},{},[219,224,226,231],{"type":65,"tag":146,"props":220,"children":221},{},[222],{"type":71,"value":223},"You finished something long-running and want to tell someone",{"type":71,"value":225},", without\nblocking on a reply — use ",{"type":65,"tag":74,"props":227,"children":229},{"className":228},[],[230],{"type":71,"value":130},{"type":71,"value":232},".",{"type":65,"tag":83,"props":234,"children":235},{},[236],{"type":71,"value":237},"Don't use it as a crutch to avoid making reasonable calls you're equipped to\nmake yourself, and don't use it to relay simple status updates the calling\nprocess\u002Flogs already surface.",{"type":65,"tag":134,"props":239,"children":241},{"id":240},"before-you-rely-on-it-check-its-set-up",[242],{"type":71,"value":243},"Before you rely on it: check it's set up",{"type":65,"tag":83,"props":245,"children":246},{},[247,252,254,260],{"type":65,"tag":74,"props":248,"children":250},{"className":249},[],[251],{"type":71,"value":79},{"type":71,"value":253}," needs one-time setup by the actual human (",{"type":65,"tag":74,"props":255,"children":257},{"className":256},[],[258],{"type":71,"value":259},"npx @novu\u002Fhuman setup",{"type":71,"value":261},").\nIf it isn't configured on this machine yet, every command exits 1 with:",{"type":65,"tag":263,"props":264,"children":268},"pre",{"className":265,"code":267,"language":71},[266],"language-text","No human connected yet. Ask your human to run: npx @novu\u002Fhuman setup\n",[269],{"type":65,"tag":74,"props":270,"children":272},{"__ignoreMap":271},"",[273],{"type":71,"value":267},{"type":65,"tag":83,"props":275,"children":276},{},[277,279,285],{"type":71,"value":278},"Treat that message as the actual next step: surface it to whoever ",{"type":65,"tag":280,"props":281,"children":282},"em",{},[283],{"type":71,"value":284},"is",{"type":71,"value":286},"\nreachable (chat, PR description, logs) rather than silently giving up or\nlooping. Never attempt to configure it on the human's behalf — you don't have\ntheir Telegram\u002FSlack\u002Femail credentials, and setup is interactive by design.",{"type":65,"tag":134,"props":288,"children":290},{"id":289},"the-four-commands",[291],{"type":71,"value":292},"The four commands",{"type":65,"tag":263,"props":294,"children":298},{"className":295,"code":296,"language":297,"meta":271,"style":271},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","human ask \"Which environment should I target: staging or prod?\"\nhuman approve \"Delete 342 rows flagged as stale from the orders table?\"\nhuman choose \"Pick a rollout strategy\" --option canary --option \"blue-green\" --option \"all at once\"\nhuman tell \"Nightly build finished — 0 failures, deployed to staging.\"\n","bash",[299],{"type":65,"tag":74,"props":300,"children":301},{"__ignoreMap":271},[302,335,361,432],{"type":65,"tag":303,"props":304,"children":307},"span",{"class":305,"line":306},"line",1,[308,313,319,325,330],{"type":65,"tag":303,"props":309,"children":311},{"style":310},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[312],{"type":71,"value":79},{"type":65,"tag":303,"props":314,"children":316},{"style":315},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[317],{"type":71,"value":318}," ask",{"type":65,"tag":303,"props":320,"children":322},{"style":321},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[323],{"type":71,"value":324}," \"",{"type":65,"tag":303,"props":326,"children":327},{"style":315},[328],{"type":71,"value":329},"Which environment should I target: staging or prod?",{"type":65,"tag":303,"props":331,"children":332},{"style":321},[333],{"type":71,"value":334},"\"\n",{"type":65,"tag":303,"props":336,"children":338},{"class":305,"line":337},2,[339,343,348,352,357],{"type":65,"tag":303,"props":340,"children":341},{"style":310},[342],{"type":71,"value":79},{"type":65,"tag":303,"props":344,"children":345},{"style":315},[346],{"type":71,"value":347}," approve",{"type":65,"tag":303,"props":349,"children":350},{"style":321},[351],{"type":71,"value":324},{"type":65,"tag":303,"props":353,"children":354},{"style":315},[355],{"type":71,"value":356},"Delete 342 rows flagged as stale from the orders table?",{"type":65,"tag":303,"props":358,"children":359},{"style":321},[360],{"type":71,"value":334},{"type":65,"tag":303,"props":362,"children":364},{"class":305,"line":363},3,[365,369,374,378,383,388,393,398,402,406,411,415,419,423,428],{"type":65,"tag":303,"props":366,"children":367},{"style":310},[368],{"type":71,"value":79},{"type":65,"tag":303,"props":370,"children":371},{"style":315},[372],{"type":71,"value":373}," choose",{"type":65,"tag":303,"props":375,"children":376},{"style":321},[377],{"type":71,"value":324},{"type":65,"tag":303,"props":379,"children":380},{"style":315},[381],{"type":71,"value":382},"Pick a rollout strategy",{"type":65,"tag":303,"props":384,"children":385},{"style":321},[386],{"type":71,"value":387},"\"",{"type":65,"tag":303,"props":389,"children":390},{"style":315},[391],{"type":71,"value":392}," --option",{"type":65,"tag":303,"props":394,"children":395},{"style":315},[396],{"type":71,"value":397}," canary",{"type":65,"tag":303,"props":399,"children":400},{"style":315},[401],{"type":71,"value":392},{"type":65,"tag":303,"props":403,"children":404},{"style":321},[405],{"type":71,"value":324},{"type":65,"tag":303,"props":407,"children":408},{"style":315},[409],{"type":71,"value":410},"blue-green",{"type":65,"tag":303,"props":412,"children":413},{"style":321},[414],{"type":71,"value":387},{"type":65,"tag":303,"props":416,"children":417},{"style":315},[418],{"type":71,"value":392},{"type":65,"tag":303,"props":420,"children":421},{"style":321},[422],{"type":71,"value":324},{"type":65,"tag":303,"props":424,"children":425},{"style":315},[426],{"type":71,"value":427},"all at once",{"type":65,"tag":303,"props":429,"children":430},{"style":321},[431],{"type":71,"value":334},{"type":65,"tag":303,"props":433,"children":435},{"class":305,"line":434},4,[436,440,445,449,454],{"type":65,"tag":303,"props":437,"children":438},{"style":310},[439],{"type":71,"value":79},{"type":65,"tag":303,"props":441,"children":442},{"style":315},[443],{"type":71,"value":444}," tell",{"type":65,"tag":303,"props":446,"children":447},{"style":321},[448],{"type":71,"value":324},{"type":65,"tag":303,"props":450,"children":451},{"style":315},[452],{"type":71,"value":453},"Nightly build finished — 0 failures, deployed to staging.",{"type":65,"tag":303,"props":455,"children":456},{"style":321},[457],{"type":71,"value":334},{"type":65,"tag":168,"props":459,"children":460},{},[461,478,494,512],{"type":65,"tag":172,"props":462,"children":463},{},[464,469,471,476],{"type":65,"tag":74,"props":465,"children":467},{"className":466},[],[468],{"type":71,"value":106},{"type":71,"value":470}," \u002F ",{"type":65,"tag":74,"props":472,"children":474},{"className":473},[],[475],{"type":71,"value":122},{"type":71,"value":477}," return the human's answer as plain text on stdout.",{"type":65,"tag":172,"props":479,"children":480},{},[481,486,487,492],{"type":65,"tag":74,"props":482,"children":484},{"className":483},[],[485],{"type":71,"value":114},{"type":71,"value":470},{"type":65,"tag":74,"props":488,"children":490},{"className":489},[],[491],{"type":71,"value":122},{"type":71,"value":493}," deliver buttons; the human taps one.",{"type":65,"tag":172,"props":495,"children":496},{},[497,502,504,510],{"type":65,"tag":74,"props":498,"children":500},{"className":499},[],[501],{"type":71,"value":122},{"type":71,"value":503}," renders each option's full text in the message and labels the\nbuttons themselves just A\u002FB\u002FC (chat button UIs, Telegram especially,\ntruncate or wrap long button labels badly). Write full, descriptive\n",{"type":65,"tag":74,"props":505,"children":507},{"className":506},[],[508],{"type":71,"value":509},"--option",{"type":71,"value":511}," values — don't shorten them to fit a button, that's handled for\nyou. Cap it at 10 options (A–J); past that, ask a plain question instead.",{"type":65,"tag":172,"props":513,"children":514},{},[515,520],{"type":65,"tag":74,"props":516,"children":518},{"className":517},[],[519],{"type":71,"value":130},{"type":71,"value":521}," is one-way — it returns as soon as it's delivered, never blocks.",{"type":65,"tag":134,"props":523,"children":525},{"id":524},"exit-codes-branch-on-these-dont-parse-prose",[526],{"type":71,"value":527},"Exit codes — branch on these, don't parse prose",{"type":65,"tag":529,"props":530,"children":531},"table",{},[532,551],{"type":65,"tag":533,"props":534,"children":535},"thead",{},[536],{"type":65,"tag":537,"props":538,"children":539},"tr",{},[540,546],{"type":65,"tag":541,"props":542,"children":543},"th",{},[544],{"type":71,"value":545},"Code",{"type":65,"tag":541,"props":547,"children":548},{},[549],{"type":71,"value":550},"Meaning",{"type":65,"tag":552,"props":553,"children":554},"tbody",{},[555,573,590,607,624],{"type":65,"tag":537,"props":556,"children":557},{},[558,568],{"type":65,"tag":559,"props":560,"children":561},"td",{},[562],{"type":65,"tag":74,"props":563,"children":565},{"className":564},[],[566],{"type":71,"value":567},"0",{"type":65,"tag":559,"props":569,"children":570},{},[571],{"type":71,"value":572},"answered \u002F approved \u002F chosen \u002F delivered",{"type":65,"tag":537,"props":574,"children":575},{},[576,585],{"type":65,"tag":559,"props":577,"children":578},{},[579],{"type":65,"tag":74,"props":580,"children":582},{"className":581},[],[583],{"type":71,"value":584},"10",{"type":65,"tag":559,"props":586,"children":587},{},[588],{"type":71,"value":589},"denied",{"type":65,"tag":537,"props":591,"children":592},{},[593,602],{"type":65,"tag":559,"props":594,"children":595},{},[596],{"type":65,"tag":74,"props":597,"children":599},{"className":598},[],[600],{"type":71,"value":601},"11",{"type":65,"tag":559,"props":603,"children":604},{},[605],{"type":71,"value":606},"timed out waiting — still pending, resumable",{"type":65,"tag":537,"props":608,"children":609},{},[610,619],{"type":65,"tag":559,"props":611,"children":612},{},[613],{"type":65,"tag":74,"props":614,"children":616},{"className":615},[],[617],{"type":71,"value":618},"12",{"type":65,"tag":559,"props":620,"children":621},{},[622],{"type":71,"value":623},"expired or canceled",{"type":65,"tag":537,"props":625,"children":626},{},[627,636],{"type":65,"tag":559,"props":628,"children":629},{},[630],{"type":65,"tag":74,"props":631,"children":633},{"className":632},[],[634],{"type":71,"value":635},"1",{"type":65,"tag":559,"props":637,"children":638},{},[639],{"type":71,"value":640},"error (not set up, bad input, network)",{"type":65,"tag":263,"props":642,"children":644},{"className":295,"code":643,"language":297,"meta":271,"style":271},"if human approve \"Deploy to production?\"; then\n  echo \"approved, proceeding\"\nelse\n  code=$?\n  if [ \"$code\" -eq 10 ]; then echo \"denied, stopping\"; exit 1; fi\n  if [ \"$code\" -eq 11 ]; then echo \"no answer yet, will resume: human wait \u003Cid>\"; fi\nfi\n",[645],{"type":65,"tag":74,"props":646,"children":647},{"__ignoreMap":271},[648,689,711,719,738,827,893],{"type":65,"tag":303,"props":649,"children":650},{"class":305,"line":306},[651,657,662,666,670,675,679,684],{"type":65,"tag":303,"props":652,"children":654},{"style":653},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[655],{"type":71,"value":656},"if",{"type":65,"tag":303,"props":658,"children":659},{"style":310},[660],{"type":71,"value":661}," human",{"type":65,"tag":303,"props":663,"children":664},{"style":315},[665],{"type":71,"value":347},{"type":65,"tag":303,"props":667,"children":668},{"style":321},[669],{"type":71,"value":324},{"type":65,"tag":303,"props":671,"children":672},{"style":315},[673],{"type":71,"value":674},"Deploy to production?",{"type":65,"tag":303,"props":676,"children":677},{"style":321},[678],{"type":71,"value":387},{"type":65,"tag":303,"props":680,"children":681},{"style":321},[682],{"type":71,"value":683},";",{"type":65,"tag":303,"props":685,"children":686},{"style":653},[687],{"type":71,"value":688}," then\n",{"type":65,"tag":303,"props":690,"children":691},{"class":305,"line":337},[692,698,702,707],{"type":65,"tag":303,"props":693,"children":695},{"style":694},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[696],{"type":71,"value":697},"  echo",{"type":65,"tag":303,"props":699,"children":700},{"style":321},[701],{"type":71,"value":324},{"type":65,"tag":303,"props":703,"children":704},{"style":315},[705],{"type":71,"value":706},"approved, proceeding",{"type":65,"tag":303,"props":708,"children":709},{"style":321},[710],{"type":71,"value":334},{"type":65,"tag":303,"props":712,"children":713},{"class":305,"line":363},[714],{"type":65,"tag":303,"props":715,"children":716},{"style":653},[717],{"type":71,"value":718},"else\n",{"type":65,"tag":303,"props":720,"children":721},{"class":305,"line":434},[722,728,733],{"type":65,"tag":303,"props":723,"children":725},{"style":724},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[726],{"type":71,"value":727},"  code",{"type":65,"tag":303,"props":729,"children":730},{"style":321},[731],{"type":71,"value":732},"=",{"type":65,"tag":303,"props":734,"children":735},{"style":724},[736],{"type":71,"value":737},"$?\n",{"type":65,"tag":303,"props":739,"children":741},{"class":305,"line":740},5,[742,747,752,756,761,765,770,776,781,786,791,795,800,804,808,813,818,822],{"type":65,"tag":303,"props":743,"children":744},{"style":653},[745],{"type":71,"value":746},"  if",{"type":65,"tag":303,"props":748,"children":749},{"style":321},[750],{"type":71,"value":751}," [",{"type":65,"tag":303,"props":753,"children":754},{"style":321},[755],{"type":71,"value":324},{"type":65,"tag":303,"props":757,"children":758},{"style":724},[759],{"type":71,"value":760},"$code",{"type":65,"tag":303,"props":762,"children":763},{"style":321},[764],{"type":71,"value":387},{"type":65,"tag":303,"props":766,"children":767},{"style":321},[768],{"type":71,"value":769}," -eq",{"type":65,"tag":303,"props":771,"children":773},{"style":772},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[774],{"type":71,"value":775}," 10",{"type":65,"tag":303,"props":777,"children":778},{"style":321},[779],{"type":71,"value":780}," ];",{"type":65,"tag":303,"props":782,"children":783},{"style":653},[784],{"type":71,"value":785}," then",{"type":65,"tag":303,"props":787,"children":788},{"style":694},[789],{"type":71,"value":790}," echo",{"type":65,"tag":303,"props":792,"children":793},{"style":321},[794],{"type":71,"value":324},{"type":65,"tag":303,"props":796,"children":797},{"style":315},[798],{"type":71,"value":799},"denied, stopping",{"type":65,"tag":303,"props":801,"children":802},{"style":321},[803],{"type":71,"value":387},{"type":65,"tag":303,"props":805,"children":806},{"style":321},[807],{"type":71,"value":683},{"type":65,"tag":303,"props":809,"children":810},{"style":694},[811],{"type":71,"value":812}," exit",{"type":65,"tag":303,"props":814,"children":815},{"style":772},[816],{"type":71,"value":817}," 1",{"type":65,"tag":303,"props":819,"children":820},{"style":321},[821],{"type":71,"value":683},{"type":65,"tag":303,"props":823,"children":824},{"style":653},[825],{"type":71,"value":826}," fi\n",{"type":65,"tag":303,"props":828,"children":830},{"class":305,"line":829},6,[831,835,839,843,847,851,855,860,864,868,872,876,881,885,889],{"type":65,"tag":303,"props":832,"children":833},{"style":653},[834],{"type":71,"value":746},{"type":65,"tag":303,"props":836,"children":837},{"style":321},[838],{"type":71,"value":751},{"type":65,"tag":303,"props":840,"children":841},{"style":321},[842],{"type":71,"value":324},{"type":65,"tag":303,"props":844,"children":845},{"style":724},[846],{"type":71,"value":760},{"type":65,"tag":303,"props":848,"children":849},{"style":321},[850],{"type":71,"value":387},{"type":65,"tag":303,"props":852,"children":853},{"style":321},[854],{"type":71,"value":769},{"type":65,"tag":303,"props":856,"children":857},{"style":772},[858],{"type":71,"value":859}," 11",{"type":65,"tag":303,"props":861,"children":862},{"style":321},[863],{"type":71,"value":780},{"type":65,"tag":303,"props":865,"children":866},{"style":653},[867],{"type":71,"value":785},{"type":65,"tag":303,"props":869,"children":870},{"style":694},[871],{"type":71,"value":790},{"type":65,"tag":303,"props":873,"children":874},{"style":321},[875],{"type":71,"value":324},{"type":65,"tag":303,"props":877,"children":878},{"style":315},[879],{"type":71,"value":880},"no answer yet, will resume: human wait \u003Cid>",{"type":65,"tag":303,"props":882,"children":883},{"style":321},[884],{"type":71,"value":387},{"type":65,"tag":303,"props":886,"children":887},{"style":321},[888],{"type":71,"value":683},{"type":65,"tag":303,"props":890,"children":891},{"style":653},[892],{"type":71,"value":826},{"type":65,"tag":303,"props":894,"children":896},{"class":305,"line":895},7,[897],{"type":65,"tag":303,"props":898,"children":899},{"style":653},[900],{"type":71,"value":901},"fi\n",{"type":65,"tag":83,"props":903,"children":904},{},[905,907,913],{"type":71,"value":906},"Add ",{"type":65,"tag":74,"props":908,"children":910},{"className":909},[],[911],{"type":71,"value":912},"--json",{"type":71,"value":914}," to any command to get the full interaction object (id, status,\nresponse, timestamps) instead of prose — parse that when you need structured\ndata rather than scraping stdout text.",{"type":65,"tag":134,"props":916,"children":918},{"id":917},"waiting-behavior",[919],{"type":71,"value":920},"Waiting behavior",{"type":65,"tag":83,"props":922,"children":923},{},[924],{"type":71,"value":925},"Commands block by default and print a live spinner (on stderr, so stdout stays\nclean for scripts) until the human answers. Two flags change that:",{"type":65,"tag":168,"props":927,"children":928},{},[929,954],{"type":65,"tag":172,"props":930,"children":931},{},[932,938,940,945,947,953],{"type":65,"tag":74,"props":933,"children":935},{"className":934},[],[936],{"type":71,"value":937},"--timeout 10m",{"type":71,"value":939}," — give up waiting after this long. On timeout the command\nprints the interaction id and exits ",{"type":65,"tag":74,"props":941,"children":943},{"className":942},[],[944],{"type":71,"value":601},{"type":71,"value":946},"; resume later with\n",{"type":65,"tag":74,"props":948,"children":950},{"className":949},[],[951],{"type":71,"value":952},"human wait \u003Cid>",{"type":71,"value":232},{"type":65,"tag":172,"props":955,"children":956},{},[957,963,965,970,972,978],{"type":65,"tag":74,"props":958,"children":960},{"className":959},[],[961],{"type":71,"value":962},"--async",{"type":71,"value":964}," — don't block at all; print the id immediately and check back\nwith ",{"type":65,"tag":74,"props":966,"children":968},{"className":967},[],[969],{"type":71,"value":952},{"type":71,"value":971}," or ",{"type":65,"tag":74,"props":973,"children":975},{"className":974},[],[976],{"type":71,"value":977},"human list",{"type":71,"value":232},{"type":65,"tag":83,"props":980,"children":981},{},[982,984,990,992,997],{"type":71,"value":983},"Use ",{"type":65,"tag":74,"props":985,"children":987},{"className":986},[],[988],{"type":71,"value":989},"--timeout",{"type":71,"value":991}," for anything inside a larger workflow that shouldn't hang\nforever waiting on a human who might be asleep; use ",{"type":65,"tag":74,"props":993,"children":995},{"className":994},[],[996],{"type":71,"value":962},{"type":71,"value":998}," when you have\nother useful work to do while you wait.",{"type":65,"tag":134,"props":1000,"children":1002},{"id":1001},"useful-flags",[1003],{"type":71,"value":1004},"Useful flags",{"type":65,"tag":168,"props":1006,"children":1007},{},[1008,1019,1061],{"type":65,"tag":172,"props":1009,"children":1010},{},[1011,1017],{"type":65,"tag":74,"props":1012,"children":1014},{"className":1013},[],[1015],{"type":71,"value":1016},"--from \"deploy-bot\"",{"type":71,"value":1018}," — label shown to the human so they know which agent\nis asking. Set this whenever you have a stable identity (skip it for\none-off ad hoc runs).",{"type":65,"tag":172,"props":1020,"children":1021},{},[1022,1028,1029,1035,1037,1043,1045,1051,1053,1059],{"type":65,"tag":74,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":71,"value":1027},"--to \u003ChumanId>",{"type":71,"value":470},{"type":65,"tag":74,"props":1030,"children":1032},{"className":1031},[],[1033],{"type":71,"value":1034},"--via \u003Ctelegram|slack|email>",{"type":71,"value":1036}," — only needed for\nmulti-human or multi-channel setups; the default human and channel from\n",{"type":65,"tag":74,"props":1038,"children":1040},{"className":1039},[],[1041],{"type":71,"value":1042},"human setup",{"type":71,"value":1044}," are almost always right. Don't guess a channel — if you\nneed a specific one, pass ",{"type":65,"tag":74,"props":1046,"children":1048},{"className":1047},[],[1049],{"type":71,"value":1050},"--via",{"type":71,"value":1052},"; the API errors if that channel is not\nlinked yet (",{"type":65,"tag":74,"props":1054,"children":1056},{"className":1055},[],[1057],{"type":71,"value":1058},"human setup \u003Cchannel>",{"type":71,"value":1060},").",{"type":65,"tag":172,"props":1062,"children":1063},{},[1064,1070],{"type":65,"tag":74,"props":1065,"children":1067},{"className":1066},[],[1068],{"type":71,"value":1069},"--ttl 2h",{"type":71,"value":1071}," — how long the request stays answerable before it expires\n(default 24h, max 72h). Shorten this for anything time-sensitive so a\nstale approval can't be actioned days later.",{"type":65,"tag":134,"props":1073,"children":1075},{"id":1074},"checking-in-without-asking-something-new",[1076],{"type":71,"value":1077},"Checking in without asking something new",{"type":65,"tag":168,"props":1079,"children":1080},{},[1081,1091,1108],{"type":65,"tag":172,"props":1082,"children":1083},{},[1084,1089],{"type":65,"tag":74,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":71,"value":977},{"type":71,"value":1090}," — see pending\u002Frecent interactions (useful before creating a\nduplicate ask).",{"type":65,"tag":172,"props":1092,"children":1093},{},[1094,1099,1101,1106],{"type":65,"tag":74,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":71,"value":952},{"type":71,"value":1100}," — resume blocking on something you created with\n",{"type":65,"tag":74,"props":1102,"children":1104},{"className":1103},[],[1105],{"type":71,"value":962},{"type":71,"value":1107}," or that previously timed out.",{"type":65,"tag":172,"props":1109,"children":1110},{},[1111,1117],{"type":65,"tag":74,"props":1112,"children":1114},{"className":1113},[],[1115],{"type":71,"value":1116},"human cancel \u003Cid>",{"type":71,"value":1118}," — withdraw a pending request you no longer need\nanswered (e.g. you found another way forward).",{"type":65,"tag":1120,"props":1121,"children":1122},"style",{},[1123],{"type":71,"value":1124},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1126,"total":1240},[1127,1142,1149,1164,1176,1189,1208,1219,1231],{"slug":1128,"name":1128,"fn":1129,"description":1130,"org":1131,"tags":1132,"stars":26,"repoUrl":27,"updatedAt":1141},"env-setup","configure Novu environment variables","Create or update Novu environment variables in the user's project safely (never expose the secret key to the client). Complements the official Novu skills by covering project-level env configuration.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1133,1136,1139],{"name":1134,"slug":1135,"type":16},"Configuration","configuration",{"name":1137,"slug":1138,"type":16},"Environment Variables","environment-variables",{"name":1140,"slug":39,"type":16},"Notifications","2026-07-13T06:21:58.740401",{"slug":4,"name":4,"fn":5,"description":6,"org":1143,"tags":1144,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1145,1146,1147,1148],{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16},{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16},{"slug":1150,"name":1150,"fn":1151,"description":1152,"org":1153,"tags":1154,"stars":306,"repoUrl":1162,"updatedAt":1163},"novu-dashboard-workflows","author Novu workflow step content","Author step content for Novu workflows defined in the Dashboard or generated\u002Fedited via the Novu MCP. Use when filling in step controls (subject, body, editorType, headers, body, conditions) for email, in-app, sms, push, chat, delay, digest, throttle, or HTTP Request steps.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1155,1158,1159],{"name":1156,"slug":1157,"type":16},"MCP","mcp",{"name":1140,"slug":39,"type":16},{"name":1160,"slug":1161,"type":16},"Workflow Automation","workflow-automation","https:\u002F\u002Fgithub.com\u002Fnovuhq\u002Fskills","2026-07-13T06:21:22.380822",{"slug":1165,"name":1165,"fn":1166,"description":1167,"org":1168,"tags":1169,"stars":306,"repoUrl":1162,"updatedAt":1175},"novu-design-workflow","design Novu notification workflows","Design notification workflows the Novu way — choose channels, set severity, decide when a workflow is critical, configure digests, and route based on subscriber state. Applies to BOTH dashboard-authored and code-first (`@novu\u002Fframework`) workflows. Use when planning a new workflow, deciding which channels to include, picking severity, configuring digest behavior, or matching a use case (order confirmation, payment failed, account suspended, comment, trial expiring, password reset, webhook fan-out, fetch-then-notify) to a proven template.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1170,1173,1174],{"name":1171,"slug":1172,"type":16},"Messaging","messaging",{"name":1140,"slug":39,"type":16},{"name":1160,"slug":1161,"type":16},"2026-07-16T06:02:17.656187",{"slug":1177,"name":1177,"fn":1178,"description":1179,"org":1180,"tags":1181,"stars":306,"repoUrl":1162,"updatedAt":1188},"novu-framework-integration","build code-first notification workflows","Build code-first notification workflows with @novu\u002Fframework. Use when defining workflows in TypeScript (Zod \u002F JSON Schema \u002F Class Validator), composing channel steps (email, SMS, push, chat, in-app) with action steps (delay, digest, custom), exposing Step Controls for non-technical teammates, rendering React\u002FVue\u002FSvelte Email templates, hosting the Bridge Endpoint inside Next.js, Express, NestJS, Remix, Nuxt, SvelteKit, H3, or AWS Lambda, syncing to Novu Cloud via CLI \u002F GitHub Actions, securing production with HMAC, or implementing translations, hydration, multi-channel orchestration, and LLM-powered notification logic in code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1182,1185,1186],{"name":1183,"slug":1184,"type":16},"Backend","backend",{"name":1140,"slug":39,"type":16},{"name":1187,"slug":45,"type":16},"TypeScript","2026-07-13T06:21:20.83585",{"slug":1190,"name":1190,"fn":1191,"description":1192,"org":1193,"tags":1194,"stars":306,"repoUrl":1162,"updatedAt":1207},"novu-inbox-integration","integrate Novu in-app notification inbox","Integrate Novu's in-app notification inbox into web applications. Supports React, Next.js, and vanilla JavaScript. Includes the Inbox component (bell icon + notification feed), composable components (Bell, Notifications, InboxContent, Preferences), headless hooks, branded theming, custom render props, multi-tenancy via contexts, tabs, localization, and HMAC security. Use when adding an in-app notification center, bell icon, notification feed, real-time notification updates, or building a personalized and branded notification experience.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1195,1198,1201,1204,1205],{"name":1196,"slug":1197,"type":16},"Frontend","frontend",{"name":1199,"slug":1200,"type":16},"JavaScript","javascript",{"name":1202,"slug":1203,"type":16},"Next.js","next-js",{"name":1140,"slug":39,"type":16},{"name":1206,"slug":41,"type":16},"React","2026-07-13T06:21:11.359078",{"slug":1209,"name":1209,"fn":1210,"description":1211,"org":1212,"tags":1213,"stars":306,"repoUrl":1162,"updatedAt":1218},"novu-manage-preferences","configure Novu notification preferences","Configure notification preferences in Novu at the workflow and subscriber level. Set default channel preferences (email, SMS, push, chat, in-app), mark preferences as read-only or subscriber-editable, and manage subscriber-specific overrides. Use when setting up notification opt-in\u002Fopt-out, configuring per-channel delivery preferences, or building a preferences management UI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1214,1215],{"name":1140,"slug":39,"type":16},{"name":1216,"slug":1217,"type":16},"Operations","operations","2026-07-13T06:21:30.061407",{"slug":1220,"name":1220,"fn":1221,"description":1222,"org":1223,"tags":1224,"stars":306,"repoUrl":1162,"updatedAt":1230},"novu-manage-subscribers","manage Novu notification subscribers and topics","Create, update, search, and delete subscribers in Novu. Manage topics for group-based notification targeting. Set subscriber credentials for push and chat channels. Use when managing notification recipients, creating subscriber records, organizing subscribers into topics, or configuring channel-specific credentials.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1225,1228,1229],{"name":1226,"slug":1227,"type":16},"API Development","api-development",{"name":1171,"slug":1172,"type":16},{"name":1140,"slug":39,"type":16},"2026-07-16T06:00:28.792114",{"slug":1232,"name":1232,"fn":1233,"description":1234,"org":1235,"tags":1236,"stars":306,"repoUrl":1162,"updatedAt":1239},"novu-trigger-notification","trigger Novu notification workflows","Trigger Novu notification workflows to send messages across email, SMS, push, chat, and in-app channels. Supports single triggers, bulk triggers, broadcast to all subscribers, topic-based targeting, and cancellation. Use when sending transactional notifications, alerts, or any event-driven messages.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1237,1238],{"name":18,"slug":19,"type":16},{"name":1140,"slug":39,"type":16},"2026-07-13T06:21:23.63132",9,{"items":1242,"total":337},[1243,1249],{"slug":1128,"name":1128,"fn":1129,"description":1130,"org":1244,"tags":1245,"stars":26,"repoUrl":27,"updatedAt":1141},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1246,1247,1248],{"name":1134,"slug":1135,"type":16},{"name":1137,"slug":1138,"type":16},{"name":1140,"slug":39,"type":16},{"slug":4,"name":4,"fn":5,"description":6,"org":1250,"tags":1251,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1252,1253,1254,1255],{"name":24,"slug":25,"type":16},{"name":18,"slug":19,"type":16},{"name":21,"slug":22,"type":16},{"name":14,"slug":15,"type":16}]