@sagmans/dsh-tui 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/dsh-tui-dogfood/SKILL.md +5 -1
- package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +26 -2
- package/README.md +63 -32
- package/lib/agent/history.d.ts +0 -2
- package/lib/agent/history.d.ts.map +1 -1
- package/lib/agent/history.js +1 -1
- package/lib/agent/history.js.map +1 -1
- package/lib/agent/host.d.ts +0 -25
- package/lib/agent/host.d.ts.map +1 -1
- package/lib/agent/host.js +2 -2
- package/lib/agent/host.js.map +1 -1
- package/lib/agent/model.d.ts +38 -6
- package/lib/agent/model.d.ts.map +1 -1
- package/lib/agent/model.js +38 -14
- package/lib/agent/model.js.map +1 -1
- package/lib/agent/prompt-history.d.ts +7 -12
- package/lib/agent/prompt-history.d.ts.map +1 -1
- package/lib/agent/prompt-history.js +10 -31
- package/lib/agent/prompt-history.js.map +1 -1
- package/lib/cards/composition.d.ts +1 -1
- package/lib/cards/composition.d.ts.map +1 -1
- package/lib/cards/composition.js +7 -0
- package/lib/cards/composition.js.map +1 -1
- package/lib/cards/presenter.d.ts.map +1 -1
- package/lib/cards/presenter.js +32 -2
- package/lib/cards/presenter.js.map +1 -1
- package/lib/cards.d.ts +27 -2
- package/lib/cards.d.ts.map +1 -1
- package/lib/cards.js +17 -3
- package/lib/cards.js.map +1 -1
- package/lib/compat/probe.js +1 -1
- package/lib/compat/probe.js.map +1 -1
- package/lib/config.d.ts +10 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +18 -0
- package/lib/config.js.map +1 -1
- package/lib/contracts.d.ts +2 -0
- package/lib/contracts.d.ts.map +1 -1
- package/lib/export.d.ts +12 -0
- package/lib/export.d.ts.map +1 -1
- package/lib/export.js +34 -3
- package/lib/export.js.map +1 -1
- package/lib/herdr/client.d.ts +0 -9
- package/lib/herdr/client.d.ts.map +1 -1
- package/lib/herdr/client.js +1 -1
- package/lib/herdr/client.js.map +1 -1
- package/lib/herdr/state.d.ts +0 -10
- package/lib/herdr/state.d.ts.map +1 -1
- package/lib/herdr/state.js +1 -1
- package/lib/herdr/state.js.map +1 -1
- package/lib/identity.d.ts +0 -2
- package/lib/identity.d.ts.map +1 -1
- package/lib/identity.js +0 -1
- package/lib/identity.js.map +1 -1
- package/lib/index.d.ts +1 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -5
- package/lib/index.js.map +1 -1
- package/lib/input/keymap.d.ts +1 -7
- package/lib/input/keymap.d.ts.map +1 -1
- package/lib/input/keymap.js +3 -11
- package/lib/input/keymap.js.map +1 -1
- package/lib/input/submission.js +2 -2
- package/lib/input/submission.js.map +1 -1
- package/lib/model-list.d.ts.map +1 -1
- package/lib/model-list.js +17 -5
- package/lib/model-list.js.map +1 -1
- package/lib/queue.d.ts +0 -2
- package/lib/queue.d.ts.map +1 -1
- package/lib/queue.js +1 -1
- package/lib/queue.js.map +1 -1
- package/lib/settings-notice.d.ts +10 -1
- package/lib/settings-notice.d.ts.map +1 -1
- package/lib/settings-notice.js +17 -7
- package/lib/settings-notice.js.map +1 -1
- package/lib/spacing.d.ts +40 -0
- package/lib/spacing.d.ts.map +1 -0
- package/lib/spacing.js +54 -0
- package/lib/spacing.js.map +1 -0
- package/lib/stash/paths.d.ts +19 -10
- package/lib/stash/paths.d.ts.map +1 -1
- package/lib/stash/paths.js +52 -23
- package/lib/stash/paths.js.map +1 -1
- package/lib/stash/schema.d.ts +13 -12
- package/lib/stash/schema.d.ts.map +1 -1
- package/lib/stash/schema.js +11 -9
- package/lib/stash/schema.js.map +1 -1
- package/lib/stash/store.d.ts.map +1 -1
- package/lib/stash/store.js +9 -19
- package/lib/stash/store.js.map +1 -1
- package/lib/stash.d.ts +17 -10
- package/lib/stash.d.ts.map +1 -1
- package/lib/stash.js +31 -20
- package/lib/stash.js.map +1 -1
- package/lib/subagents.d.ts +0 -4
- package/lib/subagents.d.ts.map +1 -1
- package/lib/subagents.js +2 -2
- package/lib/subagents.js.map +1 -1
- package/lib/surface/appearance.d.ts +3 -0
- package/lib/surface/appearance.d.ts.map +1 -1
- package/lib/surface/appearance.js +5 -0
- package/lib/surface/appearance.js.map +1 -1
- package/lib/surface/background-work.d.ts.map +1 -1
- package/lib/surface/background-work.js +17 -1
- package/lib/surface/background-work.js.map +1 -1
- package/lib/surface/commands.d.ts.map +1 -1
- package/lib/surface/commands.js +26 -6
- package/lib/surface/commands.js.map +1 -1
- package/lib/surface/modal-input.d.ts.map +1 -1
- package/lib/surface/modal-input.js +11 -0
- package/lib/surface/modal-input.js.map +1 -1
- package/lib/surface/model-choice.d.ts.map +1 -1
- package/lib/surface/model-choice.js +18 -18
- package/lib/surface/model-choice.js.map +1 -1
- package/lib/surface/preset-choice.d.ts.map +1 -1
- package/lib/surface/preset-choice.js +18 -10
- package/lib/surface/preset-choice.js.map +1 -1
- package/lib/surface/prompt-memory.d.ts +3 -1
- package/lib/surface/prompt-memory.d.ts.map +1 -1
- package/lib/surface/prompt-memory.js +10 -11
- package/lib/surface/prompt-memory.js.map +1 -1
- package/lib/surface/session-lifecycle.d.ts +6 -1
- package/lib/surface/session-lifecycle.d.ts.map +1 -1
- package/lib/surface/session-lifecycle.js +27 -8
- package/lib/surface/session-lifecycle.js.map +1 -1
- package/lib/surface/session-view.d.ts.map +1 -1
- package/lib/surface/session-view.js +1 -3
- package/lib/surface/session-view.js.map +1 -1
- package/lib/surface/staged-turns.d.ts +0 -2
- package/lib/surface/staged-turns.d.ts.map +1 -1
- package/lib/surface/staged-turns.js +37 -6
- package/lib/surface/staged-turns.js.map +1 -1
- package/lib/terminal/external-editor.d.ts +16 -0
- package/lib/terminal/external-editor.d.ts.map +1 -1
- package/lib/terminal/external-editor.js +38 -6
- package/lib/terminal/external-editor.js.map +1 -1
- package/lib/terminal/host-writes.d.ts +15 -2
- package/lib/terminal/host-writes.d.ts.map +1 -1
- package/lib/terminal/host-writes.js +10 -1
- package/lib/terminal/host-writes.js.map +1 -1
- package/lib/terminal/restore.d.ts +1 -2
- package/lib/terminal/restore.d.ts.map +1 -1
- package/lib/terminal/restore.js +1 -9
- package/lib/terminal/restore.js.map +1 -1
- package/lib/terminal/signals.d.ts +0 -1
- package/lib/terminal/signals.d.ts.map +1 -1
- package/lib/terminal/signals.js +1 -1
- package/lib/terminal/signals.js.map +1 -1
- package/lib/terminal/title.d.ts.map +1 -1
- package/lib/terminal/title.js +14 -3
- package/lib/terminal/title.js.map +1 -1
- package/lib/terminal/warning-screen.d.ts.map +1 -1
- package/lib/terminal/warning-screen.js +12 -1
- package/lib/terminal/warning-screen.js.map +1 -1
- package/lib/theme-capability.d.ts +0 -2
- package/lib/theme-capability.d.ts.map +1 -1
- package/lib/theme-capability.js +1 -1
- package/lib/theme-capability.js.map +1 -1
- package/lib/theme-defaults.d.ts.map +1 -1
- package/lib/theme-defaults.js +7 -0
- package/lib/theme-defaults.js.map +1 -1
- package/lib/theme-schema.d.ts +6 -6
- package/lib/theme-settings.d.ts +13 -8
- package/lib/theme-settings.d.ts.map +1 -1
- package/lib/theme-settings.js +7 -1
- package/lib/theme-settings.js.map +1 -1
- package/lib/theme-tokens.d.ts +1 -1
- package/lib/theme-tokens.d.ts.map +1 -1
- package/lib/theme-tokens.js +7 -2
- package/lib/theme-tokens.js.map +1 -1
- package/lib/transcript.d.ts +2 -2
- package/lib/transcript.d.ts.map +1 -1
- package/lib/transcript.js +9 -4
- package/lib/transcript.js.map +1 -1
- package/lib/ui/dock.d.ts +2 -0
- package/lib/ui/dock.d.ts.map +1 -1
- package/lib/ui/dock.js +18 -3
- package/lib/ui/dock.js.map +1 -1
- package/lib/ui/gap.d.ts +28 -0
- package/lib/ui/gap.d.ts.map +1 -0
- package/lib/ui/gap.js +47 -0
- package/lib/ui/gap.js.map +1 -0
- package/lib/ui/gutter.d.ts +25 -0
- package/lib/ui/gutter.d.ts.map +1 -0
- package/lib/ui/gutter.js +31 -0
- package/lib/ui/gutter.js.map +1 -0
- package/lib/ui/layout.d.ts +13 -1
- package/lib/ui/layout.d.ts.map +1 -1
- package/lib/ui/layout.js +32 -6
- package/lib/ui/layout.js.map +1 -1
- package/lib/ui/queue.d.ts +0 -4
- package/lib/ui/queue.d.ts.map +1 -1
- package/lib/ui/queue.js +2 -2
- package/lib/ui/queue.js.map +1 -1
- package/lib/ui/rows.d.ts +0 -8
- package/lib/ui/rows.d.ts.map +1 -1
- package/lib/ui/rows.js +1 -9
- package/lib/ui/rows.js.map +1 -1
- package/lib/ui/stash-picker.d.ts +2 -2
- package/lib/ui/stash-picker.d.ts.map +1 -1
- package/lib/ui/stash-picker.js +3 -3
- package/lib/ui/stash-picker.js.map +1 -1
- package/lib/ui/view/gate-card.d.ts.map +1 -1
- package/lib/ui/view/gate-card.js +4 -1
- package/lib/ui/view/gate-card.js.map +1 -1
- package/lib/ui/view/tool-card.d.ts +4 -0
- package/lib/ui/view/tool-card.d.ts.map +1 -1
- package/lib/ui/view/tool-card.js +21 -5
- package/lib/ui/view/tool-card.js.map +1 -1
- package/lib/ui/view/transcript-message.d.ts +3 -0
- package/lib/ui/view/transcript-message.d.ts.map +1 -1
- package/lib/ui/view/transcript-message.js +8 -1
- package/lib/ui/view/transcript-message.js.map +1 -1
- package/lib/ui/view.d.ts +11 -6
- package/lib/ui/view.d.ts.map +1 -1
- package/lib/ui/view.js +37 -26
- package/lib/ui/view.js.map +1 -1
- package/package.json +3 -1
- package/themes/deepseek-blue.yaml +3 -0
- package/themes/violet-orbit.yaml +9 -4
|
@@ -22,7 +22,11 @@ directory or branch tail. A path selects that checkout directly. The helper read
|
|
|
22
22
|
runs `pnpm run build` only when the checkout declares a build script. It adds
|
|
23
23
|
the bundle once if absent from the cloned profile, updates only its dependency,
|
|
24
24
|
restores local links from `link:` specifications, and launches
|
|
25
|
-
`dsh --profile tui` by default.
|
|
25
|
+
`dsh --profile tui` by default. For this TUI, the packaged helper checks
|
|
26
|
+
the launcher against compatible releases in the checkout’s `package.json` before
|
|
27
|
+
cloning. This checkout uses installed `dsh 0.1.5-rc.3` for PTY tests. Never
|
|
28
|
+
substitute `pnpm dsh` or a `--dsh` path from a Harness source checkout: that
|
|
29
|
+
host may migrate the cloned `settings.yaml`. The legacy
|
|
26
30
|
`scripts/dogfood/run-tui-from-worktree.sh` remains available in dsh-tui and
|
|
27
31
|
defaults to that script's checkout even when called elsewhere.
|
|
28
32
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
set -euo pipefail
|
|
4
4
|
|
|
5
5
|
name="$(basename "${BASH_SOURCE[0]}")"
|
|
6
|
+
TUI_PACKAGE_NAME='@sagmans/dsh-tui'
|
|
6
7
|
# The link policy is shared with the validator, so both read one rule set.
|
|
7
8
|
helper_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
|
8
9
|
default_repo="${DSH_DOGFOOD_DEFAULT_REPO:-$PWD}"
|
|
@@ -268,11 +269,26 @@ if [[ "$dry_run" == 1 ]]; then
|
|
|
268
269
|
fi
|
|
269
270
|
|
|
270
271
|
[[ -n "$dsh_bin" ]] || die "no dsh launcher found; put dsh on PATH or pass --dsh"
|
|
272
|
+
# This plugin's daily host must not be replaced by a source checkout during setup or launch.
|
|
273
|
+
if [[ "$package_name" == "$TUI_PACKAGE_NAME" ]]; then
|
|
274
|
+
# Keep launcher startup writes out of both the live home and the clone.
|
|
275
|
+
version_probe_home="$(mktemp -d /tmp/dsh-dogfood-version.XXXXXXXX)" || die "cannot create isolated version probe home"
|
|
276
|
+
trap 'rm -rf -- "$version_probe_home"' EXIT
|
|
277
|
+
trap 'exit 1' INT TERM
|
|
278
|
+
reported_version="$(HOME="$version_probe_home" DSH_HOME="$version_probe_home" "$dsh_bin" --version 2>/dev/null)" || die "TUI dogfood requires compatible installed dsh"
|
|
279
|
+
rm -rf -- "$version_probe_home"
|
|
280
|
+
trap - EXIT INT TERM
|
|
281
|
+
node -e "const p=require(process.argv[1]);process.exit(p.dsh?.compatibility?.dshReleases?.[process.argv[2]] === 'compatible' ? 0 : 1)" "$target_path/package.json" "$reported_version" || die "TUI dogfood requires compatible installed dsh (got ${reported_version:-<empty>})"
|
|
282
|
+
fi
|
|
271
283
|
|
|
272
284
|
# --- seed the scratch home ---------------------------------------------------
|
|
273
285
|
|
|
274
286
|
if [[ -d "$home" && "$action" != "clean" && "$dry_run" != 1 ]]; then
|
|
275
287
|
validate_marker
|
|
288
|
+
# A marker that still reads 0 belongs to a run the kernel killed before it could
|
|
289
|
+
# clean up: the identity matches, so --reseed takes it, but nothing may reuse a
|
|
290
|
+
# home whose copy stopped halfway. A marker without the line predates this.
|
|
291
|
+
[[ "$reseed" == 1 ]] || [[ "$(marker_value ready)" != 0 ]] || die "$home is a half-seeded clone; pass --reseed to clone it again"
|
|
276
292
|
check_credentials
|
|
277
293
|
chmod 700 "$home"
|
|
278
294
|
if [[ -f "$home/.credentials.yaml" ]]; then chmod 600 "$home/.credentials.yaml"; fi
|
|
@@ -293,6 +309,11 @@ if [[ ! -d "$home" ]]; then
|
|
|
293
309
|
step "seeding $home from $source_home"
|
|
294
310
|
mkdir -p "$home"
|
|
295
311
|
chmod 700 "$home"
|
|
312
|
+
# Written before the copy, so whatever the copy does this directory is one that
|
|
313
|
+
# --clean and --reseed already own: an interrupted clone is recoverable rather
|
|
314
|
+
# than a husk neither action will touch. The copy marks it ready when it lands.
|
|
315
|
+
printf 'home=%s\nsource=%s\ntarget=%s\nprofile=%s\nready=0\n' "$home" "$source_home" "$target_path" "$profile" > "$marker"
|
|
316
|
+
chmod 600 "$marker"
|
|
296
317
|
if [[ "$fresh" == 1 ]]; then
|
|
297
318
|
for seed in .credentials.yaml settings.yaml; do
|
|
298
319
|
if [[ -f "$source_home/$seed" ]]; then cp -p "$source_home/$seed" "$home/$seed"; fi
|
|
@@ -316,8 +337,6 @@ if [[ ! -d "$home" ]]; then
|
|
|
316
337
|
fi
|
|
317
338
|
fi
|
|
318
339
|
|
|
319
|
-
printf 'home=%s\nsource=%s\ntarget=%s\nprofile=%s\n' "$home" "$source_home" "$target_path" "$profile" > "$marker"
|
|
320
|
-
chmod 600 "$marker"
|
|
321
340
|
materialize_cloned_links
|
|
322
341
|
check_clone_links
|
|
323
342
|
|
|
@@ -398,6 +417,11 @@ if ! node -e "process.exit(require(process.argv[1]).dsh.profile.bundles.includes
|
|
|
398
417
|
die "profile '$profile' does not list $package_name after relink (bundles: $bundles)"
|
|
399
418
|
fi
|
|
400
419
|
|
|
420
|
+
# The home is finished: it points at the target and its bundles answer, so it is
|
|
421
|
+
# ready to be reused rather than re-seeded.
|
|
422
|
+
printf 'home=%s\nsource=%s\ntarget=%s\nprofile=%s\nready=1\n' "$home" "$source_home" "$target_path" "$profile" > "$marker"
|
|
423
|
+
chmod 600 "$marker"
|
|
424
|
+
|
|
401
425
|
printf '\n' >&2
|
|
402
426
|
printf 'home: %s\n' "$home" >&2
|
|
403
427
|
printf 'target: %s\n' "$target_path" >&2
|
package/README.md
CHANGED
|
@@ -106,15 +106,9 @@ dsh plugin --profile tui remove @sagmans/dsh-tui
|
|
|
106
106
|
|
|
107
107
|
The profile then keeps `@deepseek-ai/dsh-base` and no application, so `dsh --profile tui` waits with no output. Add the plugin again to use the profile.
|
|
108
108
|
|
|
109
|
-
###
|
|
109
|
+
### Use the installed Harness launcher
|
|
110
110
|
|
|
111
|
-
`
|
|
112
|
-
|
|
113
|
-
```sh
|
|
114
|
-
pnpm --config.verify-deps-before-run=false dsh --profile tui # from the checkout
|
|
115
|
-
CI=true pnpm dsh --profile tui # also suppresses the check
|
|
116
|
-
node "$CHECKOUT/apps/cli/lib/bin.js" --profile tui # needs neither pnpm nor the check
|
|
117
|
-
```
|
|
111
|
+
Run `dsh --version` and confirm `0.1.5-rc.3` before launching this plugin. `pnpm dsh` from a Harness source checkout runs its development host, not the installed release. That host can migrate `settings.yaml` and is outside this plugin's supported range; do not use it for TUI dogfooding.
|
|
118
112
|
|
|
119
113
|
## Troubleshooting
|
|
120
114
|
|
|
@@ -133,7 +127,7 @@ Two facts explain most failures.
|
|
|
133
127
|
| `dsh-tui: both stdin and stdout must be TTYs` | stdin or stdout is a pipe, a file, or a CI runner | run the command from a terminal |
|
|
134
128
|
| Node warnings, such as `ExperimentalWarning: stripTypeScriptTypes …`, appear after exit | the TUI holds runtime warnings until it returns the terminal to your shell; startup warnings remain visible before the TUI starts | read the warnings in your shell after exit; no warning-suppression flag is needed |
|
|
135
129
|
| Changes under `src/` have no effect | a linked profile loads `lib/`, not `src/` | `pnpm run build` in the plugin checkout |
|
|
136
|
-
|
|
|
130
|
+
| TUI preferences disappear after launching a Harness source checkout | that host treats `settings.yaml` as migration input, not live preferences | use installed `dsh 0.1.5-rc.3` with a cloned home; preserve the original settings file |
|
|
137
131
|
| `--preset <id>` is refused, because the session's agent preset is fixed | a session keeps the mode that composed it, and this session already took a turn | `/preset <id>` before the first turn, or resume without `--preset` |
|
|
138
132
|
| `--resume <id>` starts a new session | the id is a bare UUID | pass the stored id, `tui-session-…` included; a bare `--resume` opens the picker |
|
|
139
133
|
| `dsh: profile "tui" does not exist` | the profile is not created yet | the `add` command creates it |
|
|
@@ -186,7 +180,7 @@ force, and the `keys:` section moves any of them — see [Keys](#keys).
|
|
|
186
180
|
| Ctrl+T | pick the reasoning effort for the next step |
|
|
187
181
|
| Ctrl+R | reverse-search recorded prompts: the list opens filtered by whatever is in the bar, `enter` puts one back, `esc` keeps the draft |
|
|
188
182
|
| Ctrl+X then S | stash the current draft |
|
|
189
|
-
| Ctrl+X then L | open
|
|
183
|
+
| Ctrl+X then L | open the current stash bank's drafts |
|
|
190
184
|
| Ctrl+X then M | open the model picker |
|
|
191
185
|
| Ctrl+X then Y | copy the last answer to the clipboard |
|
|
192
186
|
| Ctrl+X then E | edit the draft in `$VISUAL` (or `$EDITOR`) and take back what it saves |
|
|
@@ -223,7 +217,7 @@ force, and the `keys:` section moves any of them — see [Keys](#keys).
|
|
|
223
217
|
| `/undo` | hide the newest prompt's turn and put that prompt back in the bar (`ctrl+x` then `u`) |
|
|
224
218
|
| `/redo` | step forward again after an undo (`ctrl+x` then `r`) |
|
|
225
219
|
| `/rename <title>` | title this session; the picker shows it instead of the session id |
|
|
226
|
-
| `/export [path]` | write the visible transcript as markdown
|
|
220
|
+
| `/export [path]` | write the visible transcript as markdown; with no path, `$DSH_HOME/exports/dsh-session-<id>.md` |
|
|
227
221
|
| `/resume` | open another stored session without leaving the terminal |
|
|
228
222
|
| `/clear` | clear the visible transcript |
|
|
229
223
|
| `/history` | show how many prompts are recorded and where the file is |
|
|
@@ -236,9 +230,9 @@ force, and the `keys:` section moves any of them — see [Keys](#keys).
|
|
|
236
230
|
| `/stash <draft>` | park the text given after the command (`ctrl+x` then `s` parks the editor) |
|
|
237
231
|
| `/stash-pop [index\|id]` | put a stashed draft into the editor and remove it (newest by default) |
|
|
238
232
|
| `/stash-apply [index\|id]` | put a stashed draft into the editor and keep it |
|
|
239
|
-
| `/stash-list` | pick from
|
|
233
|
+
| `/stash-list` | pick from the current stash bank's drafts; `enter` pops the marked one |
|
|
240
234
|
| `/stash-drop [index\|id]` | delete a stashed draft without using it |
|
|
241
|
-
| `/stash-clear` | delete every draft
|
|
235
|
+
| `/stash-clear` | delete every draft in the current stash bank, after a confirmation |
|
|
242
236
|
| `/quit` | leave and print the resume command |
|
|
243
237
|
|
|
244
238
|
Typing `@` opens this workspace's files above the editor, ranked as the fragment is typed the way a fuzzy finder ranks a path list: `@edtr` reaches `src/ui/editor.ts` without spelling the separators, a directory offers itself with a trailing slash so typing continues into it, and a path holding a space is quoted. A directory whose own name holds a space offers no row, because the menu stops following the token once one is in it; the files under it are still listed, each quoted whole. The rows are what git tracks or would add, with ignored paths left out, so a suggestion never names build output or a secret the repository deliberately ignores; a tree git does not own is walked instead, skipping `node_modules`, `.git`, and the rest of the build litter. A path typed from the working directory still completes on Tab as before.
|
|
@@ -270,7 +264,7 @@ plan package rather than from the dock.
|
|
|
270
264
|
|
|
271
265
|
An approval or a question draws inline above the editor and takes the keyboard. A question that lists options always adds row `0. other — type your own answer`: type or paste an answer the model did not offer, and the seam receives it as that question's free text — replacing a single-select choice, or supplementing a multi-select one. `0`, or `↓` past the last option, reaches the row; `↑` walks back to the list with the text kept, and `esc` does the same from that row, because a question skipped by accident is a question answered twice — an escape from the list skips it. Free text is written in the prompt bar's own editor, drawn under that row: movement, word and line deletion, undo, completion, and multi-line paste are all the editor the reader already uses, and the prompt bar steps aside while a question is open, so a prompt written but not sent comes back untouched once the question is answered. No question hides its answer — the reader is the one who has to check what they are about to send. Every gate row wraps at the screen edge under its own label, so a long option or question is readable rather than cut.
|
|
272
266
|
|
|
273
|
-
While a turn runs, a prompt submitted into the editor waits in the agent's own inbox instead of disappearing: it is drawn above the editor in the input bar's own frame, faint and italic, and moves into the transcript when the agent takes it — where
|
|
267
|
+
While a turn runs, a prompt submitted into the editor waits in the agent's own inbox instead of disappearing: it is drawn above the editor in the input bar's own frame, faint and italic, and moves into the transcript when the agent takes it — where a separate prompt frame keeps what the reader typed distinct from what the agent said. Its markdown lays out inside that frame, so a list or a fence reads in the same box it was typed into. `editor.queued` and `editor.queued.more` restyle or hide the waiting rows; `transcript.user` restyles the submitted text, `transcript.user.border` its frame, and `editor.border` the input bar. A reply is drawn in a frame of its own, so one exchange reads as two objects rather than as a box followed by a stream of rows: `transcript.assistant.border` restyles that frame, and hiding it draws the reply bare. `ctrl+c` takes them back: an interrupt drops whatever the agent has not started, so the waiting prompts are read first and put into the bar before the turn is stopped.
|
|
274
268
|
|
|
275
269
|
Copying is read back through what the surface drew rather than through the screen, so a selection is the words alone: dragging across a message takes its box with it on screen, and the surface takes its own frame back out before the text reaches the clipboard — the sides, the padding beside them, and the rules above and below. A selection that covers a whole message, two of them, or a part of one is read the same way, and a row the transcript did not draw — the editor's own bar, a picker's card — is copied exactly as it read, and a selection that was nothing but frame is handed back as the reader made it, because a copy is never emptied. The frame still comes back in a copy taken with the terminal's own selection — Shift held while dragging, or a terminal that keeps selection to itself — which is the one path no program can filter.
|
|
276
270
|
|
|
@@ -297,10 +291,33 @@ Any other `/command` goes to the command registry, so `/plan`, `/compact`, `/goa
|
|
|
297
291
|
says so, because submitting a command consumes the line it was typed on and there
|
|
298
292
|
is nothing left of the draft to park. `/stash-pop` puts a parked draft back and
|
|
299
293
|
removes it, so a prompt written for the wrong moment survives a restart instead
|
|
300
|
-
of being retyped or sent; `l` opens the list of them.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
294
|
+
of being retyped or sent; `l` opens the list of them. By default, a stash
|
|
295
|
+
belongs to the absolute working directory where the TUI started: new or resumed
|
|
296
|
+
sessions in the same worktree share drafts. Set `stash.scope: session` on the TUI
|
|
297
|
+
row in the profile's `cordis.patch.yml` to keep each session's drafts separate:
|
|
298
|
+
|
|
299
|
+
```yaml
|
|
300
|
+
- id: tui
|
|
301
|
+
config:
|
|
302
|
+
sessionId: !!js ctx.tuiStartup.sessionId
|
|
303
|
+
resume: !!js ctx.tuiStartup.resume
|
|
304
|
+
resumePicker: !!js ctx.tuiStartup.resumePicker
|
|
305
|
+
model: !!js ctx.tuiStartup.model
|
|
306
|
+
provider: !!js ctx.tuiStartup.provider
|
|
307
|
+
preset: !!js ctx.tuiStartup.preset
|
|
308
|
+
color: !!js ctx.tuiStartup.color
|
|
309
|
+
bell: !!js ctx.tuiStartup.bell
|
|
310
|
+
stash:
|
|
311
|
+
scope: session
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
A profile override replaces the row's config, so keep its startup mappings as
|
|
315
|
+
shown. Editing the bundle's `tui` row config instead needs only the `stash` block.
|
|
316
|
+
|
|
317
|
+
Use `scope: path` (the default) to share drafts by directory. Changing the
|
|
318
|
+
scope does not move existing drafts; switch back to the old scope to read them.
|
|
319
|
+
The footer shows `stash N` while drafts are waiting, ranked above the context
|
|
320
|
+
and cache numbers it shares a row with.
|
|
304
321
|
|
|
305
322
|
A selector is the number the list shows in brackets — `0` is the newest — or the
|
|
306
323
|
entry's own id; leaving it out takes the newest. `apply` and `pop` refuse to
|
|
@@ -318,7 +335,7 @@ the write is attempted. The bar is only cleared while it still holds that same
|
|
|
318
335
|
draft and no question has borrowed it, so an answer typed during the write is
|
|
319
336
|
never wiped by a stash finishing.
|
|
320
337
|
|
|
321
|
-
|
|
338
|
+
Each path or session bank is one JSON file under `$DSH_HOME/tui-stash`, written with
|
|
322
339
|
owner-only permissions (`0700` directory, `0600` file) through a no-follow open,
|
|
323
340
|
and every directory the path passes through must be owned by the reader (or by
|
|
324
341
|
root) and not writable by anyone else — the sticky bit is the only exception,
|
|
@@ -387,6 +404,10 @@ dsh-tui:
|
|
|
387
404
|
theme: deepseek-blue # restyle the whole surface by name (default: violet-orbit)
|
|
388
405
|
subcalls: inline # draw the calls a PTC program dispatched (default collapsed)
|
|
389
406
|
mermaid: streaming # draw a reply's mermaid fences: off, final, or streaming (default streaming)
|
|
407
|
+
spacing:
|
|
408
|
+
padding: 1 # columns that inset the conversation and the work board (0-3, default 1)
|
|
409
|
+
messages: 1 # blank rows above and below a prompt or a reply card (0-3, default 1)
|
|
410
|
+
steps: 1 # blank rows where a step of a turn opens, grouping a thought with its calls (0-3, default 1)
|
|
390
411
|
tools:
|
|
391
412
|
default: { collapsed: true, output: hidden } # how every tool's card starts
|
|
392
413
|
bash: { output: tail, tail: 5 } # keep the last five output rows behind bash's fold
|
|
@@ -568,7 +589,11 @@ field at a time, so naming a single attribute does not discard the shade the the
|
|
|
568
589
|
gave that same element. `/theme tokens` names the theme in force in its heading and
|
|
569
590
|
reports each element as `override`, `theme`, `palette`, or `default`, marking the
|
|
570
591
|
themes in your own directory and printing the export hint, so a screen that looks
|
|
571
|
-
wrong can be traced to the layer that drew it.
|
|
592
|
+
wrong can be traced to the layer that drew it. Submitted prompts, assistant
|
|
593
|
+
replies, and the editor have separate border tokens: `transcript.user.border`,
|
|
594
|
+
`transcript.assistant.border`, and `editor.border`. In `violet-orbit`, their
|
|
595
|
+
default shades are `#6f76c9`, `#a89771`, and `#6f76c9`. An existing
|
|
596
|
+
`editor.border` override now affects only the editor, not submitted prompts.
|
|
572
597
|
|
|
573
598
|
A fenced block whose language is `diff` or `patch` is drawn as the change it
|
|
574
599
|
describes rather than as one plain code block: file headers and hunk headers
|
|
@@ -726,13 +751,17 @@ The package is a Cordis plugin bundle that stacks over `@deepseek-ai/dsh-base`:
|
|
|
726
751
|
|
|
727
752
|
A question whose id ends in `:secret` declares its typed answer a credential: the bar hides everything but its first and last four characters, and the free-text row a question with options offers is labelled `API KEY`. Wording is not a declaration, because hiding every question that mentions a key would hide answers their authors meant to be read.
|
|
728
753
|
|
|
754
|
+
Air follows the log's own boundaries rather than every row. A prompt and a reply are objects of the transcript, so each frame opens and closes on blank rows — `spacing.messages`, one by default — and two boundaries that meet keep the wider ask instead of the sum, so one break never reads as two. A step is the other boundary: the loop's `step/start` opens it, which is what keeps a thought and the calls it made in one group and puts the next step's work underneath it, `spacing.steps` rows down. Nothing else is spaced — a reply after a reply, a folded thought's signpost, and the cards under the message that asked for them all stay flush — and every count accepts 0, which draws the rows exactly as the surface drew them before the air existed. `spacing.padding` insets the conversation and the work board under it instead of sitting at a seam, while the bar the reader types in, the prompts queued behind it, and the footer keep the window's full width; all three counts are read per frame, so an edit in `$DSH_HOME/settings.yaml` lands on the session already on screen.
|
|
755
|
+
|
|
756
|
+
The work board opens on a blank row of its own, so the conversation above it and the todos, jobs, and delegations below it are two regions rather than one stream. The blank row takes no row when the board has nothing to report: with no work on the board nothing is drawn and the bar sits directly under the transcript.
|
|
757
|
+
|
|
729
758
|
The fold is durable-only: the live stream decorates the row that is still being written, and everything else — cards, reasoning, work state, compaction markers — comes from the log, so a resumed session renders what the live one did. Subagent start and finish are the exception: they arrive as service events, and the transcript shows them as decoration because the durable record of a delegation is the tool call that asked for it.
|
|
730
759
|
|
|
731
760
|
Tool cards are folded by default: a card draws one header row — the tool, its argument clipped to the configured budget, and the facts the result measured — so a long read, diff, or search cannot bury the conversation. A call that has not answered yet names itself in the running colour, `tool.running.title`, and ends that row with the whole seconds it has been waiting, in `tool.running.elapsed`, once it has waited one, so a reader can tell the call they are watching from the one below it that already finished; both give way to the measured facts the moment the result lands. A call that failed names itself in the failed colour, `tool.failed.title` — including a shell whose command exited non-zero or died on a signal, which is a failure whether or not the tool that ran it said so. A shell card's row also carries the exit status and the count of output rows waiting behind the fold, because its output is the answer the reader asked for and a fold that left no trace of it would read as a call that produced nothing. Clicking a card opens or folds that one message; `Ctrl+O` opens or folds every card at once, and `tools:` in the [settings](#settings) decides how each tool starts and whether a fold hides its rows or keeps a `tail` of them.
|
|
732
761
|
|
|
733
762
|
A PTC card is the one card with children: every call the `run_code` program dispatched hangs off the card that made it, and once shown, each draws under the header as the tool's own name and argument, on one row cut at the screen edge whether the card itself is open or folded — a program's work must stay legible without opening its card. Those rows start folded, because a program can dispatch hundreds of calls and what a reader came for is the answer they produced: one click on the card's own header draws them for that card and for that card alone, `Ctrl+Y` draws them for every card at once, and `subcalls:` decides what a session starts with. Nothing else arrives with that click: the program's own rows are the level below, and `Ctrl+O` is what opens them. Each of those rows names its own call in the colour of what that call is doing — `tool.subcall.running` while the program is waiting on it, `tool.failed.title` when it failed, and `tool.subcall.title` once it is back — and a settled row keeps the one line the tool itself drew about its outcome, in `tool.terminal.status` where that tool declares one. A shell call therefore reads `bash pnpm test · exit 0` when it worked and the same row in red, with `exit 1`, when it did not, so a program's work reads row by row without opening the card. The program's own row is the one card that shows no mark: its timer is what says it is still running, and it is also what the card keeps when the program answers — the total it ran for, drawn in `tool.elapsed.done`, dimmed and italic, because the work it measured is over. Clicking one of those rows opens that call's argument in full and leaves its neighbours and the card as they were; a shell call also brings back the rows it printed, because the program's return value is all the card itself keeps. `Ctrl+Y` hides or shows them all, and `subcalls: collapsed`, the shipped default, starts every session with them hidden; see [Settings](#settings).
|
|
734
763
|
|
|
735
|
-
A card's header names the tool, then the argument the call was made with — a path or a command — in the `tool.args` colour, then the facts the result measured: a read reports its line range, line count, and token size; a file change that carried no prior content to compare against reports its lines and tokens; one that did reports added, changed, and removed lines as `+n ~n -n` in green, yellow, and red. Each stat is its own token, so any of them can be recoloured or hidden independently, and so are the elements a call in flight is drawn with — hiding `tool.running.elapsed` leaves the name in its running colour, hiding `tool.running.title` leaves the seconds counting, hiding `tool.elapsed.done` takes the total off a program's settled row, and a dispatched row is toned the same way per state with `tool.subcall.running` and `tool.subcall.title`. A state is only how a name is painted, so hiding one of those colours leaves the name in the colour a call with no state is read in rather than taking the name away.
|
|
764
|
+
A card's header names the tool, then, on a skill card, the skill it loaded in the `tool.skill` colour, then the argument the call was made with — a path or a command — in the `tool.args` colour, then the facts the result measured: a read reports its line range, line count, and token size; a file change that carried no prior content to compare against reports its lines and tokens; one that did reports added, changed, and removed lines as `+n ~n -n` in green, yellow, and red. Each stat is its own token, so any of them can be recoloured or hidden independently, and so are the elements a call in flight is drawn with — hiding `tool.running.elapsed` leaves the name in its running colour, hiding `tool.running.title` leaves the seconds counting, hiding `tool.elapsed.done` takes the total off a program's settled row, and a dispatched row is toned the same way per state with `tool.subcall.running` and `tool.subcall.title`. A state is only how a name is painted, so hiding one of those colours leaves the name in the colour a call with no state is read in rather than taking the name away. Hiding `tool.skill` is the same promise for a subject: the skill keeps its name in the label's colour. `/export` and a dispatched row spell the name too, so the words survive where no colour is.
|
|
736
765
|
|
|
737
766
|
The bundle also takes the base's global agent rows out of the composition, twenty-three of them. Every one is a row the shipped modes supply per session instead, so leaving it mounted registers the same tool names in two layers and doubles each prompt section it owns. What stays mounted is the host: sessions, storage, models, permissions, jobs, and the command registry.
|
|
738
767
|
|
|
@@ -802,22 +831,18 @@ pnpm test
|
|
|
802
831
|
pnpm run build
|
|
803
832
|
```
|
|
804
833
|
|
|
805
|
-
**A linked profile loads the built entry point**, so edits under `src/` are invisible to `dsh --profile tui` until `pnpm run build` runs.
|
|
806
|
-
|
|
807
|
-
```sh
|
|
808
|
-
node tools/pty-drive.mjs --prompt 'Reply with exactly: pong'
|
|
809
|
-
node tools/pty-drive.mjs --prompt 'Run: echo hi' --approve 20 # answer the approval gate
|
|
810
|
-
node tools/pty-drive.mjs --home /tmp/scratch-home --seconds 20 # no credentials: proves failures are visible
|
|
811
|
-
node tools/pty-drive.mjs --prompt 'Run: echo hi' --click 20:12 # press the left button at row 12
|
|
812
|
-
```
|
|
834
|
+
**A linked profile loads the built entry point**, so edits under `src/` are invisible to `dsh --profile tui` until `pnpm run build` runs. The PTY driver rebuilds, checks nested links in the isolated `--home`, and rejects launchers other than `dsh 0.1.5-rc.3`.
|
|
813
835
|
|
|
814
|
-
|
|
836
|
+
Clone your configured home with the dogfood helper for realistic runs. A minimal throwaway home can also expose startup failures without touching your real state:
|
|
815
837
|
|
|
816
838
|
```sh
|
|
817
839
|
S=$(mktemp -d)
|
|
818
840
|
cp ~/.dsh/.credentials.yaml ~/.dsh/settings.yaml "$S/" && chmod 600 "$S"/*.yaml
|
|
819
841
|
DSH_HOME="$S" dsh plugin --profile tui add "$PWD"
|
|
820
842
|
node tools/pty-drive.mjs --home "$S" --prompt 'Reply with exactly: pong'
|
|
843
|
+
node tools/pty-drive.mjs --home "$S" --prompt 'Run: echo hi' --approve 20
|
|
844
|
+
node tools/pty-drive.mjs --home "$S" --seconds 20 --prompt ''
|
|
845
|
+
node tools/pty-drive.mjs --home "$S" --prompt 'Run: echo hi' --click 20:12
|
|
821
846
|
```
|
|
822
847
|
|
|
823
848
|
Test specs import plugin sources through the `@/` alias. Under this test runner the spec file is resolved with a root-relative id, so parent-relative imports (`../src/...`) do not resolve; the alias and its matching `tsconfig.test.json` path mapping avoid that.
|
|
@@ -843,6 +868,11 @@ The automated checks drive a real PTY, but they run on this machine's terminal.
|
|
|
843
868
|
| a PTC turn in which a dispatched call failed, then a click on that red row | the row opens to the reason the call reported, and a click on those rows folds it back |
|
|
844
869
|
| that same turn, then `ctrl+y` | the rows draw under the folded card; `ctrl+y` again folds them away, and one click on the card's own header does the same for that card alone |
|
|
845
870
|
| `dsh-tui: { subcalls: inline }` in `$DSH_HOME/settings.yaml`, then a PTC turn | the one-line calls draw under the card; deleting the key folds them away |
|
|
871
|
+
| a turn whose step thinks and calls a tool before it answers | one blank row under the prompt, the thought and the calls it made as one group, and one blank row above the answer |
|
|
872
|
+
| `dsh-tui: { spacing: { padding: 0, messages: 0, steps: 0 } }` in `$DSH_HOME/settings.yaml`, then that turn | the conversation and the work board touch the window's edge and each other with no blank row anywhere, while the input bar still spans the full width; deleting the key draws the air again without a restart |
|
|
873
|
+
| `dsh-tui: { spacing: { padding: 3 } }` in `$DSH_HOME/settings.yaml`, then the same turn | the conversation and the work board move two columns further in on both sides, the input bar does not move, and the live session picks it up without a restart |
|
|
874
|
+
| a turn that leaves a todo, a job, or a delegation on the board | one blank row under the conversation and above the board's first row; with no work on the board nothing is drawn and the bar sits directly under the transcript |
|
|
875
|
+
| `dsh-tui: { spacing: { messages: 3 } }` in `$DSH_HOME/settings.yaml`, then a prompt | three blank rows above and below it, and the reply's three rows meet them as three rather than six |
|
|
846
876
|
| a thought, folded | a click on the row opens the thought under its summary; a click on the body folds it back, and the other thoughts keep their own state |
|
|
847
877
|
| a bash card, then a click on it | the row opens to its command, its retained output, and its exit status; a click folds it back to one row |
|
|
848
878
|
| a bash command that exits non-zero | the same row as any other failure: the tool's name in the failed colour, with the `exit 1` it ended on |
|
|
@@ -882,8 +912,9 @@ The automated checks drive a real PTY, but they run on this machine's terminal.
|
|
|
882
912
|
| type a prompt without sending it, then answer a question | the prompt bar steps aside while the question is open and holds the same prompt again afterwards |
|
|
883
913
|
| `echo hi \| dsh --profile tui` | refuses with a non-zero exit and a message naming the TTY requirement |
|
|
884
914
|
| `/stash`, `/stash-pop` in one terminal | the footer shows `stash 1` after the stash and the draft returns to the editor after the pop |
|
|
885
|
-
| a second `dsh --profile tui` in the same directory | `/stash-list`
|
|
886
|
-
|
|
|
915
|
+
| a second `dsh --profile tui` in the same directory | `/stash-list` shows the first terminal's drafts; a pop removes the shared draft from both banks |
|
|
916
|
+
| `stash.scope: session` in the TUI row, then a second session in the same directory | `/stash-list` says `no stashed drafts` in the second session |
|
|
917
|
+
| `/quit`, then `dsh --profile tui --resume=<id>` | `/stash-list` still shows the draft parked in that directory |
|
|
887
918
|
| hand-edit `$DSH_HOME/tui-stash/<key>.json` into invalid JSON, then `/stash-list` | the surface reports the quarantine path, starts empty, and leaves the moved file readable |
|
|
888
919
|
| `ctrl+x` then `e` with `$VISUAL` set to your editor | the alternate screen gives way to that editor with the draft in it; saving returns to the same frame with what was saved in the bar, and nothing is submitted |
|
|
889
920
|
| the same with `$VISUAL` and `$EDITOR` unset | the draft stays in the bar, and a notice names the variables to set |
|
package/lib/agent/history.d.ts
CHANGED
|
@@ -34,8 +34,6 @@ export interface SessionHistory {
|
|
|
34
34
|
export declare const PICKER_LIMIT = 30;
|
|
35
35
|
/** Events read to title one session: enough to reach its title or first prompt. */
|
|
36
36
|
export declare const TITLE_EVENT_LIMIT = 40;
|
|
37
|
-
/** Longest session title the picker shows, before the row can no longer hold it. */
|
|
38
|
-
export declare const TITLE_CHAR_LIMIT = 72;
|
|
39
37
|
/** Events read to resolve a session's preset: a selection sits in its blank prefix. */
|
|
40
38
|
export declare const PRESET_EVENT_LIMIT = 40;
|
|
41
39
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAA;IACtD,oEAAoE;IACpE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAA;IAClH,sFAAsF;IACtF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAA;CACtD;AAED,mEAAmE;AACnE,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAAA;IACtD,oEAAoE;IACpE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAA;IAClH,sFAAsF;IACtF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAA;CACtD;AAED,mEAAmE;AACnE,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,KAAK,CAAA;AAKnC,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,KAAK,CAAA;AA0BpC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,SAAmB,GAAG,MAAM,GAAG,SAAS,CAwBzG;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAQnH;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS5G;AAmBD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAsD7E"}
|
package/lib/agent/history.js
CHANGED
|
@@ -3,7 +3,7 @@ export const PICKER_LIMIT = 30;
|
|
|
3
3
|
/** Events read to title one session: enough to reach its title or first prompt. */
|
|
4
4
|
export const TITLE_EVENT_LIMIT = 40;
|
|
5
5
|
/** Longest session title the picker shows, before the row can no longer hold it. */
|
|
6
|
-
|
|
6
|
+
const TITLE_CHAR_LIMIT = 72;
|
|
7
7
|
/** Events read to resolve a session's preset: a selection sits in its blank prefix. */
|
|
8
8
|
export const PRESET_EVENT_LIMIT = 40;
|
|
9
9
|
function asRecord(value) {
|
package/lib/agent/history.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"AAkCA,mEAAmE;AACnE,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAE9B,mFAAmF;AACnF,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAEnC,oFAAoF;AACpF,MAAM,
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"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"}
|
package/lib/agent/host.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
2
|
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
3
3
|
import { type SessionId } from '@deepseek-ai/dsh-session';
|
|
4
|
-
import { ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
5
4
|
/** Everything the terminal surface needs to own one interactive agent. */
|
|
6
5
|
export interface TuiAgent {
|
|
7
6
|
readonly sessionId: SessionId;
|
|
@@ -48,30 +47,6 @@ export interface StartAgentOptions {
|
|
|
48
47
|
*/
|
|
49
48
|
readonly preset?: string | undefined;
|
|
50
49
|
}
|
|
51
|
-
/**
|
|
52
|
-
* The route an agent starts on.
|
|
53
|
-
*
|
|
54
|
-
* A launch flag is explicit, so it stands alone; otherwise the deployment
|
|
55
|
-
* default supplies the whole selection, effort included. The effort has to
|
|
56
|
-
* travel with the route here because an absent one is what the reader sees in
|
|
57
|
-
* the status line but never reaches a request.
|
|
58
|
-
*/
|
|
59
|
-
export declare function agentRoute(ctx: Context, options: Pick<StartAgentOptions, 'model' | 'provider'>): {
|
|
60
|
-
provider?: string;
|
|
61
|
-
model?: string;
|
|
62
|
-
reasoningEffort?: ReasoningEffortId;
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Whether a refused resume means the session simply has no durable log yet.
|
|
66
|
-
*
|
|
67
|
-
* Matched by the harness's stable error name rather than a class import: the
|
|
68
|
-
* surface mounts a compatible release RANGE, so the persistence package it
|
|
69
|
-
* would import is not necessarily the one behind the refusal. Any other
|
|
70
|
-
* failure — a composition that will not mount, an unreadable log — has to
|
|
71
|
-
* surface as itself, because falling back to a create hides it behind the
|
|
72
|
-
* identity collision of a session that does exist.
|
|
73
|
-
*/
|
|
74
|
-
export declare function absentSession(error: unknown): boolean;
|
|
75
50
|
/**
|
|
76
51
|
* Create or resume the one agent this surface drives.
|
|
77
52
|
*
|
package/lib/agent/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/agent/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/agent/host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAuC,KAAK,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAG9F,0EAA0E;AAC1E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,yDAAyD;IACzD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,8DAA8D;IAC9D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,0DAA0D;IAC1D,SAAS,IAAI,IAAI,CAAA;IACjB,6CAA6C;IAC7C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC;AAED,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;IAC5C,iFAAiF;IACjF,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACrC;AAkDD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoC5F"}
|
package/lib/agent/host.js
CHANGED
|
@@ -8,7 +8,7 @@ import { ReasoningEffortId, createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
|
8
8
|
* travel with the route here because an absent one is what the reader sees in
|
|
9
9
|
* the status line but never reaches a request.
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
function agentRoute(ctx, options) {
|
|
12
12
|
if (options.model !== undefined || options.provider !== undefined) {
|
|
13
13
|
return {
|
|
14
14
|
...(options.provider === undefined ? {} : { provider: options.provider }),
|
|
@@ -36,7 +36,7 @@ export function agentRoute(ctx, options) {
|
|
|
36
36
|
* surface as itself, because falling back to a create hides it behind the
|
|
37
37
|
* identity collision of a session that does exist.
|
|
38
38
|
*/
|
|
39
|
-
|
|
39
|
+
function absentSession(error) {
|
|
40
40
|
return error instanceof Error && error.name === 'SessionPersistenceNotFoundError';
|
|
41
41
|
}
|
|
42
42
|
function userMessage(text) {
|
package/lib/agent/host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/agent/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAqC,MAAM,0BAA0B,CAAA;AAC9F,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAmD3E;;;;;;;GAOG;AACH,
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/agent/host.ts"],"names":[],"mappings":"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"}
|
package/lib/agent/model.d.ts
CHANGED
|
@@ -86,9 +86,6 @@ export declare class ModelSwitch {
|
|
|
86
86
|
* picker choice must never be overwritten by it.
|
|
87
87
|
*/
|
|
88
88
|
adopt(choice: ModelChoice): void;
|
|
89
|
-
/** Forget the choice, so the session returns to the composition default. */
|
|
90
|
-
reset(): void;
|
|
91
|
-
dispose(): void;
|
|
92
89
|
}
|
|
93
90
|
/** The reasoning levels one exact route offers, described structurally. */
|
|
94
91
|
export interface ModelEfforts {
|
|
@@ -99,13 +96,48 @@ export interface ModelEfforts {
|
|
|
99
96
|
}[];
|
|
100
97
|
readonly defaultEffort?: string;
|
|
101
98
|
}
|
|
102
|
-
/**
|
|
103
|
-
export
|
|
99
|
+
/** The advisory catalog of routes this composition can reach. */
|
|
100
|
+
export interface ModelCatalog {
|
|
104
101
|
providers(): readonly ProviderEntry[];
|
|
105
102
|
models(provider: string): Promise<readonly {
|
|
106
103
|
readonly id: string;
|
|
107
104
|
readonly name: string;
|
|
108
105
|
}[]>;
|
|
109
106
|
efforts(provider: string, model: string): Promise<ModelEfforts | undefined>;
|
|
110
|
-
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Why a composition cannot answer with a model catalog.
|
|
110
|
+
*
|
|
111
|
+
* Both causes leave the catalog undefined, but they ask for different fixes: one
|
|
112
|
+
* means nothing is mounted, the other that the mounted llm predates the directory
|
|
113
|
+
* method, so a reader told only "no llm service" is sent to install what they
|
|
114
|
+
* already run.
|
|
115
|
+
*/
|
|
116
|
+
export type ModelCatalogGap = 'no_llm_service' | 'llm_without_provider_listing';
|
|
117
|
+
/**
|
|
118
|
+
* The cause half of every refusal a gap is reported with.
|
|
119
|
+
*
|
|
120
|
+
* One owner for these words, because more than one command answers the same two
|
|
121
|
+
* causes: the model list, the effort picker and `list-models` each add their own
|
|
122
|
+
* verb, and a second copy of a cause is how a reader ends up told to install a
|
|
123
|
+
* service they already run.
|
|
124
|
+
*/
|
|
125
|
+
export declare const MODEL_CATALOG_GAP_CAUSE: Record<ModelCatalogGap, string>;
|
|
126
|
+
/** Either the catalog or the reason there is none, never both. */
|
|
127
|
+
export type ModelCatalogReading = {
|
|
128
|
+
readonly kind: 'ready';
|
|
129
|
+
readonly catalog: ModelCatalog;
|
|
130
|
+
} | {
|
|
131
|
+
readonly kind: 'gap';
|
|
132
|
+
readonly gap: ModelCatalogGap;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Read the advisory catalog of routes this composition can reach.
|
|
136
|
+
*
|
|
137
|
+
* The reason travels beside the catalog so a caller that refuses can say which
|
|
138
|
+
* cause it met; a caller that only wants routes reads `createModelCatalog`.
|
|
139
|
+
*/
|
|
140
|
+
export declare function readModelCatalog(ctx: Context): ModelCatalogReading;
|
|
141
|
+
/** The catalog alone, for a caller that has no refusal to word. */
|
|
142
|
+
export declare function createModelCatalog(ctx: Context): ModelCatalog | undefined;
|
|
111
143
|
//# sourceMappingURL=model.d.ts.map
|
package/lib/agent/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAClC;AAED,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,uDAAuD;AACvD,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,aAAa,EAAE,EACnC,OAAO,EAAE,WAAW,GAAG,SAAS,GAC/B,YAAY,CAyBd;AAYD,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAElG;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAI9F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAajG;AAED;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkE;IAC5F,OAAO,CAAC,SAAS,CAA0B;IAE3C,sFAAsF;IACtF,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAKhC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAUjC,OAAO,IAAI,WAAW,GAAG,SAAS;IAUlC;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"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"}
|
package/lib/agent/model.js
CHANGED
|
@@ -129,23 +129,41 @@ export class ModelSwitch {
|
|
|
129
129
|
return;
|
|
130
130
|
this.choose(choice);
|
|
131
131
|
}
|
|
132
|
-
/** Forget the choice, so the session returns to the composition default. */
|
|
133
|
-
reset() {
|
|
134
|
-
this.selection.current = undefined;
|
|
135
|
-
this.selection.assembled = undefined;
|
|
136
|
-
}
|
|
137
|
-
dispose() {
|
|
138
|
-
this.installed?.();
|
|
139
|
-
this.installed = undefined;
|
|
140
|
-
}
|
|
141
132
|
}
|
|
142
|
-
/**
|
|
143
|
-
|
|
133
|
+
/**
|
|
134
|
+
* The cause half of every refusal a gap is reported with.
|
|
135
|
+
*
|
|
136
|
+
* One owner for these words, because more than one command answers the same two
|
|
137
|
+
* causes: the model list, the effort picker and `list-models` each add their own
|
|
138
|
+
* verb, and a second copy of a cause is how a reader ends up told to install a
|
|
139
|
+
* service they already run.
|
|
140
|
+
*/
|
|
141
|
+
export const MODEL_CATALOG_GAP_CAUSE = {
|
|
142
|
+
no_llm_service: 'this profile has no llm service',
|
|
143
|
+
llm_without_provider_listing: 'the llm service this profile mounts cannot list providers',
|
|
144
|
+
};
|
|
145
|
+
/** The one read of the llm service, which is the only place the two causes differ. */
|
|
146
|
+
function readLlmService(ctx) {
|
|
144
147
|
const llm = ctx.get('llm');
|
|
145
|
-
if (
|
|
146
|
-
return
|
|
148
|
+
if (llm === undefined || llm === null)
|
|
149
|
+
return { kind: 'gap', gap: 'no_llm_service' };
|
|
150
|
+
if (typeof llm.listProviders !== 'function')
|
|
151
|
+
return { kind: 'gap', gap: 'llm_without_provider_listing' };
|
|
152
|
+
return { kind: 'ready', llm };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Read the advisory catalog of routes this composition can reach.
|
|
156
|
+
*
|
|
157
|
+
* The reason travels beside the catalog so a caller that refuses can say which
|
|
158
|
+
* cause it met; a caller that only wants routes reads `createModelCatalog`.
|
|
159
|
+
*/
|
|
160
|
+
export function readModelCatalog(ctx) {
|
|
161
|
+
const reading = readLlmService(ctx);
|
|
162
|
+
if (reading.kind === 'gap')
|
|
163
|
+
return { kind: 'gap', gap: reading.gap };
|
|
164
|
+
const llm = reading.llm;
|
|
147
165
|
const providers = () => (llm.listProviders?.() ?? []).flatMap(entry => typeof entry.id === 'string' ? [{ id: entry.id, name: typeof entry.name === 'string' ? entry.name : entry.id }] : []);
|
|
148
|
-
|
|
166
|
+
const catalog = {
|
|
149
167
|
providers,
|
|
150
168
|
models: async (provider) => {
|
|
151
169
|
if (typeof llm.listModels !== 'function')
|
|
@@ -174,5 +192,11 @@ export function createModelCatalog(ctx) {
|
|
|
174
192
|
};
|
|
175
193
|
},
|
|
176
194
|
};
|
|
195
|
+
return { kind: 'ready', catalog };
|
|
196
|
+
}
|
|
197
|
+
/** The catalog alone, for a caller that has no refusal to word. */
|
|
198
|
+
export function createModelCatalog(ctx) {
|
|
199
|
+
const reading = readModelCatalog(ctx);
|
|
200
|
+
return reading.kind === 'ready' ? reading.catalog : undefined;
|
|
177
201
|
}
|
|
178
202
|
//# sourceMappingURL=model.js.map
|