Terminal observation
Agent providers receive bounded facts and opaque handles for one terminal’s exact environment. Handles cannot be reused in another terminal and paths never become arbitrary filesystem authority.
Terminal context
| Member | Type | Meaning |
|---|---|---|
terminal, project, environment, process | Opaque handles | Terminal-scoped identities; only their id is observable. |
foreground | { executableName, arguments?, startedAt? } | Bounded facts for the foreground process. |
tty | { deviceId, deviceName? } | Present only when the host can prove the registered PTY’s TTY. |
capabilities | ReadonlySet<AgentObservationCapability> | Granted process-observation, filesystem-observation, and/or agent-journal capabilities. |
signal | CancellationSignal | Use it in every broker operation. It has aborted and throwIfAborted(). |
Process facts
| Method | Return value |
|---|---|
processes.descendants({ signal? }) | Promise<AgentProcessSnapshot[]>; each snapshot has an opaque handle, executable name, optional start time, and optional working directory. |
processes.openFiles(processes, { access, signal? }) | Promise<AgentOpenFile[]>; accepts snapshots or handles, access is readable or writable, and returns a file handle, safe display path, and access fact. |
processes.environment(names, { signal? }) | Promise<Record<string, string>>. Names must have been declared in requiredEnvironmentVariables; values come only from the foreground process or descendant, never Node’s ambient environment. |
Discover journal files
TypeScript
const root = await terminal.observation.files.resolveHomeDirectory('.codex');
if (!root) return { state: 'not-bound' };
const files = await terminal.observation.files.listDirectory(root, {
extensions: ['.jsonl'],
maxDepth: 2,
maxEntries: 100,
maxBytes: 5_000_000,
signal: terminal.signal,
});
const journal = files.entries.at(-1);
if (!journal) return { state: 'not-bound' };
const source = await terminal.observation.files.follow(journal.handle, {
signal: terminal.signal,
maxChunkBytes: 64 * 1024,
});| Method | Return value |
|---|---|
files.resolveHomeDirectory(relativePath, { beneath?, signal? }) | An opaque directory root beneath the environment home, or undefined. |
files.resolveDirectoryRelativeToEnvironment(relativePath, { environmentVariable, beneathRelative?, signal? }) | An opaque directory root beneath a declared process environment value, or undefined. |
files.listDirectory(root, options) | A snapshot: { entries, truncated }. Every entry has a file handle, non-escaping relative path, size, and modification time. |
files.watchDirectory(root, options) | An async iterable disposable directory watcher. The first item is the current snapshot; later items arrive only after a change. |
Directory options always require extensions (at least one suffix),
maxDepth, maxEntries, and maxBytes; they can include signal.
The host reports truncated: true when a declared limit stopped discovery.
Resolve and inspect files
| Method | Constraint |
|---|---|
resolveRelativeToEnvironment(relativePath, { environmentVariable, extension?, signal? }) | Known, non-escaping path beneath a declared environment variable. |
resolvePathUnderEnvironment(providerPath, { environmentVariable, beneathRelative?, extension?, signal? }) | Canonicalizes provider-record path data only under that environment value. |
environmentRelativePath(handle, { environmentVariable, beneathRelative?, signal? }) | Returns a normalized relative-path fact, not read authority. |
resolveHomeRelative(relativePath, { beneath?, extension?, signal? }) | Known, non-escaping file under environment home. |
resolvePathUnderHome(providerPath, { beneath: { homeRelative }, extension?, signal? }) | Canonicalizes provider-record path data below an explicit home root. |
homeRelativePath(handle, { beneath: { homeRelative }, signal? }) | Normalized home-relative path fact, not a usable path authority. |
canonicalFile(handle, { beneath?, extension?, signal? }) | Canonical regular file handle or undefined. |
realpath(handle, { signal? }), stat(handle, { signal? }) | A canonical file handle, or a file stat (kind: 'file', size, modification time), respectively. |
Read and follow a file
| Method | Return value |
|---|---|
files.read(handle, { maxBytes, signal? }) | Bounded Uint8Array. |
files.readJson<T>(handle, { maxBytes, signal? }) | Parsed T or undefined. |
files.readJsonLine<T>(handle, { maxBytes, position: 'first' | 'last', signal? }) | One parsed JSONL record or undefined. |
files.follow(handle, { maxChunkBytes?, signal? }) | Disposable async iterable watcher. Chunks are { type: 'append' | 'replace' | 'truncate', bytes }; the host may lower the requested chunk size. |
The broker provides no shell, PTY, arbitrary absolute path, directory traversal, or direct host filesystem access. Use only the opaque handles it issues.