diff --git a/CHANGELOG.md b/CHANGELOG.md index 577fb2a..f00bb4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,9 +45,10 @@ - Upgraded the terminal stack to exact Ratatui 0.30.2, ratatui-core 0.1.2, tui-markdown 0.3.8, Crossterm 0.29.0, and unicode-width 0.2.2 versions. Dext carries a narrow exact-source ratatui-core compatibility patch for its - inline viewport; the real-PTY suite now gates streaming input, populated - resize bursts, whole-screen clears, cursor-query counts, replay bounds, and a - bounded completion wait that tolerates slower macOS CI hosts. + inline viewport; the real-PTY suite now starts each child with a controlling + terminal and gates streaming input, populated resize bursts, whole-screen + clears, cursor-query counts, replay bounds, and a bounded completion wait + that tolerates slower macOS CI hosts. - macOS Seatbelt profiles now allow both canonical `/private/...` scratch paths and their standard `/var` or `/tmp` aliases, keeping temp APIs confined and usable. @@ -62,6 +63,18 @@ project, user, or `DEXT_SHELVES_DIR` roots; direct pack roots and `DEXT_PACKS_DIR` are no longer discovery inputs. +- Replaced `/plan` with conversational planning turn policies. The objective + tracker now classifies planning/analysis-only prompts (including explicit + “don’t change anything” phrasing) and bare plan approvals (“go”, “proceed + with the plan”); Dext injects a matching advisory-only or + implementation-authorized turn policy into the volatile runtime status — + never the cached stable prompt — so weaker models get deterministic per-turn + structure without hard tool gating. Explicit mutation intent always + overrides advisory phrasing, question-phrased prompts are never read as + approvals, and mid-turn queued user updates re-evaluate the policy; + approval prompts and `/sandbox-profile read-only` remain the enforcement + layers. + ### Removed - Removed the completed repository-local `.auto` prompt-efficiency experiment scaffold and now ignore the entire root `.auto/` workspace. Dext runtime/build/CI and the user-owned autoresearch pack do not depend on those project experiment files. @@ -89,8 +102,13 @@ - Removed the subagent feature completely: `/subagent` slash command, `subagent-runtime` CLI subcommand, detached/inline runners, steering, quality gates, TUI state, session artifacts dir, and all associated - tests/fixtures. `/plan` preserved via a direct read-only planner. - Net -1544 lines. + tests/fixtures. Net -1544 lines. +- Removed the unused `/plan` slash command and its hidden read-only planner turn, + temporary agent-state swapping, duplicated CLI/TUI dispatch, completion entry, + welcome tip, and planner-only regression test. Planning is now an ordinary + conversation: ask Dext to inspect and propose a plan without editing, revise + it in context, then tell it to proceed. A former `/plan ...` input is no + longer intercepted and is delivered as a normal prompt. - Removed all repository-owned and embedded pack payloads. Dext ships the pack lifecycle and shelf integration, but no pack content; users own and distribute shelf repositories separately. diff --git a/Cargo.lock b/Cargo.lock index 7040de2..aa4edd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -736,9 +736,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "h2" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +checksum = "a9f37a958b41b3b19ee2707c06439c0e9e547e847223eb791ecb0cb821c65e27" dependencies = [ "atomic-waker", "bytes", @@ -1742,7 +1742,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1941,7 +1941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2499,7 +2499,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/DEXT.md b/DEXT.md index 8205109..c2a0b32 100644 --- a/DEXT.md +++ b/DEXT.md @@ -60,10 +60,23 @@ When changing Dext itself: ## Context files - `DEXT.md` is tracked project guidance and is auto-injected from the sandbox - root and its ancestors. Keep it terse and machine-facing. -- `recall.md` is an optional ignored prompt cache. It is auto-injected when - present, but Dext does not create or update it automatically. -- Do not create or update `recall.md` unless the user asks. + root and its ancestors. Keep it terse and machine-facing. DEXT.md is + human-authored policy; agents never edit it. +- `recall.md` is agent working memory, ignored by Git and auto-injected when + present. + +## Recall policy +- Create/update `recall.md` without asking, at task boundaries (task done, + correction received, gotcha resolved) — not mid-exploration. +- Hard cap ~4KB. To add when full, prune the least-valuable entry in the same + edit. +- One line per entry: date, tag `[fact]`|`[pref]`|`[proc]`|`[fix]`, session id. +- Declarative observations only — record what is true, never what to do. + Imperatives and instructions to future sessions are forbidden; DEXT.md alone + carries policy. +- Never write secrets, credentials, or personal data. +- New entries end with `?`. Strip the `?` only when a later session relies on + the entry and it holds. Delete entries the repo contradicts. ## Packs and shelves - Packs may optionally declare a reviewed `runtime.json` one-shot helper to expose dynamic tools, bounded state, continuation/steering effects, and markdown views; executable activation and write-risk calls retain approval, sandbox, credential-scrubbing, and checkpoint controls. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 83e99f4..4aaef29 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -45,7 +45,7 @@ Dext is a Rust terminal agent packaged as one binary. Most behavior is still int - Built-in GLM, ChatGPT/Codex, OpenAI, Anthropic, Kimi Code, DeepSeek, and local OpenAI-compatible profiles. - Live llama.cpp runtime context probing for the local provider; unavailable local servers fall back cleanly without aborting startup. - API-key, ChatGPT OAuth, and Anthropic Claude Pro/Max OAuth login flows; runtime auth retains whether a resolved secret is an API key or OAuth token. OAuth callback binding is loopback-only, accepted connections use blocking I/O under one two-second complete-header deadline, result pages wait for exchange/storage completion, exchange/refresh transport is bounded and redirect-free, and active OAuth credentials are rechecked at user-turn boundaries. - - Request builders for Anthropic, OpenAI-compatible, and ChatGPT/Codex response APIs. + - Request builders for Anthropic, OpenAI-compatible, and ChatGPT/Codex response APIs. Public adaptive Anthropic models (Sonnet 4.6, Sonnet 5, Opus 4.6/4.7/4.8, Opus 5, and Fable 5) omit `thinking.display`; transformed OAuth and API-key request fixtures verify the same adaptive shape. - Model alias normalization and provider/model switching helpers. - `src/claude_subscription.rs` @@ -132,7 +132,7 @@ Dext is a Rust terminal agent packaged as one binary. Most behavior is still int - `vendor/ratatui-core/` - Exact upstream `ratatui-core 0.1.2` source selected through `[patch.crates-io]`. - - Narrow inline-terminal fixes that avoid synchronous cursor-query stalls and whole-display clears during resize. + - Narrow inline-terminal fixes that avoid synchronous cursor-query stalls and extra whole-display clears before Dext's owned resize replay, plus an origin-reset primitive that clears the visible display before stale-width scrollback is purged so complete transcript reconstruction replays the intro exactly once. - Hunk rationale and refresh instructions in `vendor/ratatui-core/DEXT_PATCH.md`. ## Tool model @@ -279,6 +279,6 @@ cargo test --release --locked cargo test --release --locked --test tui_smoke -- --nocapture ``` -The TUI smoke suite launches the real compiled binary inside a pseudo-terminal. In addition to launch/help/exit coverage, it checks narrow and wide layouts, multiline input, live-stream input, resize survival, bounded cursor queries, zero whole-screen resize clears, and completed output after resize. Renderer changes also follow the live-terminal checks in [`TUI.md`](TUI.md). +The TUI smoke suite launches the real compiled binary inside a pseudo-terminal. In addition to launch/help/exit coverage, it checks narrow and wide layouts, multiline input, live-stream input, resize survival, bounded cursor queries, a visible-display clear before each paired scrollback purge, exactly one Dext intro per replay segment, terminal-height-bounded complete replay, and completed output after resize. Renderer changes also follow the live-terminal checks in [`TUI.md`](TUI.md). On Windows CI and release builders, the scheduler-sensitive `fast_bash_command_returns_without_100ms_poll_tail` regression runs alone after the remaining release tests. Its original `<90 ms` assertion remains unchanged; isolation prevents unrelated suite load from obscuring the process-wait regression it measures. The external-runner stdin-backpressure regression still requires bounded completion under the shared deadline, but accepts either the stdin-write or root-process timeout phase on Windows because pipe buffering can make the full write complete at the deadline boundary; Unix continues to require the stdin-write phase. The tool-call mock provider consumes its bounded `Content-Length` request body before responding so Windows does not reset the connection with unread request data. diff --git a/docs/RISK_REGISTER.md b/docs/RISK_REGISTER.md index b50f126..f71ae39 100644 --- a/docs/RISK_REGISTER.md +++ b/docs/RISK_REGISTER.md @@ -18,7 +18,7 @@ Priorities: **P1** needs planned mitigation before a stronger security/reliabili | R-010 | Privacy · local recovery · P3 | Low with normal Git push; medium with mirror/backup sharing | Medium | High | Checkpoint refs and owner-private sidecars/blobs may retain sensitive file content and symlink targets. Write-risk arbitrary-command checkpoints can preserve existing untracked entries within bounded limits. Mirroring `refs/dext/*`, copying full repository metadata, or sharing state backups can disclose it. Evidence: checkpoint storage in `src/git_checkpoints.rs` and warnings in `SECURITY.md`. | On Unix, checkpoint storage containers are current-user-owned, `.dext` is not group/world-writable, and managed checkpoint/sidecar/blob directories are owner-private; unsafe restore containers fail closed, prune retains unsafe blob entries and sidecar directory trees with bounded warnings, and orphan top-level sidecar symlinks are unlinked without traversal. Blobs are content-addressed and verified before/while restoring; current manifests record exact direct-sidecar membership, while ambiguous missing artifacts in older manifests fail before mutation; every manifest path is validated by one repo-relative rule that a row cannot opt out of; recognized retired rows require intact headers, complete retired field grammar, and live-ref OID matches; retention publishes the compacted manifest before deleting expired/retired refs or artifacts so cleanup failure leaves orphan state rather than a manifest naming deleted recovery points, while corruption or tampering fails closed; runtime manifest reads are capped at 16 MiB; cache reuse requires stable source/blob metadata fingerprints; `.dext/` is locally excluded; arbitrary-command inventory/capture is capped at 500 paths, 8 MiB/file, and 32 MiB/checkpoint; non-UTF-8/unsupported/capped entries require partial-recovery approval; failed creation cleans new blobs; automatic retention is 20 checkpoints/seven days and prunes valid unreferenced blobs; normal Git pushes do not include hidden refs; docs warn against mirror-pushing Dext refs. | Add an explicit sensitive-checkpoint inventory/prune workflow and optional checkpoint disable/exclude patterns · recovery/privacy owner · review when capture scope, retention, backup, or ref publication behavior changes. | | R-011 | Maintainability · architecture · P2 | High for routine core changes | Medium | High | `src/main.rs`, `src/tui.rs`, and the in-crate test surface remain large; unrelated runtime concerns still share broad compile/review boundaries. Evidence: module line counts and the responsibility map in `docs/ARCHITECTURE.md`. | Provider streaming, tool rounds/journal, checkpoints, mutation previews, sandbox, policy, pack runtime, packs, shelves, seats, sessions, and orchestration already have focused modules; the unused work-map/focus/track vertical slice and its TUI/event/test surface were removed rather than extracted; tool metadata has one registry for required fields and execution flags; release tests cover cross-module behavior. | Extract one stable seam at a time (HTTP tool, diagnostics, doctor, export, eval) with behavior-preserving tests; do not combine extraction with feature work · architecture owner · review when adding another substantial `main.rs` subsystem or when merge/compile cost blocks delivery. | | R-012 | Security · state · same-user concurrency · P2 | Low in normal private state; medium with a hostile same-user process | High | Medium | Seat reads/writes validate path components, ancestors, ownership, modes, links, and opened-file identity, but path-based ancestor validation and later open/rename are not one descriptor-relative transaction. A hostile same-user process can replace an ancestor after validation and redirect or disrupt Seat metadata/pointer operations. Evidence: `src/seats.rs` ancestor validation and atomic path replacement. | Portable ids; owner-safe Unix state ancestors; owner-private managed directories; no-follow single-link record reads; inode revalidation; bounded schema/content; cross-process operation lock; atomic secret-file replacement; transactional reset rollback attempt; documented same-user boundary. | Use descriptor-relative no-follow traversal and handle-relative atomic replacement for the complete Seat path, or place Seat operations inside an OS-isolated trusted state service · state/security owner · review on Seat path changes or any state-redirection incident. | -| R-013 | Reliability · provider compatibility · P1 | High when Anthropic changes its private Claude Code contract | High for affected subscription users | High | Claude Pro/Max routing depends on an unofficial, version-specific OAuth and request shape that Anthropic can change without API compatibility guarantees; provider terms may also restrict third-party subscription clients. Evidence: pinned Claude Code 2.1.224 constants and billing/checksum/header construction in `src/claude_subscription.rs`. | Compatibility applies only to typed OAuth credentials on the marked built-in Anthropic profile at the exact official base URL; API keys, custom endpoints, GLM, and Kimi bypass it; malformed body shapes fail closed; OAuth callback binding is loopback-only, accepted connections use blocking I/O, and complete request headers/state are validated under one two-second total deadline; exchange/refresh uses bounded redirect-free transport, rechecks active OAuth expiry per user turn, and preserves refresh rotation; fake-transport/vector tests cover fingerprints, checksum, headers, identity validation, callback outcomes, refresh persistence, and provider isolation; docs disclose unofficial status and terms responsibility. | Revalidate OAuth endpoints/scopes and public wire vectors against each supported Claude Code contract before changing the pin; disable or update the route on provider rejection rather than adding permissive fallback shaping · provider/security owner · every Claude compatibility change or authentication incident. | +| R-013 | Reliability · provider compatibility · P1 | High when Anthropic changes its private Claude Code contract | High for affected subscription users | High | Claude Pro/Max routing depends on an unofficial, version-specific OAuth and request shape that Anthropic can change without API compatibility guarantees; provider terms may also restrict third-party subscription clients. Evidence: pinned Claude Code 2.1.224 constants and billing/checksum/header construction in `src/claude_subscription.rs`. | Compatibility applies only to typed OAuth credentials on the marked built-in Anthropic profile at the exact official base URL; API keys, custom endpoints, GLM, and Kimi bypass it; malformed body shapes fail closed; OAuth callback binding is loopback-only, accepted connections use blocking I/O, and complete request headers/state are validated under one two-second total deadline; exchange/refresh uses bounded redirect-free transport, rechecks active OAuth expiry per user turn, and preserves refresh rotation; fake-transport/vector tests cover fingerprints, checksum, headers, identity validation, callback outcomes, refresh persistence, provider isolation, OAuth-transformed adaptive request fields, API-key parity, and visible thinking-delta/signature round trips; docs disclose unofficial status and terms responsibility. | Revalidate OAuth endpoints/scopes and public wire vectors against each supported Claude Code contract before changing the pin; disable or update the route on provider rejection rather than adding permissive fallback shaping · provider/security owner · every Claude compatibility change or authentication incident. | ## Review protocol diff --git a/docs/TUI.md b/docs/TUI.md index a4bbda6..1c1ae26 100644 --- a/docs/TUI.md +++ b/docs/TUI.md @@ -1,20 +1,24 @@ # Terminal UI -Dext's interactive interface is an inline Ratatui application in the regular terminal buffer. It preserves native terminal scrollback instead of taking over the alternate screen. The backend viewer is the only alternate-screen surface. +Dext's interactive interface is an inline Ratatui application in the regular terminal buffer. It uses native terminal scrollback during ordinary operation instead of taking over the alternate screen. On every effective transcript-pane width change, Dext deliberately replaces that scrollback immediately with a complete replay at the new width. The backend viewer is the only alternate-screen surface. ## Behavior contract TUI and dependency changes must preserve these behaviors: - The main interface remains an inline viewport in the regular terminal buffer. -- Completed transcript output remains in native terminal scrollback. +- Completed transcript output remains in native terminal scrollback during ordinary operation. Every effective transcript-pane width change immediately purges stale-width terminal history and rebuilds Dext's complete logical transcript; pre-Dext shell scrollback is intentionally not preserved by that rebuild. - The settled banner, transcript, composer, status rows, expansion state, spacing, and styling change only through explicit TUI work, never merely because dependencies changed. - The startup welcome stays in inline transcript scrollback, starts with one transcript-owned blank separator row below CLI diagnostics, and uses a compact four-zone layout: a Dext/version brand row, an adaptive working-directory and cached Git summary at 80 columns or wider, exactly two Model/Approval facts between rules, and one rotating tip drawn from verified TUI features. Width calculations and truncation use terminal cell width, and the Git probe runs off the render loop with only an 8 ms startup wait before falling back to path-only rendering. -- The empty composer prompt is `❯ Type a request… @ files · / commands`; typing, login, permission, and paste-preview behavior retain their existing paths. Slash completion mirrors the canonical handled commands, including `/privacy`, `/preview`, `/context`, `/tool-profile`, `/diagnostics`, `/shelves`, `/project-extensions`, and `/undo`. +- The empty composer prompt is `❯ Type a request… @ files · / commands`; typing, login, permission, and paste-preview behavior retain their existing paths. Slash completion mirrors the canonical handled commands, including `/privacy`, `/preview`, `/context`, `/tool-profile`, `/diagnostics`, `/shelves`, `/project-extensions`, and `/undo`. `/login` completion shows every provider id exactly once and suppresses duplicate numbered-selector entries. +- Structured slash listings use the established `/sessions` hierarchy: count and section headers, two-space names, four-space details, and detached `Use:` footers. Dense name/description catalogs such as `/help` use aligned rows at 64 columns and wider and fall back to the stacked hierarchy when narrow. The TUI supplies its actual transcript-pane width; output keeps a two-cell gutter and a 120-column readability cap. `/system` preserves source/prompt paragraphs, blank lines, and leading indentation while wrapping prose. Dynamic fields are sanitized before layout; every physical row is bounded by Unicode display cells, with `?` replacing only a grapheme that cannot fit in an otherwise impossible one-cell measure. An explicit structured-slash event retains those layouts even when ANSI color is disabled. Generic slash confirmations, including `/model` and thinking-effort status, retain the faded info treatment. - Frugal mode applies the stricter pseudo-tool-protocol sanitizer to partial-stream recovery, completed transcript/thinking blocks, live details, and the inspector: serialized or multiline tool-call-like assistant payloads are replaced with `[tool call redacted; waiting for structured tool event]` while surrounding prose remains visible. Standard mode retains the narrower legacy line detector. - The main status row shows the exact `main` branch label as `Main`, including `Main (dirty)` when the working tree is dirty, without renaming the branch or changing any other branch casing. It keeps a live cumulative agent-active elapsed clock at its right edge while Dext works; the clock pauses and hides while Dext is idle awaiting input. +- Anthropic thinking deltas are retained in the provider event stream and finalized with their signatures for tool-loop replay. The TUI shows live and completed thinking only while verbose display is enabled (the default); toggling verbose hides it without changing stored provider blocks. `stream-json` exposes thinking events, while console text and final JSON omit thinking content. - Input and the viewport remain responsive while output streams and while the terminal is resized. -- Resize replay is cohesive: no item-by-item reconstruction, whole-screen flash, cursor-query stall, or cursor-query timeout. +- Resize replay follows a full-ownership model. On every effective transcript-pane width change, Dext uses one synchronized update to clear the visible display and reset the inline viewport to the origin without a cursor query, purge stale-width scrollback, and immediately rebuild the complete logical transcript at the observed width before appending pending output. Clearing before purging removes the still-visible old intro before logical history replays it once. There is no quiet-settle debounce, visible-suffix overwrite, or short-history exception. This removes mixed old/new wrapping, duplicate transcript copies, and width/height-shrink bookkeeping edge cases; the deliberate tradeoffs are complete replay work during resize bursts and replacement of pre-Dext shell scrollback. +- Pending permission prompts render inside the inline viewport, never into scrollback; only the compact decision line is appended once resolved. Approval prompts and decisions must not trigger a full-history re-emit. +- Pending transcript insertion keeps an already prepared failed batch separate from newly queued raw output. A retry reuses that prepared batch without regrouping or reranking it; new output is prepared only after the retry succeeds. - The backend viewer remains the only alternate-screen surface. - `Ctrl+L` opens a read-only todo modal in the inline UI; it never enters the alternate screen and remains available during ordinary idle or busy work. Permission and local-auth prompts intentionally retain input and rendering priority. @@ -52,11 +56,12 @@ Unmodified Ratatui 0.30.2 regressed Dext's inline experience. Its fallback `inse Enabling Ratatui's `scrolling-regions` feature was rejected because it changed settled rendering and expanded the backend dependency graph. -Dext patches the exact upstream `ratatui-core 0.1.2` source through `[patch.crates-io]`. The patch is limited to three inline-terminal corrections: +Dext patches the exact upstream `ratatui-core 0.1.2` source through `[patch.crates-io]`. The patch is limited to four inline-terminal corrections: 1. `Terminal::clear` preserves Ratatui's tracked cursor position instead of synchronously querying the backend. 2. Fallback `insert_before` clears the viewport directly rather than calling the cursor-preserving public clear. 3. Horizontal shrink avoids `ClearType::All` for inline viewports; the normal viewport clear and full next draw remain in place. +4. `Terminal::reset_inline_viewport` clears the visible display, resets both diff buffers, and anchors an inline viewport at the terminal origin without querying the cursor. On every effective transcript-pane width change, Dext calls it before Crossterm purges stale-width scrollback, then replays its complete logical transcript once at the observed width. The vendored source and hunk-level rationale live under `vendor/ratatui-core/`. This is a narrow compatibility patch, not a renderer fork. Remove it when a released upstream version satisfies the same regression gate without changing settled behavior. @@ -68,23 +73,24 @@ Run the complete renderer gate after any TUI or terminal dependency change: cargo fmt --all -- --check cargo clippy -p dext --all-targets --all-features --locked --no-deps -- -D warnings cargo audit --deny warnings +cargo deny check licenses cargo test -p ratatui-core --lib --locked cargo build --release --locked cargo test --release --locked cargo test --release --locked --test tui_smoke -- --nocapture ``` -The PTY smoke suite exercises the real binary and requires: +The PTY smoke suite starts each Dext child in a fresh session with the slave PTY as its controlling terminal and applies resize geometry through that slave endpoint, matching real terminal resize delivery on macOS and Linux. Resize assertions wait for the replay marker with a bounded deadline rather than assuming a fixed scheduler delay on shared CI hosts. It exercises the real binary and requires: - banner and composer visibility at narrow and wide sizes; - editable input during live streaming; - process survival and responsive input through a populated-history resize burst; -- zero whole-screen clears during inline resize; +- one visible-display clear before one scrollback purge for every effective populated-transcript width change, followed immediately by a complete logical-transcript replay at the observed width with exactly one Dext intro; +- repeated frames at the same width do not rebuild, while simultaneous width/height shrink still reconstructs the complete transcript from the origin; - cursor queries bounded by resize events rather than transcript size; -- terminal-height-bounded replay chunks; -- completed stream output and accepted input after resize, with a bounded 10-second completion wait so slower macOS CI hosts do not create false negatives. +- replay chunks bounded by terminal height, with pending output appended only after reconstruction; -Before releasing a renderer/backend update, also perform a live WSL2 check because ConPTY latency and perceptual flicker cannot be fully modeled by the Linux PTY. Resize a populated streaming session repeatedly and reject any visible replay, flash, input stall, scrollback loss, or mode-switching change. Native Linux and tmux checks are also recommended when terminal behavior changes. +Before releasing a renderer/backend update, also perform a live WSL2 check because ConPTY latency and perceptual flicker cannot be fully modeled by the Linux PTY. Resize a populated streaming session repeatedly and reject any crash, input stall, mixed-width or duplicate history, unexpected scrollback loss outside the documented full-ownership rebuild, or mode-switching change. Full replay during each observed width change and loss of pre-Dext shell scrollback are documented tradeoffs, not regressions. Native Linux and tmux checks are also recommended when terminal behavior changes. ## Dependency maintenance diff --git a/docs/USAGE.md b/docs/USAGE.md index a38c99d..4d8d08a 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -138,6 +138,8 @@ The OAuth-backed `chatgpt` provider remains on the Codex Responses contract. Its Built-in input/cached-input/output prices per million tokens are Sol `$5/$0.50/$30`, Terra `$2.50/$0.25/$15`, and Luna `$1/$0.10/$6`; above 272,000 input tokens, Dext applies the documented 2× input/cache and 1.5× output tier unless explicit pricing overrides are set. +The built-in Anthropic catalog enables adaptive thinking for Sonnet 4.6, Sonnet 5, Opus 4.6/4.7/4.8, Opus 5, and Fable 5. These requests carry the selected output effort and omit `thinking.display`, allowing the provider stream to include thinking deltas. The transformed official OAuth request and the API-key request retain the same adaptive fields. `xhigh` effort maps natively on Sonnet 5, Opus 4.7/4.8, Opus 5, and Fable 5; `max` additionally covers Sonnet 4.6 and Opus 4.6; unsupported extended levels downgrade to `high`. Sonnet 5, Opus 5, and Fable 5 declare 1,000,000-token context windows; other Claude models keep the 200K fallback. Built-in input/cache-read/output prices per million tokens are Sonnet 5 `$2/$0.20/$10`, Opus 4.5–4.8 and Opus 5 `$5/$0.50/$25`, earlier Sonnet `$3/$0.30/$15`, Fable 5 `$10/$1/$50`, and Opus 4.1-and-earlier `$15/$1.50/$75`; Anthropic documents standard per-token rates across the full 1M window for these models, so no long-context tier applies. TUI visibility remains a presentation choice: verbose display shows thinking, `stream-json` emits thinking events, and console text/final JSON omit thinking content. + The built-in Kimi Code catalog uses Anthropic Messages semantics at `https://api.kimi.com/coding`, defaults to K3, and reports zero incremental token cost because access is covered by the coding plan. Verified K3 metadata enables adaptive thinking with `max` effort and preserves empty thinking signatures required by that model; these compatibility rules do not apply to generic/custom Anthropic profiles. ## Local Qwen / llama.cpp @@ -173,6 +175,8 @@ Start Dext: dext ``` +Planning is conversational, not a mode. Ask for a plan (“plan the refactor”, “review this for bugs, don’t change anything”) and Dext applies an advisory-only turn policy: read-only tools and a structured Goal/Findings/Steps/Risks answer. Revise the plan in the same thread, then approve it (“go”, “proceed with the plan”) and Dext converts the agreed steps into todos and executes them. The policy steers the model; approval prompts and `/sandbox-profile read-only` remain the hard enforcement layers. + Useful slash commands: ```text diff --git a/docs/index.html b/docs/index.html index f699ba3..9590a40 100644 --- a/docs/index.html +++ b/docs/index.html @@ -439,7 +439,7 @@

The agent that lives in your terminal.

Dext — Technical Documentation

Dext is a single-binary Rust coding agent that runs from your terminal. It keeps project-scoped session state and gives the model a curated set of native tools for filesystem operations, search, shell execution, data processing, HTTP requests, Git operations, and task tracking.

Dext is source-first: prompts, runtime state, tool policies, provider wiring, and the TUI all live in the repository with no external service required beyond your chosen model provider.

-
Explicit continuity, not autonomous memory: By default, Dext autosaves session state under a project-specific key, but restores it only when you use --resume or a session command. Optional recall.md and Seat summaries are user-authored context; --no-session disables durable session/log writes.
+
Policy-governed continuity: By default, Dext autosaves session state under a project-specific key, but restores it only when you use --resume or a session command. recall.md is bounded agent working memory: project DEXT.md policy decides whether the agent maintains it, and every native write stays inside normal tool approval, mutation preview, checkpoint, 4 KiB size, and privacy-redaction controls. Seat summaries are user-authored context; --no-session disables durable session/log writes.
Canonical documentation: this GitHub Pages site is the main technical reference and is deployed from docs/ after each reviewed change to main. Focused Markdown guides remain supplemental. Open non-documentation risks are tracked in the risk register.
Developer verification: run cargo fmt --all -- --check, Clippy with warnings denied, cargo audit --deny warnings, cargo deny check licenses, the vendored ratatui-core tests, release build/tests, and the PTY smoke suite. Reinstall with cargo install --path . --force --locked so the binary on PATH matches the source. Renderer-specific requirements are documented in docs/TUI.md.
@@ -647,7 +647,7 @@

Main.rs — Agent Core