Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Notable changes to Bake. `/changelog` in the terminal prints the section for the

## [Unreleased]

## [0.3.1] - 2026-09-30

- `/settings` opens straight on its most general section, Terminal, instead of a list of sections. The sections run from most general to most specific on the tab row under the title: Terminal, Session, Agent, Shell, Web search, and Advanced. Tab and Shift-Tab move between them, and Escape from a section closes the panel. Typing on any section searches every setting, and a setting changed from another section's results opens that section with the changed row selected.
- Native Windows consoles, including the classic console host and editor terminals, draw the rounded frame instead of the ASCII one. Node writes to them as UTF-16, so the missing locale and `TERM` variables no longer mean the frame cannot be drawn. A Chinese, Japanese, or Korean system locale still selects the ASCII frame outside Windows Terminal, because the console host draws its line characters two cells wide there.

## [0.3.0] - 2026-10-01

- `edit` no longer needs a prior `read`. A replacement whose `old_string` matches the current file exactly once is applied, even if the file changed since it was read, and changes elsewhere in the file are kept. When the model had not seen that content, the result shows the edited lines. `replace_all` and `write` still require a current read. `edits: [{ old_string, new_string }]` applies several changes to one file in one atomic call. A failed match names a whitespace-insensitive near match or lists the matching lines. `fs-observation-policy.editGuard: version` restores the old refusal.
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@deepseek-ai/dsh",
"description": "dsh CLI: profile launch, plugin management, and configuration inspection",
"version": "0.3.0",
"version": "0.3.1",
"publishConfig": {
"access": "public"
},
Expand Down
2 changes: 1 addition & 1 deletion apps/tui/DESIGN-LAYOUT.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ The composer's rule and the divider that opens each turn are full-width runs of
- One that is **not encoding UTF-8** writes the bytes through as mojibake, so the frame becomes punctuation on every row.
- One configured to draw **East Asian Ambiguous** characters two cells wide draws a full-width horizontal run at twice the width Ink measured. The frame wraps, and Ink's own row arithmetic is wrong from then on — this is the damaging case. Every other Ambiguous character on this surface (the turn marker, the selection pointer, the caret) sits alone in a fixed-width rail, where a terminal that draws it wide shifts one row by one column; a border run accumulates that error across the whole line.

`resolveFrame` in `packages/app/src/frame.ts` decides once, before the first frame, and `@dsh-tui/ui` takes the answer as a prop — the presentation layer reads no environment. Encoding and `TERM` come from `LC_ALL`/`LC_CTYPE`/`LANG` in POSIX order; Windows Terminal sets neither but draws UTF-8, so its `WT_SESSION` stands in for both. Ambiguous width is a terminal *preference* and cannot be detected, so a CJK character locale (or `--locale zh`) stands in for it. `composerFrame` in the profile overrules the lot, which is the only answer for a terminal the environment describes wrongly.
`resolveFrame` in `packages/app/src/frame.ts` decides once, before the first frame, and `@dsh-tui/ui` takes the answer as a prop — the presentation layer reads no environment. Encoding and `TERM` come from `LC_ALL`/`LC_CTYPE`/`LANG` in POSIX order; Windows Terminal sets neither but draws UTF-8, so its `WT_SESSION` stands in for both. Native Windows needs neither: Node writes to the console as UTF-16 whatever the code page, so every Windows console draws the frame. Ambiguous width is a terminal *preference* and cannot be detected, so a CJK character locale (or `--locale zh`) stands in for it; outside Windows Terminal, Windows names that locale in the system rather than the environment, and its console host draws Ambiguous characters wide under a CJK code page. `composerFrame` in the profile overrules the lot, which is the only answer for a terminal the environment describes wrongly.

The ASCII fallback is laid out against the same widths and spends the same rows.

Expand Down
4 changes: 2 additions & 2 deletions apps/tui/packages/app/README.i18n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write apps/tui/packages/app/README.md
README.md: 3fc43a29f47db2ab7e297bcc0175c4cd7a812a37
README.zh.md: 4c5e6f9dcdb5c77b6968c58b21e0bfa6bda4b5a6
README.md: 48af4f91845c3f6e8c43938b728c47d986f501ce
README.zh.md: a6829d328ae90d1e3cbb35ac50185362079615cc
2 changes: 1 addition & 1 deletion apps/tui/packages/app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ bun run start

Use `bun run start --screen fullscreen` (or `bake --screen fullscreen` in an install) for a scrollable transcript with the input pinned at the bottom. The mouse wheel moves three rows, PgUp/PgDn move half a viewport, Ctrl+Home goes to the beginning, and Ctrl+End returns to the newest output. Scrolling up pauses following while new output arrives; scrolling back to the bottom resumes it. While paused, the row above the input leads with `↓ Latest · Ctrl+End`, which turns to `↓ New output · Ctrl+End` once output arrives below the view; clicking it also returns to the newest output. Fullscreen reports the mouse to Bake, so select text with Shift-drag, or Option-drag on macOS. Open sheets and selection panels keep their own navigation keys. Resizing rewraps visible history, and exit restores the shell screen and cursor. `--screen inline` uses native terminal scrollback and is the default; `INK_SCREEN_READER=true` also selects inline mode. Fullscreen has no transcript search yet.

`/settings` opens a panel of settings, saved in the settings file (`~/.bake/settings.yaml`) section by section; the terminal's own are in its `tui` section, where the `tui-runner` profile values are the defaults under the user's. The panel's first page lists sections, each with its values or what it holds: Session (the default model and, when the permission plugin is mounted, the default access preset, both marked `New sessions`), Terminal (the screen mode, inline by default or fullscreen, language, borders, whether the goal's objective is named on the header, tool output lines, menu rows, and the Ctrl+C quit window), then, when the composition registers them, Agent (parallel tool calls, subagents running at once, subagent nesting depth, whether subagents may pick a model, the models they may pick, and, once they may, Auto routing (beta)), Shell (the command timeout, the longest timeout a command may ask for, and the command output kept in memory), and Web search (searches per request, the search model, and its answer token limit). Advanced lists every registered settings namespace but `tui` and edits each field from the schema its plugin registered: on/off fields flip, constants are picked from a list, numbers and text are typed, secrets are typed masked and shown only as `Set` or `Not set`, and lists and maps open as JSON in `$VISUAL`, then `$EDITOR`, then `vi` (Notepad on Windows). The editor has the terminal until it exits, and the panel is drawn again after it; JSON with comments is accepted, and text that does not parse or an editor that exits non-zero leaves the value unchanged with the reason shown. The models subagents may pick come from the same catalog `/model` lists: Enter adds or removes one, each change is saved at once, and `Done` or Escape returns. The subagent plugin refuses the choice switched on with no model allowed, so switching it on from an empty list asks for the models first and saves both together, and the last model is kept while the choice is on. Auto routing (beta) lets the task router pick one of those models, and its reasoning effort, for a delegation that names none. Switching it on first says what it sends: each such delegation's task text and the names of the allowed models go to the router's URL, the hosted ing router by default, while the user's own providers still run every model. It also says when Bake is not signed in to the router, and then offers `Sign in and turn on` first; Enter on `Turn on` saves it without signing in. While it is on, the Agent section also offers Router account, the router's URL, the routing priority (`From the task` by default, or quality, cost, speed, or balanced), and Model calibration. Calibration asks the router how it sees each allowed model: the benchmarked model it matched or `unknown to the router`, its quality score, its price per million tokens, and `Ranked` or `Needs a hint`. Enter on a model sets its quality tier, its cost tier, or the benchmarked model it serves, each saved at once, and the list is asked again after every change. A quality tier set on a model the router has benchmarks for is marked as unused, since benchmarks win. When no model is ranked, the list warns that routed delegations keep the default model; a router that cannot be reached shows why. Router account signs in by email: it asks for an address, the router emails a six-digit code, and the code typed next is traded for a token the credential store keeps, so routed delegations send it from then on. A first sign-in creates the account. A refused address or code is shown on the field and asked again, and Escape leaves the stored token as it was. Signed in, the row names the account, and Enter offers signing in with another email or signing out. When the launch environment supplies the token, the row names its variable instead and signing in is not offered. Every write names only its field, so a secret the panel never showed is never lost. Typing on the first page searches every setting in every section, named by where it lives (`Shell › Command timeout`), and Enter edits the one found. Up/Down choose, Enter opens a section, a value list, or flips an on/off setting, Tab and Shift-Tab move to the next or previous section, named on a row of tabs under the title, and Escape returns to the page above and closes the panel from the first. A value list marks the value in force as `Current` and the default as `Default`, and ends with `Enter a value…` where the setting takes a typed one: durations accept `500ms`, `30s`, `2m`, or `1h`, sizes `64KB` or `1MB`, and a value outside the setting's bounds is refused with the bound it breaks. A setting the user has set also offers a pinned `Reset to default`, and a section with any offers `Reset this section to defaults` after a confirmation that defaults to keeping them. Screen mode and language apply at the next launch, and the panel marks them `Next launch` until then, as it does every field of a namespace whose plugin reads it only at start; `--screen`, or a `screen` set in the profile, overrides the saved screen, which the panel marks `Set by --screen`. The others apply at once, including edits made to the file by hand. A failed save, including a value the owning plugin refuses, shows its reason at the top of the panel and leaves the panel open. Closing the panel after a change names the file it was saved to. Without a settings file, only Session and Terminal are offered, and the panel says the changes last until exit.
`/settings` opens a panel of settings, saved in the settings file (`~/.bake/settings.yaml`) section by section; the terminal's own are in its `tui` section, where the `tui-runner` profile values are the defaults under the user's. The panel opens on its first and most general section, with every section named on a row of tabs under the title, most general first: Terminal (the screen mode, inline by default or fullscreen, language, borders, whether the goal's objective is named on the header, tool output lines, menu rows, and the Ctrl+C quit window), Session (the default model and, when the permission plugin is mounted, the default access preset, both marked `New sessions`), then, when the composition registers them, Agent (parallel tool calls, subagents running at once, subagent nesting depth, whether subagents may pick a model, the models they may pick, and, once they may, Auto routing (beta)), Shell (the command timeout, the longest timeout a command may ask for, and the command output kept in memory), and Web search (searches per request, the search model, and its answer token limit). Advanced lists every registered settings namespace but `tui` and edits each field from the schema its plugin registered: on/off fields flip, constants are picked from a list, numbers and text are typed, secrets are typed masked and shown only as `Set` or `Not set`, and lists and maps open as JSON in `$VISUAL`, then `$EDITOR`, then `vi` (Notepad on Windows). The editor has the terminal until it exits, and the panel is drawn again after it; JSON with comments is accepted, and text that does not parse or an editor that exits non-zero leaves the value unchanged with the reason shown. The models subagents may pick come from the same catalog `/model` lists: Enter adds or removes one, each change is saved at once, and `Done` or Escape returns. The subagent plugin refuses the choice switched on with no model allowed, so switching it on from an empty list asks for the models first and saves both together, and the last model is kept while the choice is on. Auto routing (beta) lets the task router pick one of those models, and its reasoning effort, for a delegation that names none. Switching it on first says what it sends: each such delegation's task text and the names of the allowed models go to the router's URL, the hosted ing router by default, while the user's own providers still run every model. It also says when Bake is not signed in to the router, and then offers `Sign in and turn on` first; Enter on `Turn on` saves it without signing in. While it is on, the Agent section also offers Router account, the router's URL, the routing priority (`From the task` by default, or quality, cost, speed, or balanced), and Model calibration. Calibration asks the router how it sees each allowed model: the benchmarked model it matched or `unknown to the router`, its quality score, its price per million tokens, and `Ranked` or `Needs a hint`. Enter on a model sets its quality tier, its cost tier, or the benchmarked model it serves, each saved at once, and the list is asked again after every change. A quality tier set on a model the router has benchmarks for is marked as unused, since benchmarks win. When no model is ranked, the list warns that routed delegations keep the default model; a router that cannot be reached shows why. Router account signs in by email: it asks for an address, the router emails a six-digit code, and the code typed next is traded for a token the credential store keeps, so routed delegations send it from then on. A first sign-in creates the account. A refused address or code is shown on the field and asked again, and Escape leaves the stored token as it was. Signed in, the row names the account, and Enter offers signing in with another email or signing out. When the launch environment supplies the token, the row names its variable instead and signing in is not offered. Every write names only its field, so a secret the panel never showed is never lost. Typing on a section's page searches every setting in every section, named by where it lives (`Shell › Command timeout`), and Enter edits the one found, then opens the section it lives in. Up/Down choose, Enter opens a subsection, a value list, or flips an on/off setting, Tab and Shift-Tab move to the next or previous section, and Escape returns to the page above and closes the panel from a section on the tab row. A value list marks the value in force as `Current` and the default as `Default`, and ends with `Enter a value…` where the setting takes a typed one: durations accept `500ms`, `30s`, `2m`, or `1h`, sizes `64KB` or `1MB`, and a value outside the setting's bounds is refused with the bound it breaks. A setting the user has set also offers a pinned `Reset to default`, and a section with any offers `Reset this section to defaults` after a confirmation that defaults to keeping them. Screen mode and language apply at the next launch, and the panel marks them `Next launch` until then, as it does every field of a namespace whose plugin reads it only at start; `--screen`, or a `screen` set in the profile, overrides the saved screen, which the panel marks `Set by --screen`. The others apply at once, including edits made to the file by hand. A failed save, including a value the owning plugin refuses, shows its reason at the top of the panel and leaves the panel open. Closing the panel after a change names the file it was saved to. Without a settings file, only Terminal and Session are offered, and the panel says the changes last until exit.

The model is remembered too. A `/model` choice or a Shift-Tab step changes the current session and is also saved as the default model in the `agent-default-model` section of the same file, so the next launch and `/new` start on it; a resumed session keeps the model it recorded. The panel's default model row opens the same sheet. `/model` lists Recent first (the current model and up to four chosen before, kept as `recentModels` in the `tui` section), then each provider's models under its name, newest first. Each row shows the model's context window, `think` when it offers reasoning efforts, and `image` when it accepts images. ←→ step the selected model's reasoning effort on the row under the list, and Enter chooses the model and effort together.

Expand Down
Loading
Loading