Zellij Cross-Session Orchestration
Use this skill when the user wants to work with their zellij-based coding-agent workflows from ~/pro/botfiles, especially for detached task launches or cross-session coordination.
Trigger conditions
Load this skill when the user asks to:
- start a side task in another zellij session
- inspect another live task/session
- send a message into another live zellij-backed agent session
- use repo-managed
work-* / zellij orchestration conventions from ~/pro/botfiles
Source of truth
Prefer the repo-managed helpers and docs in ~/pro/botfiles:
README.md
docs/cross-session-orchestration-contract.md
codex/skills/start-zellij-session-for-task/SKILL.md
codex/skills/cross-session-context/SKILL.md
codex/skills/cross-session-message/SKILL.md
Core commands
1) Launch a detached side-task session
Use when the user wants a second coding-agent run without taking over the current terminal.
start-zellij-session-for-task --project-root "<project-root>" <linear url|linear id|github issue url|task description>
Optional target override:
start-zellij-session-for-task --project-root "<project-root>" --target ml <...>
Raw Codex fallback for hosts without the App Server notification wrappers:
start-zellij-session-for-task --project-root "<project-root>" --no-codex-app-notify <...>
Supported targets from the botfiles docs:
here (default)
ml
arya
agent
Behavior to preserve:
- resolves tracker/slug context with shared task-status tooling
- creates a detached zellij session named from the resolved task slug
- renames the initial tab to
[TRACKER-ID] when available
- launches Codex through
codex-app-notify-session into a real spawned pane in the detached session (not only via options --default-shell) so attach/dump-screen can verify visible Codex UI and request_user_input prompts can notify via the App Server proxy
- clears inherited
CODEX_* metadata before starting child Codex
- seeds the child session with
$start-new-task <original input>
- uses
codex-app-notify-session --dangerously-bypass-approvals-and-sandbox by default; use --no-codex-app-notify only as an explicit raw-Codex fallback
- fails early for remote targets if the project root is not present there
- supports
--dry-run for inspection-only requests
- on current Linux/Zellij behavior, prefer a two-step launch pattern for detached sessions: create the background session first, then inject the bootstrap command as a real pane command (for example via
ZELLIJ_SESSION_NAME=<session> zellij run -- <bootstrap-script>) rather than relying on attach --create-background ... options --default-shell <script> to materialize a visible pane
- post-launch verification should inspect the actual spawned pane (commonly
terminal_1) because the initial terminal_0 pane may remain empty in detached-session flows
2) Inspect another tracked live session
Use the helper instead of manually scraping zellij state.
get-cross-session-context --project-root "<project-root>" <task slug|tracker ref|session name>
Useful flags:
--include-transcript-tail 4
--json
--tab-name <name>
- lower-level overrides only for debug work:
--task-dir, --status-file, --zellij-session
Behavior to preserve:
- task/status metadata is the primary source of truth
- transcript tail is only a targeted fallback
- live zellij inspection is diagnostic only
- if multiple task homes match, stop and surface candidates instead of guessing
3) Preview or send a bounded cross-session message
Always preview first because the helper is dry-run by default.
send-zellij-message --project-root "<project-root>" --text "<message>" <task slug|tracker ref|session name>
Useful flags:
--execute
--submit enter
--tab-name <name>
--json
Behavior to preserve:
- run preview first and inspect the resolved target
- add
--execute only once the target looks correct
- use
--submit enter only when intentional
- require
composer_preflight: safe_empty before execution and
outcome: delivered plus delivered: true before claiming a forwarded turn
- treat
executed, verified staging, and an Enter action as intermediate states,
not delivery
- long or multiline Codex payloads receive an extra delayed confirm Enter only
when the intended payload remains visibly staged after the first Enter
- refuse ambiguous tab selection or cross-machine targets unless the user intentionally does local debug work with explicit
--zellij-session
- use this only for bounded prompt delivery, status pings, or resumable instructions; it is not a remote-control channel
work-* conventions from README
The botfiles README documents reconnect-friendly shell helpers:
work-here
work-ml, work-ml-ssh
work-arya, work-arya-mosh, work-arya-ssh
work-agent, work-agent-mosh, work-agent-ssh
- raw shell shortcuts like
mml, marya, magent
Important conventions:
fzf is needed for interactive picker mode
- if
fzf is missing, pass a session name explicitly
- local
zellij is required for work-here
- mosh-based flows fall back to SSH if needed
- if already inside zellij on the current host, prefer the built-in session manager instead of nesting
Verification
When using these helpers, verify with:
- command exit status
- printed attach hint / resolved target
- JSON output when available for structured inspection
- remote-target project-root existence before assuming launch succeeded
- when tracker/task-slug lookup returns
no_match but you have a concrete session name from a Linear activation comment, retry get-cross-session-context with --zellij-session <session> for diagnostic live-session inspection only
- for
send-zellij-message, always do the JSON dry-run preview first; if preview
is unsafe, execution fails, or delivery remains unverified, treat the message
as not delivered and record the exact receipt before choosing a fallback
durable note
- manual fallback means attach and inspect the exact pane, then let the human
decide how to handle an existing draft or selector. Do not clear, append to,
or submit unknown composer state through the helper
Observed debug pitfall
In Arya supervision/debug flows, a freshly launched session may exist in zellij list-sessions before any tracker-backed task home, transcript path, or status artifact is discoverable. In that case:
- use Linear comments plus live zellij session existence as passive evidence of liveness
- do not claim execution-substrate context beyond what the helper actually resolved
- if
send-zellij-message --execute times out on a zellij tab-selection action (for example go-to-tab-name), treat that as a helper delivery failure, not as a successful nudge
- prefer leaving a durable Linear supervision comment over repeated blind retries when the lane is still fresh and not clearly stalled
- if you launch a fresh detached task and
get-cross-session-context still reports no_match, treat that as "metadata not materialized yet" rather than a failed launch when the start helper already returned success with a concrete session name/tab/attach hint
Practical debug notes
- In Hermes terminal calls, prefer passing bare tracker IDs like
ZON-101 to start-zellij-session-for-task instead of full https://linear.app/... URLs when possible. Full Linear URLs can trigger the terminal security scanner because of the .app TLD, while the tracker ID avoids the approval interruption and still resolves correctly.
- Do not use
~ inside the terminal tool workdir; resolve it to an absolute path such as /home/azureuser/pro/botfiles first.
- In cron/supervision environments, verify the helper repo path exists on the current machine before assuming
~/pro/botfiles-style commands are runnable. If the expected botfiles checkout is absent, fall back to durable passive evidence already referenced from Linear/task artifacts instead of claiming helper-based verification.
- In passive Arya supervision, a
get-cross-session-context ... <TRACKER> result of status: no_match does not by itself mean the lane lacks a reviewer-facing artifact or needs recovery; first inspect recent Linear comments because some review-ready lanes only surfaced their durable handoff in comments rather than a tracked task home.
- If you retry with
--zellij-session <session> for diagnostic inspection and the helper returns status: ambiguous with many candidate task homes, treat that as "no verified live execution substrate" for the target lane. Do not infer liveness from the shared zellij session name alone, and prefer a durable Linear note over any bounded nudge.
- When checking repo-backed PR/CI context from supervision loops, treat broad
gh pr list --search '<TRACKER>' matches carefully: the command can return unrelated historical PRs that happen to mention the same string somewhere. Only forward PR/CI context when the match is clearly ticket-specific by title, branch, URL, or repo context.
- For Arya pickup of generic Zone tickets that lack repo-local evidence, default the launch root to
~/pro/personal_os rather than a broad product repo guess. Treat ticket-local evidence as things like an explicit repo/path mention, linked GitHub issue/PR/repo, or existing tracked task metadata.
- Do not treat
start-zellij-session-for-task success plus zellij list-sessions presence as sufficient activation evidence. A stale session name collision or an idle shell pane can produce those signals without a real live Codex surface.
- After a supposedly successful detached launch, verify the target pane itself (for example with
zellij ... action dump-screen -f) and require visible Codex/start-task output before calling it a real execution path.
- If a pickup ticket remains in
Todo because a stale session already exists for the expected slug, treat that as a blocked/failed execution verification case, not as successful activation. Prefer leaving a compact Linear explanation comment and clearing the stale session before retrying pickup.
- For tracker-linked work that lacks repo-specific evidence, default canonical project root to
~/pro/personal_os rather than inferring some other product repo from broad company context alone.
- In pickup loops, do not treat a launched zellij session plus helper success text as sufficient activation evidence. Confirm the detached pane visibly shows Codex/start-new-task output before calling it a real execution path or moving a ticket to
In Progress.
- If
start-zellij-session-for-task returns session already exists, do not treat that as activation or successful reuse by itself. Immediately inspect with get-cross-session-context; if tracker-backed metadata is still missing, you only have a bare/legacy zellij session until Codex visibility is independently verified.
- On this machine/tooling combination,
zellij action dump-screen does not accept a --session selector, so it is not a reliable detached-session verification path from Hermes by itself. Prefer the repo helper outputs plus conservative status handling over ad hoc attach-and-type probing unless you intentionally accept diagnostic-only shell interaction.
Pitfalls
- Do not treat raw zellij inspection as the main contract when task metadata exists.
- Do not write into another session without previewing first.
- Do not guess among ambiguous sessions/tabs.
- Do not assume cross-machine sends are allowed; the helper intentionally blocks many of them.
- Do not override target/profile behavior unless the user explicitly asks.
1---2name: zellij-cross-session-orchestration3description: Use repo-managed zellij helpers from ~/pro/botfiles to inspect, message, and launch parallel coding-agent task sessions.4---56# Zellij Cross-Session Orchestration78Use this skill when the user wants to work with their zellij-based coding-agent workflows from `~/pro/botfiles`, especially for detached task launches or cross-session coordination.910## Trigger conditions1112Load this skill when the user asks to:13- start a side task in another zellij session14- inspect another live task/session15- send a message into another live zellij-backed agent session16- use repo-managed `work-*` / zellij orchestration conventions from `~/pro/botfiles`1718## Source of truth1920Prefer the repo-managed helpers and docs in `~/pro/botfiles`:21- `README.md`22- `docs/cross-session-orchestration-contract.md`23- `codex/skills/start-zellij-session-for-task/SKILL.md`24- `codex/skills/cross-session-context/SKILL.md`25- `codex/skills/cross-session-message/SKILL.md`2627## Core commands2829### 1) Launch a detached side-task session3031Use when the user wants a second coding-agent run without taking over the current terminal.3233```bash34start-zellij-session-for-task --project-root "<project-root>" <linear url|linear id|github issue url|task description>35```3637Optional target override:3839```bash40start-zellij-session-for-task --project-root "<project-root>" --target ml <...>41```4243Raw Codex fallback for hosts without the App Server notification wrappers:4445```bash46start-zellij-session-for-task --project-root "<project-root>" --no-codex-app-notify <...>47```4849Supported targets from the botfiles docs:50- `here` (default)51- `ml`52- `arya`53- `agent`5455Behavior to preserve:56- resolves tracker/slug context with shared task-status tooling57- creates a detached zellij session named from the resolved task slug58- renames the initial tab to `[TRACKER-ID]` when available59- launches Codex through `codex-app-notify-session` into a real spawned pane in the detached session (not only via `options --default-shell`) so attach/dump-screen can verify visible Codex UI and `request_user_input` prompts can notify via the App Server proxy60- clears inherited `CODEX_*` metadata before starting child Codex61- seeds the child session with `$start-new-task <original input>`62- uses `codex-app-notify-session --dangerously-bypass-approvals-and-sandbox` by default; use `--no-codex-app-notify` only as an explicit raw-Codex fallback63- fails early for remote targets if the project root is not present there64- supports `--dry-run` for inspection-only requests65- on current Linux/Zellij behavior, prefer a two-step launch pattern for detached sessions: create the background session first, then inject the bootstrap command as a real pane command (for example via `ZELLIJ_SESSION_NAME=<session> zellij run -- <bootstrap-script>`) rather than relying on `attach --create-background ... options --default-shell <script>` to materialize a visible pane66- post-launch verification should inspect the actual spawned pane (commonly `terminal_1`) because the initial `terminal_0` pane may remain empty in detached-session flows676869## 2) Inspect another tracked live session7071Use the helper instead of manually scraping zellij state.7273```bash74get-cross-session-context --project-root "<project-root>" <task slug|tracker ref|session name>75```7677Useful flags:78- `--include-transcript-tail 4`79- `--json`80- `--tab-name <name>`81- lower-level overrides only for debug work: `--task-dir`, `--status-file`, `--zellij-session`8283Behavior to preserve:84- task/status metadata is the primary source of truth85- transcript tail is only a targeted fallback86- live zellij inspection is diagnostic only87- if multiple task homes match, stop and surface candidates instead of guessing8889## 3) Preview or send a bounded cross-session message9091Always preview first because the helper is dry-run by default.9293```bash94send-zellij-message --project-root "<project-root>" --text "<message>" <task slug|tracker ref|session name>95```9697Useful flags:98- `--execute`99- `--submit enter`100- `--tab-name <name>`101- `--json`102103Behavior to preserve:104- run preview first and inspect the resolved target105- add `--execute` only once the target looks correct106- use `--submit enter` only when intentional107- require `composer_preflight: safe_empty` before execution and108 `outcome: delivered` plus `delivered: true` before claiming a forwarded turn109- treat `executed`, verified staging, and an Enter action as intermediate states,110 not delivery111- long or multiline Codex payloads receive an extra delayed confirm Enter only112 when the intended payload remains visibly staged after the first Enter113- refuse ambiguous tab selection or cross-machine targets unless the user intentionally does local debug work with explicit `--zellij-session`114- use this only for bounded prompt delivery, status pings, or resumable instructions; it is not a remote-control channel115116## work-* conventions from README117118The botfiles README documents reconnect-friendly shell helpers:119- `work-here`120- `work-ml`, `work-ml-ssh`121- `work-arya`, `work-arya-mosh`, `work-arya-ssh`122- `work-agent`, `work-agent-mosh`, `work-agent-ssh`123- raw shell shortcuts like `mml`, `marya`, `magent`124125Important conventions:126- `fzf` is needed for interactive picker mode127- if `fzf` is missing, pass a session name explicitly128- local `zellij` is required for `work-here`129- mosh-based flows fall back to SSH if needed130- if already inside zellij on the current host, prefer the built-in session manager instead of nesting131132## Verification133134When using these helpers, verify with:135- command exit status136- printed attach hint / resolved target137- JSON output when available for structured inspection138- remote-target project-root existence before assuming launch succeeded139- when tracker/task-slug lookup returns `no_match` but you have a concrete session name from a Linear activation comment, retry `get-cross-session-context` with `--zellij-session <session>` for diagnostic live-session inspection only140- for `send-zellij-message`, always do the JSON dry-run preview first; if preview141 is unsafe, execution fails, or delivery remains unverified, treat the message142 as not delivered and record the exact receipt before choosing a fallback143 durable note144- manual fallback means attach and inspect the exact pane, then let the human145 decide how to handle an existing draft or selector. Do not clear, append to,146 or submit unknown composer state through the helper147148## Observed debug pitfall149150In Arya supervision/debug flows, a freshly launched session may exist in `zellij list-sessions` before any tracker-backed task home, transcript path, or status artifact is discoverable. In that case:151- use Linear comments plus live zellij session existence as passive evidence of liveness152- do **not** claim execution-substrate context beyond what the helper actually resolved153- if `send-zellij-message --execute` times out on a zellij tab-selection action (for example `go-to-tab-name`), treat that as a helper delivery failure, not as a successful nudge154- prefer leaving a durable Linear supervision comment over repeated blind retries when the lane is still fresh and not clearly stalled155- if you launch a fresh detached task and `get-cross-session-context` still reports `no_match`, treat that as "metadata not materialized yet" rather than a failed launch when the start helper already returned success with a concrete session name/tab/attach hint156157## Practical debug notes158159- In Hermes terminal calls, prefer passing bare tracker IDs like `ZON-101` to `start-zellij-session-for-task` instead of full `https://linear.app/...` URLs when possible. Full Linear URLs can trigger the terminal security scanner because of the `.app` TLD, while the tracker ID avoids the approval interruption and still resolves correctly.160- Do not use `~` inside the terminal tool `workdir`; resolve it to an absolute path such as `/home/azureuser/pro/botfiles` first.161- In cron/supervision environments, verify the helper repo path exists on the current machine before assuming `~/pro/botfiles`-style commands are runnable. If the expected botfiles checkout is absent, fall back to durable passive evidence already referenced from Linear/task artifacts instead of claiming helper-based verification.162- In passive Arya supervision, a `get-cross-session-context ... <TRACKER>` result of `status: no_match` does not by itself mean the lane lacks a reviewer-facing artifact or needs recovery; first inspect recent Linear comments because some review-ready lanes only surfaced their durable handoff in comments rather than a tracked task home.163- If you retry with `--zellij-session <session>` for diagnostic inspection and the helper returns `status: ambiguous` with many candidate task homes, treat that as "no verified live execution substrate" for the target lane. Do not infer liveness from the shared zellij session name alone, and prefer a durable Linear note over any bounded nudge.164- When checking repo-backed PR/CI context from supervision loops, treat broad `gh pr list --search '<TRACKER>'` matches carefully: the command can return unrelated historical PRs that happen to mention the same string somewhere. Only forward PR/CI context when the match is clearly ticket-specific by title, branch, URL, or repo context.165- For Arya pickup of generic Zone tickets that lack repo-local evidence, default the launch root to `~/pro/personal_os` rather than a broad product repo guess. Treat ticket-local evidence as things like an explicit repo/path mention, linked GitHub issue/PR/repo, or existing tracked task metadata.166- Do not treat `start-zellij-session-for-task` success plus `zellij list-sessions` presence as sufficient activation evidence. A stale session name collision or an idle shell pane can produce those signals without a real live Codex surface.167- After a supposedly successful detached launch, verify the target pane itself (for example with `zellij ... action dump-screen -f`) and require visible Codex/start-task output before calling it a real execution path.168- If a pickup ticket remains in `Todo` because a stale session already exists for the expected slug, treat that as a blocked/failed execution verification case, not as successful activation. Prefer leaving a compact Linear explanation comment and clearing the stale session before retrying pickup.169- For tracker-linked work that lacks repo-specific evidence, default canonical project root to `~/pro/personal_os` rather than inferring some other product repo from broad company context alone.170- In pickup loops, do not treat a launched zellij session plus helper success text as sufficient activation evidence. Confirm the detached pane visibly shows Codex/start-new-task output before calling it a real execution path or moving a ticket to `In Progress`.171- If `start-zellij-session-for-task` returns `session already exists`, do not treat that as activation or successful reuse by itself. Immediately inspect with `get-cross-session-context`; if tracker-backed metadata is still missing, you only have a bare/legacy zellij session until Codex visibility is independently verified.172- On this machine/tooling combination, `zellij action dump-screen` does not accept a `--session` selector, so it is not a reliable detached-session verification path from Hermes by itself. Prefer the repo helper outputs plus conservative status handling over ad hoc attach-and-type probing unless you intentionally accept diagnostic-only shell interaction.173174## Pitfalls175176- Do not treat raw zellij inspection as the main contract when task metadata exists.177- Do not write into another session without previewing first.178- Do not guess among ambiguous sessions/tabs.179- Do not assume cross-machine sends are allowed; the helper intentionally blocks many of them.180- Do not override target/profile behavior unless the user explicitly asks.