chore: one changeset for the release, and no new em-dashes

Consolidates the four contributor changesets, and rewords the em-dashes this release
added in comments and docs. The five in test/settings-save-failure-ui.test.ts stay:
they assert existing toast text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-04 17:31:48 +01:00
1 parent eb3b08d58b
commit 4960bee779
36 files changed
+117 -106

No files matched your search

+1 -1
View File
@@ -50,7 +50,7 @@ const PATTERNS: Record<TokenPattern, RegExp> = {
'model-plain': /^[a-zA-Z0-9][a-zA-Z0-9._\-/]*$/,
// codex --model, and the value a custom-model `launchModel` is forced onto it. Same
// shape as `model-plain` (leading alphanumeric, so a flag cannot ride the flag) plus
// `:` — Ollama-style ids like `qwen3:32b` must survive onto the command line.
// `:`, since Ollama-style ids like `qwen3:32b` must survive onto the command line.
'model-plain-colon': /^[a-zA-Z0-9][a-zA-Z0-9._\-/:]*$/,
// buildPiCommand — `:` for a thinking suffix (`sonnet:high`), `/` for `provider/id`
'model-pi': /^[a-zA-Z0-9._\-/:]+$/,
+2 -2
View File
@@ -594,13 +594,13 @@ const capabilitiesSchema = z
launchModel: launchModelTemplate,
// State that must survive the isolated-directory redirect, symlinked by name from
// the CLI's real home (deepseek: profiles/sessions/settings.yaml). Single path
// segments only — the consumer joins them, so a traversal here would escape the
// segments only: the consumer joins them, so a traversal here would escape the
// real home. See the field's comment in cli-registry/types.ts.
linkFromRealHome: z.array(homeSegmentName).max(8).optional(),
// Which of `linkFromRealHome` are directories (missing ones are created before
// linking; missing files are skipped). Same segment pattern, see types.ts.
linkFromRealHomeDirs: z.array(homeSegmentName).max(8).optional(),
// The real home's fallback location, relative to the user's home: ONE segment —
// The real home's fallback location, relative to the user's home, ONE segment:
// a leading dot is legitimate (`.dsh` is what ships) but separators, `..` and
// bare `.` are not; the consumer joins it under the user's home, a traversal
// here escapes that home and `.` IS that home (linking THROUGH it unshielded).
+1 -1
View File
@@ -1581,7 +1581,7 @@ const DEEPSEEK: CliEntry = {
// deliberately replaces the user's own for the session rather than linking it.
// `sessions` and `profiles` are directories: dsh creates them itself on a first
// turn, and a fresh/relocated $DSH_HOME that never ran one would otherwise get a
// dangling link whose every write fails ENOENT — the consumer creates missing
// dangling link whose every write fails ENOENT: the consumer creates missing
// directory targets and skips missing file targets like `settings.yaml`.
linkFromRealHome: ['profiles', 'sessions', 'settings.yaml'],
linkFromRealHomeDirs: ['profiles', 'sessions'],
+5 -5
View File
@@ -861,11 +861,11 @@ export interface CliCapabilities {
*
* `appendV1Suffix` (env kind only): the raw `endpoint.baseUrl` gets `withV1Suffix()`
* applied before being written to `baseUrlVar`, instead of being used verbatim. Only
* copilot declares it — its OpenAI-style route is `<base>/v1/chat/completions`, and a
* copilot declares it: its OpenAI-style route is `<base>/v1/chat/completions`, and a
* gateway saves the bare root. claude/gemini must NOT get it: Claude Code's own SDK was
* confirmed working end-to-end against the RAW `baseUrl`, so appending a suffix there
* would be wrong, not just redundant. The per-session config-file recipes do not need
* this flag at all — `renderConfigFile()` applies the suffix inside every template
* this flag at all: `renderConfigFile()` applies the suffix inside every template
* (deepseek's patch included), so no configDir entry carries a raw base URL.
*/
customModelInjection:
@@ -890,11 +890,11 @@ export interface CliCapabilities {
launchModel?: string;
/**
* Names of entries under this CLI's REAL home that must be symlinked into the
* isolated directory after the generated file is written — the same trick
* isolated directory after the generated file is written: the same trick
* `linkSharedProjectsDir()` plays for claude's `projects`. Declared for CLIs whose
* home carries state that must survive the redirect (deepseek's `sessions` transcript
* root and `profiles` bundles, plus `settings.yaml`, which would otherwise stop
* applying and — for `sessions` — get deleted by `removeConfigDir` on clear/close).
* applying and, for `sessions`, get deleted by `removeConfigDir` on clear/close).
* A CLI that saves a linked file by rename replaces the link: dsh does, so the first
* in-session settings write turns `settings.yaml` into a local file.
* Never include `fileName` itself: the generated file owns that name in the isolated
@@ -905,7 +905,7 @@ export interface CliCapabilities {
/**
* Which of `linkFromRealHome` are DIRECTORIES (`sessions`, `profiles`) rather than
* files (`settings.yaml`). A missing directory target is created (mode 0700, what
* dsh does itself on a first turn) before linking — linking a nonexistent directory
* dsh does itself on a first turn) before linking: linking a nonexistent directory
* leaves a dangling symlink the CLI's own `mkdir` under it fails on with ENOENT on
* EVERY turn. A missing FILE target is skipped instead of linked (dangling-file
* links serve no purpose the CLI could not do itself). Must be a subset of