A terminal session is an interactive shell that DataMind Oda opens for itself and keeps alive between steps, so multi-step work keeps its place: the working folder, exported variables, defined functions and programs left running all stay in the session. This page is the reference for how a session lives: how it starts, when Oda considers it ready, how sends settle, and how it ends.
The actions Oda takes in a session, with their parameters, results and markers, are on Terminal tools.
What a session is
An interactive shell, kept between steps. Oda opens it in the chat's workspace folder and reuses it across steps; one send finishing does not end the session.
State stays in place. The working folder, exported variables, defined functions and any program the session left running persist from one send to the next.
Its own prompt. A session shows the controlled prompt oda> .
Process-local. Sessions live inside the running app. They do not survive a restart of Oda, and nothing is restored afterwards.
Nothing starts on its own. A session exists only after Oda opens it; no session starts at app start.
Ids and names. Oda tells sessions apart by ids such as pty-1 and pty-2; a session can also carry a display name such as main or gdb.
Running or exited. At any moment, a session is either running or exited, with the exit code or the signal that ended it.
Owned by one chat. A session belongs to the exact chat that opened it. Another chat, or a helper Oda runs for part of the task, is refused even when it knows the session's id.
Not the side-panel terminal. The terminal in your side panel is yours; you open it and type in it. See The terminal.
Not the command shells. The bash and PowerShell shells that run Oda's commands are a separate feature with their own rules. See Persistent shells.
The life of a session
Open. Oda asks for a session, usually of the default shell type, and can give it a display name such as main or gdb. A session exists only after the shell starts successfully; a failed start is reported and rolled back, never left half-created. The chat shows a row such as started terminal session pty-1 (main) [type: shell].
Send. Oda writes input and waits for the session to settle. One send runs at a time per session; a second send is refused until the first settles.
Read. Oda reads the output the session kept, in pages, continuing from where a previous read stopped.
Stop. Stopping a send interrupts what is running with a real signal, delivered after the pending write settles; Oda never types a control character into the session. A cancelled send keeps its place until the pending write and the interrupt have both settled.
Resize. A session is created with its size and its terminal type, which programs inside see as their TERM setting. Resizing re-fits the text; nothing running in the session is restarted.
After exit. Once the shell has exited, typing into the session or resizing it is refused with terminal process has exited.
Close. Closing stops the watching, ends the work in the session and then the shell with its whole process tree, and settles any send that was still waiting. Oda asks the processes to stop and forces anything still running after the close grace. Closing is safe to repeat: a second close reads terminal session <id> was already closing and changes nothing.
Busy, idle or unknown
Apart from settling sends, Oda watches whether a session is busy or idle. The state is idle, busy or unknown, and each report carries a revision that moves on when what Oda sees changes.
Idle is never assumed. An incomplete observation is not reported as idle; when Oda cannot be sure, the answer is unknown.
Typing clears the reading. Input ends the evidence behind an earlier idle answer.
Quiet work still counts. Anything still running in the session keeps it busy; a job that has been stopped does too, even after its prompt returns, until that work is resumed or ended.
Where the watch works. Only for the plain interactive bash (version 4.4 or newer) and zsh sessions Oda can observe. Other shells, commands started in custom ways, custom signal traps or prompt handlers, and Windows report unknown.
Signals
Oda can signal the work running in a session. The signal goes to the session's foreground process group: normally the command the shell is running right now, and the session stays open afterwards.
On macOS and Linux.SIGINT, SIGTERM, SIGKILL, SIGTSTP and SIGHUP are available.
On Windows. Only SIGINT, SIGTERM and SIGKILL reach a session; suspend and hangup are refused. An interrupt arrives the way a typed Ctrl-C does, as keyboard input to the program.
A force kill at the shell itself is refused. To end a session, Oda closes it instead.
When Oda considers a session ready
Oda settles a send using three kinds of evidence, and the result says which one settled it:
The prompt came back. Oda follows the shell's own prompt marker: when the verified prompt returns and the shell holds the foreground again, the session is ready for the next input.
The input was read. After the first write, one exact reading can show that the session read its input.
Quiet counts as idle. Once a prompt has been seen, three seconds of silence, plus a half-second grace, settle the wait as idle.
Wait reason
What it means
stdin_read
The session took the input and is waiting for more.
inferred_idle
The session went quiet; this suggests the command finished, but it is not proof.
timeout
The wait reached its limit before the session settled.
session_exit
The shell itself ended, rather than a command finishing.
An idle or timed-out wait never proves that the foreground command exited: the command can still be running when the wait ends.
Output and reads
Output is kept as text lines: control sequences, colours and cursor movement are stripped, and line endings are normalised, because a session is made for commands that read and print text.
The kept window holds the newest output, up to 10,000 lines or 4 MiB; beyond that, the oldest lines drop off first.
A single read never returns more than 256 KiB of text; a cut lands on a character boundary and is marked [output truncated].
Reads page through what is kept, and a truncation sticks: once earlier output has been dropped, a read reports which lines of the kept window it returned and never presents a partial window as the whole output.
Sizes, timings and their checks
A session starts on these defaults:
Setting
Default
Shell
bash by default; PowerShell can be selected instead
Screen
40 rows by 160 columns
Kept output
10,000 lines, up to 4 MiB
Largest single read
256 KiB
Checks while settling
every 50 ms
Exact check after the first write
150 ms
Silence counted as idle
3 seconds, plus a 500 ms grace
Waiting for a send
30 seconds
Close grace
3 seconds
Oda starts the shell without your profiles or startup files: bash runs with --noprofile --norc -i and PowerShell with -NoLogo -NoProfile; paging programs are switched off and colour is off, so output stays plain.
An explicit shell command or argument set replaces the dialect defaults; an empty value falls back to them.
Oda checks these values as the app starts: they must be positive numbers, the single-read cap cannot be larger than the kept-output cap, and the idle grace cannot be shorter than one settling check.
Confinement and secrets
A session runs inside the chat's access mode, the same way Oda's commands do; the modes are described on Command sandboxing and approvals.
Full access starts the shell directly, with no limits applied.
Read Only and Workspace Write start the shell confined. On a computer where the app cannot confine a shell, the session does not start: Oda reports that the mode cannot confine a shell here, and it never falls back to running the shell unconfined.
A mode change is refused while a chat has sessions open or a session is still being created: close the open sessions and wait for any session still being created to settle, then change the mode.
Oda removes its own ambient secrets from the environment before the shell starts, so they are not present inside a session.
Refusals and failures
Every refusal names the session, the name or the reason involved, so a case is easy to describe when you report it. In plain words:
No shell for the type. A session type with no shell behind it is refused.
Not yours to use. A session that belongs to another chat, an id nothing holds any more, a session that is already closing, and sessions that are shutting down with the app are refused, each naming what is wrong.
Busy. A second send while one is active is refused until the first settles.
A name is taken. Two sessions in one chat cannot share a display name; a name another session already uses, or one that is already being created, is refused.
A start failed. If the shell ends while the session is starting, or misses its readiness deadline, no session opens; the message carries the exit code or the signal when one is known.
A close failed. A close that cannot end the processes cleanly reports the failure instead of claiming success, and closing many sessions reports how many could not be closed.
Background sends
A send can run in the background, so Oda keeps working while the session runs the command:
The send becomes a job that belongs to the chat. Oda reads its output with the job tools and stops it the same way, and a stopped background send reads as killed. See Background runs and jobs.
The job's reader keeps a byte cursor: each read continues from where the last one stopped, so output is not shown twice, and a read taken before the send starts comes back empty rather than failing.
Questions, answered
Why was an action on a session refused?
An action has to come from the exact chat that opened the session, and it has to name a session that still exists. Another chat's session, an id nothing holds any more, a session that is already closing, and sessions shutting down with the app are refused, each naming what is wrong. The chat that holds the session can still use it; for anything else, Oda opens a new session.
What do busy, idle and unknown mean?
Busy means Oda can see work running in the session. Idle means Oda can see the session sitting quietly with nothing else running in it. Unknown means Oda cannot observe the session clearly enough to say: a shell other than plain interactive bash or zsh, a custom signal trap or prompt handler, and Windows all answer unknown. An unclear observation is never called idle.
How does Oda know a session is ready for the next input?
Oda follows the shell's own prompt marker: when the verified prompt returns and the shell holds the foreground again, the session is ready. After the first write, one exact reading can show that the input was read. Once a prompt has been seen, three seconds of silence, plus a half-second grace, also settle the session as idle.
Why did the wait end with inferred_idle while the command was still running?
inferred_idle only means the session went quiet. Quiet suggests the command finished, but it is not proof: the command can still be running after the wait ends. A timeout wait proves no more than that.
How are signals different on Windows?
On Windows, only SIGINT, SIGTERM and SIGKILL reach a session, and a request for suspend or hangup is refused. An interrupt arrives the way a typed Ctrl-C does, as keyboard input to the program running in the session. On every system, a SIGKILL aimed at the shell itself is refused; Oda closes the session instead.
Why is a session still busy after I stopped a send?
Stopping a send does not free its place at once. The send keeps the session's single slot until the pending write and the interrupt have both settled, and the next send can start only after that.
What happens to a waiting send when the session closes?
Closing ends the wait: the send settles as a session exit, and the shell with everything running under it ends. The session then reads as closed.
Can I name a session, and why was a name refused?
Yes; a session can carry a display name such as main or gdb. Names are per chat: a name another session in the same chat already uses, or a name that is already being created, is refused. Leaving the name out is always fine.
How long does a terminal session live?
While the app runs and while the chat that opened it lives. A session is not shared with other chats and is not restored after a restart of Oda; when its chat is gone, the session is gone with it. Oda opens a fresh session when it next needs one.
What does it mean when closing a session reports a failure?
The close could not end the shell and its processes cleanly, so Oda reports the failure instead of claiming success; closing many sessions reports how many could not be closed. Ask Oda to close the session again, and keep the message, which names the reason.
Why does session output arrive without colour and screen updates?
A session is made for commands that read and print text. Oda strips control sequences and normalises line endings, so colour codes and cursor movement do not come through, and a program that draws a full-screen interface is outside this design.
Does what a session sets up carry into the next send?
Yes. The working folder, exported variables, defined functions and any program the session left running all persist from one send to the next. Only the end of the session clears them.