1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// SPDX-FileCopyrightText: 2026 conpty-oxide contributors <https://github.com/P4suta/conpty-oxide/graphs/contributors>
//
// SPDX-License-Identifier: MIT OR Apache-2.0
//! Correctness-first Windows `ConPTY` (pseudoconsole) library.
//!
//! `conpty-oxide` wraps the Windows pseudoconsole (`ConPTY`) API with a focus on
//! getting the hard parts right:
//!
//! - A well-defined EOF contract for the console output pipe.
//! - No hangs around `ClosePseudoConsole`.
//! - Reliable process-tree termination ("kill tree") via Job objects.
//! - A blocking API (default `blocking` feature) and an async API behind the
//! `tokio` feature.
//! - Dynamic loading of `conpty.dll`, falling back to the system console API.
//!
//! This crate targets Windows exclusively and does not compile on other
//! platforms.
//!
//! Low-level lifecycle types, backend identity, and unchecked bundle loading
//! are intentionally not part of the 0.1 contract. Errors are opaque — there
//! are no variants to match — and [`Result`] always uses this crate's error.
//! Hidden compile-fail doctests pin each of these boundaries.
//!
//! # Where to start
//!
// The two paragraphs below are feature-gated so their intra-doc links always
// point at something that exists: neither front end is guaranteed to be
// compiled in, and a link into a module that was configured out is a rustdoc
// error rather than a dead link.
//! # Feature flags
//!
//! - `blocking` (default) — the synchronous frontend.
//! - `tokio` — the asynchronous frontend on Tokio.
//! - `tracing` — diagnostics through the `tracing` crate; never changes the
//! public API or any behavior.
//!
//! The features can be combined.
//!
//! # Managed sessions
//!
//! A managed session is bounded by its root process. Once the root's real exit
//! status is saved, descendants remaining in the session Job are terminated
//! and the output tail proceeds to EOF. Splitting with `into_parts` changes
//! ownership only; it does not detach the process tree.
//!
//! Input drop or shutdown ends the terminal session rather than delivering an
//! ordinary stdin EOF. Output is one raw UTF-8/VT byte stream with no separate
//! stdout and stderr channels. `collect_output` retains an unbounded amount of
//! output; use `wait` to discard it safely or owned parts to stream it.
//!
//! # Choosing a `ConPTY` implementation
//!
//! Automatic selection needs no setup: it prefers a validated standalone
//! `conpty.dll` bundle next to the executable, then falls back to the operating
//! system's `ConPTY`. An application can also select a bundle explicitly to get
//! the newer console host's behaviour on older Windows versions:
//!
//! - [`ConPtyBackend::auto`] uses a valid bundle found next to the executable,
//! falls back to the system implementation when that bundle is rejected,
//! and returns an error if neither is usable. This is also what the default
//! backend selection does.
//! - [`ConPtyBackend::from_dir`] loads a bundle from a directory you name,
//! validating that its `conpty.dll` and `OpenConsole.exe` are a matching
//! pair before either runs.
//! - With either frontend enabled, `SessionOptions::backend` selects a backend
//! for a managed session.
//!
//! Cursor inheritance, manual EOF policy, detached sessions, and pre-staged
//! spawning are intentionally outside the 0.1 API. They can be added later as
//! typed advanced operations when concrete use cases justify them.
// `cargo test --doc` normally inspects only Rust source, not README.md. Under
// the all-frontend configuration used by CI, append the README while rustdoc
// is collecting tests so its blocking, Tokio, and low-level snippets are the
// exact text compiled. It is omitted from ordinary API documentation and from
// single/no-frontend doctest legs, where one of those snippets is intentionally
// unavailable.
// docs.rs passes `--cfg docsrs` (see `[package.metadata.docs.rs]`), which
// turns on the nightly-only `doc_cfg` feature: every feature-gated item then
// carries an "Available on crate feature … only" badge. Stable builds never
// see the cfg, so this is inert everywhere else. (The badges used to need a
// separate `doc_auto_cfg` feature; that was merged into `doc_cfg` and removed
// in 1.92 — rust-lang/rust#138907 — so naming it here breaks the docs.rs
// build.)
// Every public item carries documentation, and this keeps it that way under
// every driver — `cargo rustc`, rustdoc, rust-analyzer — including invocations
// where Cargo does not forward the workspace lint table.
compile_error!;
pub use ;
pub use ConPtyBackend;
pub use ;
pub use Size;
pub use ExitStatus;
/// The API boundaries stated in the crate docs, pinned as compile-fail
/// doctests so a widened surface fails `cargo test --doc` instead of
/// shipping. The module exists only while rustdoc collects doctests, so
/// none of these render as examples.
///
/// Low-level lifecycle types stay private:
///
/// ```compile_fail
/// use conpty_oxide::blocking::Pty;
/// ```
///
/// ```compile_fail
/// use conpty_oxide::tokio::PtyBuilder;
/// ```
///
/// Backend identity and unchecked bundle loading stay private:
///
/// ```compile_fail
/// use conpty_oxide::BackendKind;
/// ```
///
/// ```compile_fail
/// let backend = conpty_oxide::ConPtyBackend::from_dir_unchecked(".");
/// ```
///
/// Errors stay opaque and the result alias keeps this crate's error:
///
/// ```compile_fail
/// fn inspect(error: conpty_oxide::Error) {
/// match error {
/// conpty_oxide::Error::Io(_) => {}
/// }
/// }
/// ```
///
/// ```compile_fail
/// type ForeignResult = conpty_oxide::Result<(), std::io::Error>;
/// ```