[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-deepgram-multi-session":3,"mdc-oxvfe4-key":32,"related-repo-deepgram-multi-session":871,"related-org-deepgram-multi-session":957},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":22,"repoUrl":23,"updatedAt":24,"license":25,"forks":26,"topics":27,"repo":28,"sourceUrl":30,"mdContent":31},"multi-session","orchestrate parallel terminal sessions","Use when you need to orchestrate multiple parallel terminal sessions via wsh server mode. Examples: \"run builds in parallel across several projects\", \"tail logs in one session while working in another\", \"fan out tests across multiple sessions and gather results\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"deepgram","Deepgram","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fdeepgram.png",[12,16,19],{"name":13,"slug":14,"type":15},"Automation","automation","tag",{"name":17,"slug":18,"type":15},"CLI","cli",{"name":20,"slug":21,"type":15},"Engineering","engineering",5,"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fwsh","2026-07-12T08:29:34.248241",null,2,[],{"repoUrl":23,"stars":22,"forks":26,"topics":29,"description":25},[],"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fwsh\u002Ftree\u002FHEAD\u002Fskills\u002Fmulti-session","---\nname: multi-session\ndescription: >\n  Use when you need to orchestrate multiple parallel terminal sessions\n  via wsh server mode. Examples: \"run builds in parallel across several\n  projects\", \"tail logs in one session while working in another\",\n  \"fan out tests across multiple sessions and gather results\".\n---\n\n> **IMPORTANT: EXECUTION CONTEXT**\n> This skill describes *what to do* — domain patterns and decision-making.\n> It does NOT describe *how* to call the API.\n>\n> 1. **If you have `wsh_*` tools** (check your toolkit for `wsh_send_input`,\n>    `wsh_get_screen`, etc.): use them directly. Operation names in this\n>    skill generally map to tool names (e.g., \"send input\" → `wsh_send_input`).\n>    When in doubt, list your available `wsh_*` tools.\n> 2. **If you do NOT have `wsh_*` tools**: you are in HTTP\u002Fcurl fallback mode.\n>    **DO NOT GUESS endpoints or CLI subcommands.**\n>    Load the full API reference first: search your workspace for\n>    `skills\u002Fcore\u002F` and read `SKILL.md`. It contains every endpoint\n>    with working curl examples and a bootstrap sequence.\n> 3. **Quick bootstrap**: `curl -sf --unix-socket ${XDG_RUNTIME_DIR:-\u002Ftmp}\u002Fwsh\u002Fdefault.http.sock http:\u002F\u002Flocalhost\u002Fhealth`\n>    — if that fails: `wsh server -L agent-$$ --ephemeral &` and retry.\n\n# wsh:multi-session — Parallel Terminal Sessions\n\nSometimes one terminal isn't enough. You need to run a build\nwhile tailing logs. Run tests across three environments\nsimultaneously. Drive multiple processes that each need\nindependent input and output. Multi-session gives you this.\n\n## When to Use Multiple Sessions\n\n**Use multi-session when:**\n- Tasks are independent and can run in parallel\n- You need isolated environments (different directories,\n  different env vars, different shells)\n- A long-running process needs monitoring while you work\n  in another session\n- You're coordinating multiple tools that each need their\n  own terminal\n\n**Don't use multi-session when:**\n- A single shell with `&&` or `&` would suffice\n- The tasks are strictly sequential\n- You only need to run one thing at a time\n\n## Prerequisites\n\nwsh always runs as a server daemon, so multi-session is\nalways available. The sessions API endpoint is at\n`\u002Fsessions\u002F`. You create sessions explicitly and interact\nwith each via `\u002Fsessions\u002F:name\u002F` prefix.\n\nIf you're in an attached wsh session (started with `wsh`),\nthere's already a `default` session. You can create\nadditional sessions via the API alongside it.\n\n## Creating Sessions\n\nGive each session a descriptive name that reflects its purpose:\n\n    create session \"build\"\n    create session \"test\" with command: npm test --watch\n    create session \"logs\" with command: tail -f \u002Fvar\u002Flog\u002Fapp.log\n\nYou can specify:\n- `name` — identifier (auto-generated if omitted)\n- `command` — run a specific command instead of a shell\n- `rows`, `cols` — terminal dimensions\n- `cwd` — working directory\n- `env` — environment variables (object of key-value pairs)\n- `tags` — string labels for grouping and filtering\n\nA session with a `command` will exit when that command\nfinishes. A session without one starts an interactive shell\nthat persists until you kill it.\n\n## Listing and Inspecting\n\n    list sessions\n    get session \"build\"\n\n## Ending Sessions\n\nPrefer a graceful exit when the session is running an\ninteractive program:\n\n    # Exit a shell\n    send input to \"build\": exit\\n\n\n    # Quit a TUI\n    send input to \"monitor\": q\n\nThe session will close automatically when its process exits.\n\nIf the process is stuck or you don't care about graceful\nshutdown, force-kill it:\n\n    kill session \"build\"\n\nThis terminates the process immediately. Clean up after\nyourself — don't leave orphaned sessions running.\n\n## Renaming Sessions\n\nIf a session's purpose changes:\n\n    rename session \"build\" to \"build-v2\"\n\n## Working Across Sessions\n\nThe power of multi-session is parallelism. Here are the\ncommon coordination patterns.\n\n### Fan-Out: Run in Parallel, Gather Results\n\nSpawn several sessions, kick off work in each, then poll\nthem for completion. Tag them for easy group operations:\n\n    # Create sessions and start work (all tagged \"ci\")\n    create session \"test-unit\" tagged: ci, send: npm run test:unit\n    create session \"test-e2e\" tagged: ci, send: npm run test:e2e\n    create session \"lint\" tagged: ci, send: npm run lint\n\n    # Poll each for completion\n    for each session:\n        wait for idle\n        read screen\n        check for shell prompt (done) or still running\n\n    # Gather results\n    read scrollback from each session\n    report combined results\n\nThis is the most common pattern. The key insight: you don't\nhave to wait for one to finish before checking another.\n\n**Best approach — wait for any session (with tag filter):**\n\n    wait for idle on sessions tagged \"ci\" (timeout 1000ms)\n    # returns the name of whichever session settled first\n    # read its screen, check if done\n    # repeat with last_session + last_generation to avoid\n    # re-returning the same session immediately\n\nThis races all tagged sessions and returns the first to settle.\nMuch more efficient than polling each one individually. The tag\nfilter ensures unrelated sessions don't interfere.\n\n**Alternative — poll round-robin:**\n\n    await idle test-unit (short timeout, 1000ms, fresh=true)\n    await idle test-e2e (short timeout, 1000ms, fresh=true)\n    await idle lint (short timeout, 1000ms, fresh=true)\n    # repeat until all show shell prompts\n    # fresh=true prevents busy-loop storms when a session is idle\n\n### Watcher: Long-Running Process + Working Session\n\nOne session runs something persistent (a dev server, log\ntail, file watcher). Other sessions do active work.\nPeriodically check the watcher for relevant output:\n\n    create session \"server\", send: npm run dev\n    create session \"work\"\n\n    # Do work in the work session\n    send to \"work\": curl localhost:3000\u002Fapi\u002Fhealth\n\n    # Check server session for errors if something fails\n    read screen from \"server\"\n\n### Pipeline: Sequential Handoff\n\nOne session's output informs the next session's input.\nThis isn't true parallelism — it's staged work:\n\n    create session \"build\"\n    send to \"build\": cargo build 2>&1 | tee \u002Ftmp\u002Fbuild.log\n    wait for build to finish\n\n    create session \"deploy\"\n    send to \"deploy\": .\u002Fdeploy.sh\n    # only if build succeeded\n\n## Cross-Server Sessions (Federation)\n\nWhen wsh is configured as a federated cluster, sessions can span\nmultiple servers. A hub server orchestrates one or more backend\nservers, and the session list aggregates across all healthy\nbackends transparently.\n\n**What changes with federation:**\n- Sessions created on a specific backend include a `server`\n  field indicating which machine they live on\n- Session listing without a server filter returns sessions from\n  all healthy servers in the cluster\n- Tag-based workflows (fan-out, wait-for-idle with tag filter)\n  work transparently across server boundaries — tags are\n  cluster-wide, not per-server\n- The wait-for-any-session idle detection races across all\n  backends, returning whichever session settles first\n\n**What stays the same:**\n- The send\u002Fwait\u002Fread\u002Fdecide loop is identical\n- Session operations are automatically routed to the right\n  server — you don't need to track which server owns which\n  session after creation\n- Tags, naming conventions, and cleanup discipline all apply\n\nFor detailed guidance on distributed session management, server\nhealth monitoring, and failure handling, see the\n**wsh:cluster-orchestration** skill.\n\n## Pitfalls\n\n### Session Sprawl\nIt's easy to create sessions and forget about them. Every\nsession is a running process consuming resources. Adopt a\ndiscipline:\n- Create sessions with a clear purpose\n- Destroy or exit sessions as soon as their purpose is served\n- Before creating new sessions, list existing ones to see\n  if you can reuse one\n- If you're doing a fan-out, clean up all sessions when\n  the fan-out is complete\n\n### Naming and Tagging Discipline\nNames are how you identify individual sessions. Tags are how\nyou group them. Use both for organization:\n\n    Good: \"test-unit\", \"test-e2e\", \"build-frontend\"\n    Bad:  \"session1\", \"s2\", \"tmp\"\n\nIf you're creating sessions in a loop, use a predictable\nnaming scheme so you can iterate over them later:\n\n    test-0, test-1, test-2\n    build-api, build-web, build-docs\n\nTags let you group related sessions for bulk operations.\nTag all test sessions with \"test\", all build sessions with\n\"build\", then list or wait-for-idle on just that group:\n\n    create \"test-unit\" tagged: test\n    create \"test-e2e\" tagged: test\n    create \"lint\" tagged: test\n\n    list sessions tagged \"test\"\n    wait for idle on sessions tagged \"test\"\n\nTags can be added and removed after creation, so you can\nre-categorize sessions as their role changes.\n\n### Don't Multiplex What Doesn't Need It\nIf you just need to run three commands in sequence, one\nsession with `&&` is simpler than three sessions. Multi-session\nadds overhead — session creation, polling, cleanup. Only use\nit when you genuinely need parallelism or isolation.\n\n### Session Exit Detection\nA session running a specific command (not a shell) will exit\nwhen that command finishes. The session disappears from the\nsessions list. If you're polling and a session vanishes, the\nprocess finished — read its output before it's gone, or\nredirect output to a file you can read from another session.\n\n### Context Isolation Cuts Both Ways\nEach session is independent — different working directory,\ndifferent environment, different shell history. If you `cd`\nin one session, the others are unaffected. This is useful\nfor isolation but means you can't share state between\nsessions through shell variables. Use files, environment\nvariables at creation time, or the filesystem as shared state.\n",{"data":33,"body":34},{"name":4,"description":6},{"type":35,"children":36},"root",[37,189,196,201,208,216,240,248,282,288,309,330,336,341,353,358,435,447,453,462,468,473,482,487,492,501,506,512,517,526,532,537,544,549,558,563,571,580,585,593,602,608,613,622,628,633,642,648,653,661,692,700,718,730,736,742,747,770,776,781,790,795,804,809,818,823,829,841,847,852,858],{"type":38,"tag":39,"props":40,"children":41},"element","blockquote",{},[42,70],{"type":38,"tag":43,"props":44,"children":45},"p",{},[46,53,55,61,63,68],{"type":38,"tag":47,"props":48,"children":49},"strong",{},[50],{"type":51,"value":52},"text","IMPORTANT: EXECUTION CONTEXT",{"type":51,"value":54},"\nThis skill describes ",{"type":38,"tag":56,"props":57,"children":58},"em",{},[59],{"type":51,"value":60},"what to do",{"type":51,"value":62}," — domain patterns and decision-making.\nIt does NOT describe ",{"type":38,"tag":56,"props":64,"children":65},{},[66],{"type":51,"value":67},"how",{"type":51,"value":69}," to call the API.",{"type":38,"tag":71,"props":72,"children":73},"ol",{},[74,124,163],{"type":38,"tag":75,"props":76,"children":77},"li",{},[78,92,94,100,102,108,110,115,117,122],{"type":38,"tag":47,"props":79,"children":80},{},[81,83,90],{"type":51,"value":82},"If you have ",{"type":38,"tag":84,"props":85,"children":87},"code",{"className":86},[],[88],{"type":51,"value":89},"wsh_*",{"type":51,"value":91}," tools",{"type":51,"value":93}," (check your toolkit for ",{"type":38,"tag":84,"props":95,"children":97},{"className":96},[],[98],{"type":51,"value":99},"wsh_send_input",{"type":51,"value":101},",\n",{"type":38,"tag":84,"props":103,"children":105},{"className":104},[],[106],{"type":51,"value":107},"wsh_get_screen",{"type":51,"value":109},", etc.): use them directly. Operation names in this\nskill generally map to tool names (e.g., \"send input\" → ",{"type":38,"tag":84,"props":111,"children":113},{"className":112},[],[114],{"type":51,"value":99},{"type":51,"value":116},").\nWhen in doubt, list your available ",{"type":38,"tag":84,"props":118,"children":120},{"className":119},[],[121],{"type":51,"value":89},{"type":51,"value":123}," tools.",{"type":38,"tag":75,"props":125,"children":126},{},[127,138,140,145,147,153,155,161],{"type":38,"tag":47,"props":128,"children":129},{},[130,132,137],{"type":51,"value":131},"If you do NOT have ",{"type":38,"tag":84,"props":133,"children":135},{"className":134},[],[136],{"type":51,"value":89},{"type":51,"value":91},{"type":51,"value":139},": you are in HTTP\u002Fcurl fallback mode.\n",{"type":38,"tag":47,"props":141,"children":142},{},[143],{"type":51,"value":144},"DO NOT GUESS endpoints or CLI subcommands.",{"type":51,"value":146},"\nLoad the full API reference first: search your workspace for\n",{"type":38,"tag":84,"props":148,"children":150},{"className":149},[],[151],{"type":51,"value":152},"skills\u002Fcore\u002F",{"type":51,"value":154}," and read ",{"type":38,"tag":84,"props":156,"children":158},{"className":157},[],[159],{"type":51,"value":160},"SKILL.md",{"type":51,"value":162},". It contains every endpoint\nwith working curl examples and a bootstrap sequence.",{"type":38,"tag":75,"props":164,"children":165},{},[166,171,173,179,181,187],{"type":38,"tag":47,"props":167,"children":168},{},[169],{"type":51,"value":170},"Quick bootstrap",{"type":51,"value":172},": ",{"type":38,"tag":84,"props":174,"children":176},{"className":175},[],[177],{"type":51,"value":178},"curl -sf --unix-socket ${XDG_RUNTIME_DIR:-\u002Ftmp}\u002Fwsh\u002Fdefault.http.sock http:\u002F\u002Flocalhost\u002Fhealth",{"type":51,"value":180},"\n— if that fails: ",{"type":38,"tag":84,"props":182,"children":184},{"className":183},[],[185],{"type":51,"value":186},"wsh server -L agent-$$ --ephemeral &",{"type":51,"value":188}," and retry.",{"type":38,"tag":190,"props":191,"children":193},"h1",{"id":192},"wshmulti-session-parallel-terminal-sessions",[194],{"type":51,"value":195},"wsh:multi-session — Parallel Terminal Sessions",{"type":38,"tag":43,"props":197,"children":198},{},[199],{"type":51,"value":200},"Sometimes one terminal isn't enough. You need to run a build\nwhile tailing logs. Run tests across three environments\nsimultaneously. Drive multiple processes that each need\nindependent input and output. Multi-session gives you this.",{"type":38,"tag":202,"props":203,"children":205},"h2",{"id":204},"when-to-use-multiple-sessions",[206],{"type":51,"value":207},"When to Use Multiple Sessions",{"type":38,"tag":43,"props":209,"children":210},{},[211],{"type":38,"tag":47,"props":212,"children":213},{},[214],{"type":51,"value":215},"Use multi-session when:",{"type":38,"tag":217,"props":218,"children":219},"ul",{},[220,225,230,235],{"type":38,"tag":75,"props":221,"children":222},{},[223],{"type":51,"value":224},"Tasks are independent and can run in parallel",{"type":38,"tag":75,"props":226,"children":227},{},[228],{"type":51,"value":229},"You need isolated environments (different directories,\ndifferent env vars, different shells)",{"type":38,"tag":75,"props":231,"children":232},{},[233],{"type":51,"value":234},"A long-running process needs monitoring while you work\nin another session",{"type":38,"tag":75,"props":236,"children":237},{},[238],{"type":51,"value":239},"You're coordinating multiple tools that each need their\nown terminal",{"type":38,"tag":43,"props":241,"children":242},{},[243],{"type":38,"tag":47,"props":244,"children":245},{},[246],{"type":51,"value":247},"Don't use multi-session when:",{"type":38,"tag":217,"props":249,"children":250},{},[251,272,277],{"type":38,"tag":75,"props":252,"children":253},{},[254,256,262,264,270],{"type":51,"value":255},"A single shell with ",{"type":38,"tag":84,"props":257,"children":259},{"className":258},[],[260],{"type":51,"value":261},"&&",{"type":51,"value":263}," or ",{"type":38,"tag":84,"props":265,"children":267},{"className":266},[],[268],{"type":51,"value":269},"&",{"type":51,"value":271}," would suffice",{"type":38,"tag":75,"props":273,"children":274},{},[275],{"type":51,"value":276},"The tasks are strictly sequential",{"type":38,"tag":75,"props":278,"children":279},{},[280],{"type":51,"value":281},"You only need to run one thing at a time",{"type":38,"tag":202,"props":283,"children":285},{"id":284},"prerequisites",[286],{"type":51,"value":287},"Prerequisites",{"type":38,"tag":43,"props":289,"children":290},{},[291,293,299,301,307],{"type":51,"value":292},"wsh always runs as a server daemon, so multi-session is\nalways available. The sessions API endpoint is at\n",{"type":38,"tag":84,"props":294,"children":296},{"className":295},[],[297],{"type":51,"value":298},"\u002Fsessions\u002F",{"type":51,"value":300},". You create sessions explicitly and interact\nwith each via ",{"type":38,"tag":84,"props":302,"children":304},{"className":303},[],[305],{"type":51,"value":306},"\u002Fsessions\u002F:name\u002F",{"type":51,"value":308}," prefix.",{"type":38,"tag":43,"props":310,"children":311},{},[312,314,320,322,328],{"type":51,"value":313},"If you're in an attached wsh session (started with ",{"type":38,"tag":84,"props":315,"children":317},{"className":316},[],[318],{"type":51,"value":319},"wsh",{"type":51,"value":321},"),\nthere's already a ",{"type":38,"tag":84,"props":323,"children":325},{"className":324},[],[326],{"type":51,"value":327},"default",{"type":51,"value":329}," session. You can create\nadditional sessions via the API alongside it.",{"type":38,"tag":202,"props":331,"children":333},{"id":332},"creating-sessions",[334],{"type":51,"value":335},"Creating Sessions",{"type":38,"tag":43,"props":337,"children":338},{},[339],{"type":51,"value":340},"Give each session a descriptive name that reflects its purpose:",{"type":38,"tag":342,"props":343,"children":347},"pre",{"className":344,"code":346,"language":51},[345],"language-text","create session \"build\"\ncreate session \"test\" with command: npm test --watch\ncreate session \"logs\" with command: tail -f \u002Fvar\u002Flog\u002Fapp.log\n",[348],{"type":38,"tag":84,"props":349,"children":351},{"__ignoreMap":350},"",[352],{"type":51,"value":346},{"type":38,"tag":43,"props":354,"children":355},{},[356],{"type":51,"value":357},"You can specify:",{"type":38,"tag":217,"props":359,"children":360},{},[361,372,383,402,413,424],{"type":38,"tag":75,"props":362,"children":363},{},[364,370],{"type":38,"tag":84,"props":365,"children":367},{"className":366},[],[368],{"type":51,"value":369},"name",{"type":51,"value":371}," — identifier (auto-generated if omitted)",{"type":38,"tag":75,"props":373,"children":374},{},[375,381],{"type":38,"tag":84,"props":376,"children":378},{"className":377},[],[379],{"type":51,"value":380},"command",{"type":51,"value":382}," — run a specific command instead of a shell",{"type":38,"tag":75,"props":384,"children":385},{},[386,392,394,400],{"type":38,"tag":84,"props":387,"children":389},{"className":388},[],[390],{"type":51,"value":391},"rows",{"type":51,"value":393},", ",{"type":38,"tag":84,"props":395,"children":397},{"className":396},[],[398],{"type":51,"value":399},"cols",{"type":51,"value":401}," — terminal dimensions",{"type":38,"tag":75,"props":403,"children":404},{},[405,411],{"type":38,"tag":84,"props":406,"children":408},{"className":407},[],[409],{"type":51,"value":410},"cwd",{"type":51,"value":412}," — working directory",{"type":38,"tag":75,"props":414,"children":415},{},[416,422],{"type":38,"tag":84,"props":417,"children":419},{"className":418},[],[420],{"type":51,"value":421},"env",{"type":51,"value":423}," — environment variables (object of key-value pairs)",{"type":38,"tag":75,"props":425,"children":426},{},[427,433],{"type":38,"tag":84,"props":428,"children":430},{"className":429},[],[431],{"type":51,"value":432},"tags",{"type":51,"value":434}," — string labels for grouping and filtering",{"type":38,"tag":43,"props":436,"children":437},{},[438,440,445],{"type":51,"value":439},"A session with a ",{"type":38,"tag":84,"props":441,"children":443},{"className":442},[],[444],{"type":51,"value":380},{"type":51,"value":446}," will exit when that command\nfinishes. A session without one starts an interactive shell\nthat persists until you kill it.",{"type":38,"tag":202,"props":448,"children":450},{"id":449},"listing-and-inspecting",[451],{"type":51,"value":452},"Listing and Inspecting",{"type":38,"tag":342,"props":454,"children":457},{"className":455,"code":456,"language":51},[345],"list sessions\nget session \"build\"\n",[458],{"type":38,"tag":84,"props":459,"children":460},{"__ignoreMap":350},[461],{"type":51,"value":456},{"type":38,"tag":202,"props":463,"children":465},{"id":464},"ending-sessions",[466],{"type":51,"value":467},"Ending Sessions",{"type":38,"tag":43,"props":469,"children":470},{},[471],{"type":51,"value":472},"Prefer a graceful exit when the session is running an\ninteractive program:",{"type":38,"tag":342,"props":474,"children":477},{"className":475,"code":476,"language":51},[345],"# Exit a shell\nsend input to \"build\": exit\\n\n\n# Quit a TUI\nsend input to \"monitor\": q\n",[478],{"type":38,"tag":84,"props":479,"children":480},{"__ignoreMap":350},[481],{"type":51,"value":476},{"type":38,"tag":43,"props":483,"children":484},{},[485],{"type":51,"value":486},"The session will close automatically when its process exits.",{"type":38,"tag":43,"props":488,"children":489},{},[490],{"type":51,"value":491},"If the process is stuck or you don't care about graceful\nshutdown, force-kill it:",{"type":38,"tag":342,"props":493,"children":496},{"className":494,"code":495,"language":51},[345],"kill session \"build\"\n",[497],{"type":38,"tag":84,"props":498,"children":499},{"__ignoreMap":350},[500],{"type":51,"value":495},{"type":38,"tag":43,"props":502,"children":503},{},[504],{"type":51,"value":505},"This terminates the process immediately. Clean up after\nyourself — don't leave orphaned sessions running.",{"type":38,"tag":202,"props":507,"children":509},{"id":508},"renaming-sessions",[510],{"type":51,"value":511},"Renaming Sessions",{"type":38,"tag":43,"props":513,"children":514},{},[515],{"type":51,"value":516},"If a session's purpose changes:",{"type":38,"tag":342,"props":518,"children":521},{"className":519,"code":520,"language":51},[345],"rename session \"build\" to \"build-v2\"\n",[522],{"type":38,"tag":84,"props":523,"children":524},{"__ignoreMap":350},[525],{"type":51,"value":520},{"type":38,"tag":202,"props":527,"children":529},{"id":528},"working-across-sessions",[530],{"type":51,"value":531},"Working Across Sessions",{"type":38,"tag":43,"props":533,"children":534},{},[535],{"type":51,"value":536},"The power of multi-session is parallelism. Here are the\ncommon coordination patterns.",{"type":38,"tag":538,"props":539,"children":541},"h3",{"id":540},"fan-out-run-in-parallel-gather-results",[542],{"type":51,"value":543},"Fan-Out: Run in Parallel, Gather Results",{"type":38,"tag":43,"props":545,"children":546},{},[547],{"type":51,"value":548},"Spawn several sessions, kick off work in each, then poll\nthem for completion. Tag them for easy group operations:",{"type":38,"tag":342,"props":550,"children":553},{"className":551,"code":552,"language":51},[345],"# Create sessions and start work (all tagged \"ci\")\ncreate session \"test-unit\" tagged: ci, send: npm run test:unit\ncreate session \"test-e2e\" tagged: ci, send: npm run test:e2e\ncreate session \"lint\" tagged: ci, send: npm run lint\n\n# Poll each for completion\nfor each session:\n    wait for idle\n    read screen\n    check for shell prompt (done) or still running\n\n# Gather results\nread scrollback from each session\nreport combined results\n",[554],{"type":38,"tag":84,"props":555,"children":556},{"__ignoreMap":350},[557],{"type":51,"value":552},{"type":38,"tag":43,"props":559,"children":560},{},[561],{"type":51,"value":562},"This is the most common pattern. The key insight: you don't\nhave to wait for one to finish before checking another.",{"type":38,"tag":43,"props":564,"children":565},{},[566],{"type":38,"tag":47,"props":567,"children":568},{},[569],{"type":51,"value":570},"Best approach — wait for any session (with tag filter):",{"type":38,"tag":342,"props":572,"children":575},{"className":573,"code":574,"language":51},[345],"wait for idle on sessions tagged \"ci\" (timeout 1000ms)\n# returns the name of whichever session settled first\n# read its screen, check if done\n# repeat with last_session + last_generation to avoid\n# re-returning the same session immediately\n",[576],{"type":38,"tag":84,"props":577,"children":578},{"__ignoreMap":350},[579],{"type":51,"value":574},{"type":38,"tag":43,"props":581,"children":582},{},[583],{"type":51,"value":584},"This races all tagged sessions and returns the first to settle.\nMuch more efficient than polling each one individually. The tag\nfilter ensures unrelated sessions don't interfere.",{"type":38,"tag":43,"props":586,"children":587},{},[588],{"type":38,"tag":47,"props":589,"children":590},{},[591],{"type":51,"value":592},"Alternative — poll round-robin:",{"type":38,"tag":342,"props":594,"children":597},{"className":595,"code":596,"language":51},[345],"await idle test-unit (short timeout, 1000ms, fresh=true)\nawait idle test-e2e (short timeout, 1000ms, fresh=true)\nawait idle lint (short timeout, 1000ms, fresh=true)\n# repeat until all show shell prompts\n# fresh=true prevents busy-loop storms when a session is idle\n",[598],{"type":38,"tag":84,"props":599,"children":600},{"__ignoreMap":350},[601],{"type":51,"value":596},{"type":38,"tag":538,"props":603,"children":605},{"id":604},"watcher-long-running-process-working-session",[606],{"type":51,"value":607},"Watcher: Long-Running Process + Working Session",{"type":38,"tag":43,"props":609,"children":610},{},[611],{"type":51,"value":612},"One session runs something persistent (a dev server, log\ntail, file watcher). Other sessions do active work.\nPeriodically check the watcher for relevant output:",{"type":38,"tag":342,"props":614,"children":617},{"className":615,"code":616,"language":51},[345],"create session \"server\", send: npm run dev\ncreate session \"work\"\n\n# Do work in the work session\nsend to \"work\": curl localhost:3000\u002Fapi\u002Fhealth\n\n# Check server session for errors if something fails\nread screen from \"server\"\n",[618],{"type":38,"tag":84,"props":619,"children":620},{"__ignoreMap":350},[621],{"type":51,"value":616},{"type":38,"tag":538,"props":623,"children":625},{"id":624},"pipeline-sequential-handoff",[626],{"type":51,"value":627},"Pipeline: Sequential Handoff",{"type":38,"tag":43,"props":629,"children":630},{},[631],{"type":51,"value":632},"One session's output informs the next session's input.\nThis isn't true parallelism — it's staged work:",{"type":38,"tag":342,"props":634,"children":637},{"className":635,"code":636,"language":51},[345],"create session \"build\"\nsend to \"build\": cargo build 2>&1 | tee \u002Ftmp\u002Fbuild.log\nwait for build to finish\n\ncreate session \"deploy\"\nsend to \"deploy\": .\u002Fdeploy.sh\n# only if build succeeded\n",[638],{"type":38,"tag":84,"props":639,"children":640},{"__ignoreMap":350},[641],{"type":51,"value":636},{"type":38,"tag":202,"props":643,"children":645},{"id":644},"cross-server-sessions-federation",[646],{"type":51,"value":647},"Cross-Server Sessions (Federation)",{"type":38,"tag":43,"props":649,"children":650},{},[651],{"type":51,"value":652},"When wsh is configured as a federated cluster, sessions can span\nmultiple servers. A hub server orchestrates one or more backend\nservers, and the session list aggregates across all healthy\nbackends transparently.",{"type":38,"tag":43,"props":654,"children":655},{},[656],{"type":38,"tag":47,"props":657,"children":658},{},[659],{"type":51,"value":660},"What changes with federation:",{"type":38,"tag":217,"props":662,"children":663},{},[664,677,682,687],{"type":38,"tag":75,"props":665,"children":666},{},[667,669,675],{"type":51,"value":668},"Sessions created on a specific backend include a ",{"type":38,"tag":84,"props":670,"children":672},{"className":671},[],[673],{"type":51,"value":674},"server",{"type":51,"value":676},"\nfield indicating which machine they live on",{"type":38,"tag":75,"props":678,"children":679},{},[680],{"type":51,"value":681},"Session listing without a server filter returns sessions from\nall healthy servers in the cluster",{"type":38,"tag":75,"props":683,"children":684},{},[685],{"type":51,"value":686},"Tag-based workflows (fan-out, wait-for-idle with tag filter)\nwork transparently across server boundaries — tags are\ncluster-wide, not per-server",{"type":38,"tag":75,"props":688,"children":689},{},[690],{"type":51,"value":691},"The wait-for-any-session idle detection races across all\nbackends, returning whichever session settles first",{"type":38,"tag":43,"props":693,"children":694},{},[695],{"type":38,"tag":47,"props":696,"children":697},{},[698],{"type":51,"value":699},"What stays the same:",{"type":38,"tag":217,"props":701,"children":702},{},[703,708,713],{"type":38,"tag":75,"props":704,"children":705},{},[706],{"type":51,"value":707},"The send\u002Fwait\u002Fread\u002Fdecide loop is identical",{"type":38,"tag":75,"props":709,"children":710},{},[711],{"type":51,"value":712},"Session operations are automatically routed to the right\nserver — you don't need to track which server owns which\nsession after creation",{"type":38,"tag":75,"props":714,"children":715},{},[716],{"type":51,"value":717},"Tags, naming conventions, and cleanup discipline all apply",{"type":38,"tag":43,"props":719,"children":720},{},[721,723,728],{"type":51,"value":722},"For detailed guidance on distributed session management, server\nhealth monitoring, and failure handling, see the\n",{"type":38,"tag":47,"props":724,"children":725},{},[726],{"type":51,"value":727},"wsh:cluster-orchestration",{"type":51,"value":729}," skill.",{"type":38,"tag":202,"props":731,"children":733},{"id":732},"pitfalls",[734],{"type":51,"value":735},"Pitfalls",{"type":38,"tag":538,"props":737,"children":739},{"id":738},"session-sprawl",[740],{"type":51,"value":741},"Session Sprawl",{"type":38,"tag":43,"props":743,"children":744},{},[745],{"type":51,"value":746},"It's easy to create sessions and forget about them. Every\nsession is a running process consuming resources. Adopt a\ndiscipline:",{"type":38,"tag":217,"props":748,"children":749},{},[750,755,760,765],{"type":38,"tag":75,"props":751,"children":752},{},[753],{"type":51,"value":754},"Create sessions with a clear purpose",{"type":38,"tag":75,"props":756,"children":757},{},[758],{"type":51,"value":759},"Destroy or exit sessions as soon as their purpose is served",{"type":38,"tag":75,"props":761,"children":762},{},[763],{"type":51,"value":764},"Before creating new sessions, list existing ones to see\nif you can reuse one",{"type":38,"tag":75,"props":766,"children":767},{},[768],{"type":51,"value":769},"If you're doing a fan-out, clean up all sessions when\nthe fan-out is complete",{"type":38,"tag":538,"props":771,"children":773},{"id":772},"naming-and-tagging-discipline",[774],{"type":51,"value":775},"Naming and Tagging Discipline",{"type":38,"tag":43,"props":777,"children":778},{},[779],{"type":51,"value":780},"Names are how you identify individual sessions. Tags are how\nyou group them. Use both for organization:",{"type":38,"tag":342,"props":782,"children":785},{"className":783,"code":784,"language":51},[345],"Good: \"test-unit\", \"test-e2e\", \"build-frontend\"\nBad:  \"session1\", \"s2\", \"tmp\"\n",[786],{"type":38,"tag":84,"props":787,"children":788},{"__ignoreMap":350},[789],{"type":51,"value":784},{"type":38,"tag":43,"props":791,"children":792},{},[793],{"type":51,"value":794},"If you're creating sessions in a loop, use a predictable\nnaming scheme so you can iterate over them later:",{"type":38,"tag":342,"props":796,"children":799},{"className":797,"code":798,"language":51},[345],"test-0, test-1, test-2\nbuild-api, build-web, build-docs\n",[800],{"type":38,"tag":84,"props":801,"children":802},{"__ignoreMap":350},[803],{"type":51,"value":798},{"type":38,"tag":43,"props":805,"children":806},{},[807],{"type":51,"value":808},"Tags let you group related sessions for bulk operations.\nTag all test sessions with \"test\", all build sessions with\n\"build\", then list or wait-for-idle on just that group:",{"type":38,"tag":342,"props":810,"children":813},{"className":811,"code":812,"language":51},[345],"create \"test-unit\" tagged: test\ncreate \"test-e2e\" tagged: test\ncreate \"lint\" tagged: test\n\nlist sessions tagged \"test\"\nwait for idle on sessions tagged \"test\"\n",[814],{"type":38,"tag":84,"props":815,"children":816},{"__ignoreMap":350},[817],{"type":51,"value":812},{"type":38,"tag":43,"props":819,"children":820},{},[821],{"type":51,"value":822},"Tags can be added and removed after creation, so you can\nre-categorize sessions as their role changes.",{"type":38,"tag":538,"props":824,"children":826},{"id":825},"dont-multiplex-what-doesnt-need-it",[827],{"type":51,"value":828},"Don't Multiplex What Doesn't Need It",{"type":38,"tag":43,"props":830,"children":831},{},[832,834,839],{"type":51,"value":833},"If you just need to run three commands in sequence, one\nsession with ",{"type":38,"tag":84,"props":835,"children":837},{"className":836},[],[838],{"type":51,"value":261},{"type":51,"value":840}," is simpler than three sessions. Multi-session\nadds overhead — session creation, polling, cleanup. Only use\nit when you genuinely need parallelism or isolation.",{"type":38,"tag":538,"props":842,"children":844},{"id":843},"session-exit-detection",[845],{"type":51,"value":846},"Session Exit Detection",{"type":38,"tag":43,"props":848,"children":849},{},[850],{"type":51,"value":851},"A session running a specific command (not a shell) will exit\nwhen that command finishes. The session disappears from the\nsessions list. If you're polling and a session vanishes, the\nprocess finished — read its output before it's gone, or\nredirect output to a file you can read from another session.",{"type":38,"tag":538,"props":853,"children":855},{"id":854},"context-isolation-cuts-both-ways",[856],{"type":51,"value":857},"Context Isolation Cuts Both Ways",{"type":38,"tag":43,"props":859,"children":860},{},[861,863,869],{"type":51,"value":862},"Each session is independent — different working directory,\ndifferent environment, different shell history. If you ",{"type":38,"tag":84,"props":864,"children":866},{"className":865},[],[867],{"type":51,"value":868},"cd",{"type":51,"value":870},"\nin one session, the others are unaffected. This is useful\nfor isolation but means you can't share state between\nsessions through shell variables. Use files, environment\nvariables at creation time, or the filesystem as shared state.",{"items":872,"total":956},[873,888,900,911,923,933,945],{"slug":874,"name":874,"fn":875,"description":876,"org":877,"tags":878,"stars":22,"repoUrl":23,"updatedAt":887},"agent-orchestration","orchestrate multiple AI agents","Use when you need to launch and drive other AI agents (Claude Code, Aider, Codex, etc.) through their terminal interfaces via wsh. Examples: \"run multiple Claude Code sessions in parallel on different tasks\", \"feed a task to an AI agent and handle its approval prompts\", \"coordinate several AI agents working on subtasks of a larger project\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[879,882,883,884],{"name":880,"slug":881,"type":15},"Agents","agents",{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":885,"slug":886,"type":15},"Multi-Agent","multi-agent","2026-07-12T08:29:40.028618",{"slug":889,"name":889,"fn":890,"description":891,"org":892,"tags":893,"stars":22,"repoUrl":23,"updatedAt":899},"cluster-orchestration","orchestrate sessions across federated clusters","Use when you need to manage sessions across multiple wsh servers in a federated cluster. Examples: \"distribute builds across several machines\", \"create sessions on a specific backend\", \"monitor health across a cluster of servers\", \"coordinate work across server boundaries\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[894,897,898],{"name":895,"slug":896,"type":15},"Architecture","architecture",{"name":13,"slug":14,"type":15},{"name":20,"slug":21,"type":15},"2026-07-12T08:29:38.810244",{"slug":901,"name":901,"fn":902,"description":903,"org":904,"tags":905,"stars":22,"repoUrl":23,"updatedAt":910},"core","authenticate and bootstrap wsh terminal operations","REQUIRED before any wsh terminal operation when you do NOT have wsh_* MCP tools. Contains the complete HTTP API reference with working curl examples, bootstrap sequence, and authentication guide. wsh has no CLI subcommands for programmatic use — do NOT run 'wsh \u003Cverb>' commands or guess endpoints. Load this skill first.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[906,909],{"name":907,"slug":908,"type":15},"Authentication","authentication",{"name":17,"slug":18,"type":15},"2026-07-12T08:29:32.614733",{"slug":912,"name":912,"fn":913,"description":914,"org":915,"tags":916,"stars":22,"repoUrl":23,"updatedAt":922},"core-mcp","bootstrap MCP terminal sessions","REQUIRED before any wsh terminal operation. Contains the complete MCP tool reference and bootstrap sequence for wsh_create_session, wsh_send_input, wsh_get_screen, wsh_send_and_read, wsh_send_keys, and all wsh_* tools. Do NOT guess wsh CLI commands or HTTP endpoints — use MCP tools or load this skill first.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[917,918,919],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":920,"slug":921,"type":15},"MCP","mcp","2026-07-12T08:29:45.869993",{"slug":924,"name":924,"fn":925,"description":926,"org":927,"tags":928,"stars":22,"repoUrl":23,"updatedAt":932},"drive-process","interact with CLI programs via wsh","Use when you need to drive a CLI program through command-and-response interaction via wsh. Examples: \"run a build command and check the output\", \"interact with an installer that asks questions\", \"execute a sequence of shell commands and handle errors\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[929,930,931],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},"2026-07-12T08:29:51.485222",{"slug":934,"name":934,"fn":935,"description":936,"org":937,"tags":938,"stars":22,"repoUrl":23,"updatedAt":944},"generative-ui","build interactive terminal user interfaces","Use when you need to build dynamic, interactive terminal experiences on the fly. Examples: \"create a live dashboard in the terminal\", \"build an interactive file browser\", \"generate a custom TUI for this workflow\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[939,940,941],{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":942,"slug":943,"type":15},"Frontend","frontend","2026-07-12T08:29:41.286933",{"slug":946,"name":946,"fn":947,"description":948,"org":949,"tags":950,"stars":22,"repoUrl":23,"updatedAt":955},"infrastructure-ops","manage infrastructure across multiple servers","Use when you need to manage infrastructure across multiple servers interactively via wsh — deploying applications, configuring services, managing packages, performing rolling updates, and handling the prompts and judgment calls that declarative tools cannot. Examples: \"deploy this application across 10 servers with health checks between each\", \"upgrade packages across the fleet and handle diverse prompts\", \"inspect and modify configuration across servers\", \"roll back a failed deployment\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[951,952],{"name":17,"slug":18,"type":15},{"name":953,"slug":954,"type":15},"Infrastructure","infrastructure","2026-07-12T08:29:57.659886",12,{"items":958,"total":1113},[959,975,989,1003,1015,1027,1039,1050,1066,1080,1090,1102],{"slug":960,"name":960,"fn":961,"description":962,"org":963,"tags":964,"stars":972,"repoUrl":973,"updatedAt":974},"deepclaw-voice","configure phone calls with Deepgram Voice","Set up phone calling to OpenClaw using Deepgram Voice Agent API",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[965,968,969],{"name":966,"slug":967,"type":15},"API Development","api-development",{"name":9,"slug":8,"type":15},{"name":970,"slug":971,"type":15},"Voice","voice",78,"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fdeepclaw","2026-07-12T08:29:25.371332",{"slug":976,"name":976,"fn":977,"description":978,"org":979,"tags":980,"stars":986,"repoUrl":987,"updatedAt":988},"1password","manage secrets with 1Password CLI","Set up and use 1Password CLI (op). Use when installing the CLI, enabling desktop app integration, signing in (single or multi-account), or reading\u002Finjecting\u002Frunning secrets via op.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[981,982,983],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":984,"slug":985,"type":15},"Security","security",23,"https:\u002F\u002Fgithub.com\u002Fdeepgram\u002Fdglabs-deepclaw","2026-07-12T08:28:49.991939",{"slug":990,"name":990,"fn":991,"description":992,"org":993,"tags":994,"stars":986,"repoUrl":987,"updatedAt":1002},"apple-notes","manage Apple Notes on macOS","Manage Apple Notes via the `memo` CLI on macOS (create, view, edit, delete, search, move, and export notes). Use when a user asks OpenClaw to add a note, list notes, search notes, or manage note folders.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[995,996,999],{"name":17,"slug":18,"type":15},{"name":997,"slug":998,"type":15},"Knowledge Management","knowledge-management",{"name":1000,"slug":1001,"type":15},"macOS","macos","2026-07-12T08:29:01.538106",{"slug":1004,"name":1004,"fn":1005,"description":1006,"org":1007,"tags":1008,"stars":986,"repoUrl":987,"updatedAt":1014},"apple-reminders","manage Apple Reminders via CLI","Manage Apple Reminders via the `remindctl` CLI on macOS (list, add, edit, complete, delete). Supports lists, date filters, and JSON\u002Fplain output.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1009,1010,1011],{"name":17,"slug":18,"type":15},{"name":1000,"slug":1001,"type":15},{"name":1012,"slug":1013,"type":15},"Task Management","task-management","2026-07-12T08:29:14.035414",{"slug":1016,"name":1016,"fn":1017,"description":1018,"org":1019,"tags":1020,"stars":986,"repoUrl":987,"updatedAt":1026},"bear-notes","manage Bear notes via CLI","Create, search, and manage Bear notes via grizzly CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1021,1022,1023],{"name":17,"slug":18,"type":15},{"name":997,"slug":998,"type":15},{"name":1024,"slug":1025,"type":15},"Notes","notes","2026-07-12T08:28:51.246011",{"slug":1028,"name":1028,"fn":1029,"description":1030,"org":1031,"tags":1032,"stars":986,"repoUrl":987,"updatedAt":1038},"blogwatcher","monitor blogs and RSS feeds","Monitor blogs and RSS\u002FAtom feeds for updates using the blogwatcher CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1033,1034,1035],{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":1036,"slug":1037,"type":15},"Monitoring","monitoring","2026-07-12T08:29:02.762321",{"slug":1040,"name":1040,"fn":1041,"description":1042,"org":1043,"tags":1044,"stars":986,"repoUrl":987,"updatedAt":1049},"blucli","control BluOS audio playback","BluOS CLI (blu) for discovery, playback, grouping, and volume.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1045,1048],{"name":1046,"slug":1047,"type":15},"Audio","audio",{"name":17,"slug":18,"type":15},"2026-07-12T08:28:21.009637",{"slug":1051,"name":1051,"fn":1052,"description":1053,"org":1054,"tags":1055,"stars":986,"repoUrl":987,"updatedAt":1065},"bluebubbles","send and manage iMessages","Use when you need to send or manage iMessages via BlueBubbles (recommended iMessage integration). Calls go through the generic message tool with channel=\"bluebubbles\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1056,1059,1062],{"name":1057,"slug":1058,"type":15},"Communications","communications",{"name":1060,"slug":1061,"type":15},"iMessage","imessage",{"name":1063,"slug":1064,"type":15},"Messaging","messaging","2026-07-12T08:28:57.517914",{"slug":1067,"name":1067,"fn":1068,"description":1069,"org":1070,"tags":1071,"stars":986,"repoUrl":987,"updatedAt":1079},"camsnap","capture frames and clips from cameras","Capture frames or clips from RTSP\u002FONVIF cameras.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1072,1073,1076],{"name":13,"slug":14,"type":15},{"name":1074,"slug":1075,"type":15},"Camera","camera",{"name":1077,"slug":1078,"type":15},"Media","media","2026-07-12T08:28:28.096134",{"slug":1081,"name":1081,"fn":1082,"description":1083,"org":1084,"tags":1085,"stars":986,"repoUrl":987,"updatedAt":1089},"clawhub","manage agent skills with ClawHub","Use the ClawHub CLI to search, install, update, and publish agent skills from clawhub.com. Use when you need to fetch new skills on the fly, sync installed skills to latest or a specific version, or publish new\u002Fupdated skill folders with the npm-installed clawhub CLI.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1086,1087,1088],{"name":880,"slug":881,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},"2026-07-12T08:28:30.589001",{"slug":1091,"name":1091,"fn":1092,"description":1093,"org":1094,"tags":1095,"stars":986,"repoUrl":987,"updatedAt":1101},"coding-agent","run coding agents for programmatic control","Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1096,1097,1098],{"name":880,"slug":881,"type":15},{"name":13,"slug":14,"type":15},{"name":1099,"slug":1100,"type":15},"Coding","coding","2026-07-12T08:29:08.6658",{"slug":1103,"name":1103,"fn":1104,"description":1105,"org":1106,"tags":1107,"stars":986,"repoUrl":987,"updatedAt":1112},"eightctl","control Eight Sleep pod settings","Control Eight Sleep pods (status, temperature, alarms, schedules).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1108,1109],{"name":13,"slug":14,"type":15},{"name":1110,"slug":1111,"type":15},"Hardware","hardware","2026-07-12T08:28:39.322181",73]