@dsh-cc/tui 0.5.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/LICENSE +201 -0
- package/README.md +144 -0
- package/lib/bash-history.d.ts +31 -0
- package/lib/bash-history.d.ts.map +1 -0
- package/lib/bash-history.js +94 -0
- package/lib/bash-history.js.map +1 -0
- package/lib/compact-fold.d.ts +35 -0
- package/lib/compact-fold.d.ts.map +1 -0
- package/lib/compact-fold.js +60 -0
- package/lib/compact-fold.js.map +1 -0
- package/lib/components/arg-completers.d.ts +22 -0
- package/lib/components/arg-completers.d.ts.map +1 -0
- package/lib/components/arg-completers.js +75 -0
- package/lib/components/arg-completers.js.map +1 -0
- package/lib/components/code-theme.d.ts +25 -0
- package/lib/components/code-theme.d.ts.map +1 -0
- package/lib/components/code-theme.js +137 -0
- package/lib/components/code-theme.js.map +1 -0
- package/lib/components/completion.d.ts +50 -0
- package/lib/components/completion.d.ts.map +1 -0
- package/lib/components/completion.js +279 -0
- package/lib/components/completion.js.map +1 -0
- package/lib/components/diff-card.d.ts +29 -0
- package/lib/components/diff-card.d.ts.map +1 -0
- package/lib/components/diff-card.js +175 -0
- package/lib/components/diff-card.js.map +1 -0
- package/lib/components/diff-hunks.d.ts +44 -0
- package/lib/components/diff-hunks.d.ts.map +1 -0
- package/lib/components/diff-hunks.js +188 -0
- package/lib/components/diff-hunks.js.map +1 -0
- package/lib/components/editor-history.d.ts +23 -0
- package/lib/components/editor-history.d.ts.map +1 -0
- package/lib/components/editor-history.js +29 -0
- package/lib/components/editor-history.js.map +1 -0
- package/lib/components/markdown-theme.d.ts +11 -0
- package/lib/components/markdown-theme.d.ts.map +1 -0
- package/lib/components/markdown-theme.js +29 -0
- package/lib/components/markdown-theme.js.map +1 -0
- package/lib/components/masked-input.d.ts +24 -0
- package/lib/components/masked-input.d.ts.map +1 -0
- package/lib/components/masked-input.js +168 -0
- package/lib/components/masked-input.js.map +1 -0
- package/lib/components/overlay-host.d.ts +31 -0
- package/lib/components/overlay-host.d.ts.map +1 -0
- package/lib/components/overlay-host.js +128 -0
- package/lib/components/overlay-host.js.map +1 -0
- package/lib/components/overlays.d.ts +94 -0
- package/lib/components/overlays.d.ts.map +1 -0
- package/lib/components/overlays.js +450 -0
- package/lib/components/overlays.js.map +1 -0
- package/lib/components/provider-box.d.ts +23 -0
- package/lib/components/provider-box.d.ts.map +1 -0
- package/lib/components/provider-box.js +164 -0
- package/lib/components/provider-box.js.map +1 -0
- package/lib/components/read-group.d.ts +51 -0
- package/lib/components/read-group.d.ts.map +1 -0
- package/lib/components/read-group.js +105 -0
- package/lib/components/read-group.js.map +1 -0
- package/lib/components/root-bash.d.ts +36 -0
- package/lib/components/root-bash.d.ts.map +1 -0
- package/lib/components/root-bash.js +112 -0
- package/lib/components/root-bash.js.map +1 -0
- package/lib/components/root-types.d.ts +42 -0
- package/lib/components/root-types.d.ts.map +1 -0
- package/lib/components/root-types.js +8 -0
- package/lib/components/root-types.js.map +1 -0
- package/lib/components/root-utils.d.ts +22 -0
- package/lib/components/root-utils.d.ts.map +1 -0
- package/lib/components/root-utils.js +45 -0
- package/lib/components/root-utils.js.map +1 -0
- package/lib/components/root.d.ts +25 -0
- package/lib/components/root.d.ts.map +1 -0
- package/lib/components/root.js +357 -0
- package/lib/components/root.js.map +1 -0
- package/lib/components/theme.d.ts +61 -0
- package/lib/components/theme.d.ts.map +1 -0
- package/lib/components/theme.js +99 -0
- package/lib/components/theme.js.map +1 -0
- package/lib/components/transcript.d.ts +43 -0
- package/lib/components/transcript.d.ts.map +1 -0
- package/lib/components/transcript.js +203 -0
- package/lib/components/transcript.js.map +1 -0
- package/lib/components/working-line.d.ts +35 -0
- package/lib/components/working-line.d.ts.map +1 -0
- package/lib/components/working-line.js +66 -0
- package/lib/components/working-line.js.map +1 -0
- package/lib/effort-catalog.d.ts +27 -0
- package/lib/effort-catalog.d.ts.map +1 -0
- package/lib/effort-catalog.js +36 -0
- package/lib/effort-catalog.js.map +1 -0
- package/lib/export-markdown.d.ts +18 -0
- package/lib/export-markdown.d.ts.map +1 -0
- package/lib/export-markdown.js +124 -0
- package/lib/export-markdown.js.map +1 -0
- package/lib/harness/approval-preview.d.ts +33 -0
- package/lib/harness/approval-preview.d.ts.map +1 -0
- package/lib/harness/approval-preview.js +179 -0
- package/lib/harness/approval-preview.js.map +1 -0
- package/lib/harness/boot-banner.d.ts +14 -0
- package/lib/harness/boot-banner.d.ts.map +1 -0
- package/lib/harness/boot-banner.js +89 -0
- package/lib/harness/boot-banner.js.map +1 -0
- package/lib/harness/driver-agent.d.ts +78 -0
- package/lib/harness/driver-agent.d.ts.map +1 -0
- package/lib/harness/driver-agent.js +314 -0
- package/lib/harness/driver-agent.js.map +1 -0
- package/lib/harness/driver-agents.d.ts +20 -0
- package/lib/harness/driver-agents.d.ts.map +1 -0
- package/lib/harness/driver-agents.js +123 -0
- package/lib/harness/driver-agents.js.map +1 -0
- package/lib/harness/driver-approvals.d.ts +38 -0
- package/lib/harness/driver-approvals.d.ts.map +1 -0
- package/lib/harness/driver-approvals.js +277 -0
- package/lib/harness/driver-approvals.js.map +1 -0
- package/lib/harness/driver-bash.d.ts +15 -0
- package/lib/harness/driver-bash.d.ts.map +1 -0
- package/lib/harness/driver-bash.js +73 -0
- package/lib/harness/driver-bash.js.map +1 -0
- package/lib/harness/driver-catalog.d.ts +84 -0
- package/lib/harness/driver-catalog.d.ts.map +1 -0
- package/lib/harness/driver-catalog.js +256 -0
- package/lib/harness/driver-catalog.js.map +1 -0
- package/lib/harness/driver-ctx.d.ts +462 -0
- package/lib/harness/driver-ctx.d.ts.map +1 -0
- package/lib/harness/driver-ctx.js +11 -0
- package/lib/harness/driver-ctx.js.map +1 -0
- package/lib/harness/driver-hud.d.ts +31 -0
- package/lib/harness/driver-hud.d.ts.map +1 -0
- package/lib/harness/driver-hud.js +204 -0
- package/lib/harness/driver-hud.js.map +1 -0
- package/lib/harness/driver-live.d.ts +36 -0
- package/lib/harness/driver-live.d.ts.map +1 -0
- package/lib/harness/driver-live.js +44 -0
- package/lib/harness/driver-live.js.map +1 -0
- package/lib/harness/driver-modal.d.ts +52 -0
- package/lib/harness/driver-modal.d.ts.map +1 -0
- package/lib/harness/driver-modal.js +78 -0
- package/lib/harness/driver-modal.js.map +1 -0
- package/lib/harness/driver-mode.d.ts +35 -0
- package/lib/harness/driver-mode.d.ts.map +1 -0
- package/lib/harness/driver-mode.js +84 -0
- package/lib/harness/driver-mode.js.map +1 -0
- package/lib/harness/driver-pickers.d.ts +48 -0
- package/lib/harness/driver-pickers.d.ts.map +1 -0
- package/lib/harness/driver-pickers.js +249 -0
- package/lib/harness/driver-pickers.js.map +1 -0
- package/lib/harness/driver-promote.d.ts +29 -0
- package/lib/harness/driver-promote.d.ts.map +1 -0
- package/lib/harness/driver-promote.js +36 -0
- package/lib/harness/driver-promote.js.map +1 -0
- package/lib/harness/driver-queue.d.ts +19 -0
- package/lib/harness/driver-queue.d.ts.map +1 -0
- package/lib/harness/driver-queue.js +281 -0
- package/lib/harness/driver-queue.js.map +1 -0
- package/lib/harness/driver-run-local.d.ts +32 -0
- package/lib/harness/driver-run-local.d.ts.map +1 -0
- package/lib/harness/driver-run-local.js +366 -0
- package/lib/harness/driver-run-local.js.map +1 -0
- package/lib/harness/driver-sessions.d.ts +28 -0
- package/lib/harness/driver-sessions.d.ts.map +1 -0
- package/lib/harness/driver-sessions.js +386 -0
- package/lib/harness/driver-sessions.js.map +1 -0
- package/lib/harness/driver.d.ts +22 -0
- package/lib/harness/driver.d.ts.map +1 -0
- package/lib/harness/driver.js +459 -0
- package/lib/harness/driver.js.map +1 -0
- package/lib/harness/preset.d.ts +32 -0
- package/lib/harness/preset.d.ts.map +1 -0
- package/lib/harness/preset.js +34 -0
- package/lib/harness/preset.js.map +1 -0
- package/lib/harness/session-list.d.ts +65 -0
- package/lib/harness/session-list.d.ts.map +1 -0
- package/lib/harness/session-list.js +91 -0
- package/lib/harness/session-list.js.map +1 -0
- package/lib/harness/shell-output.d.ts +44 -0
- package/lib/harness/shell-output.d.ts.map +1 -0
- package/lib/harness/shell-output.js +90 -0
- package/lib/harness/shell-output.js.map +1 -0
- package/lib/harness/statusline-cc-transcript.d.ts +51 -0
- package/lib/harness/statusline-cc-transcript.d.ts.map +1 -0
- package/lib/harness/statusline-cc-transcript.js +191 -0
- package/lib/harness/statusline-cc-transcript.js.map +1 -0
- package/lib/harness/statusline-command.d.ts +54 -0
- package/lib/harness/statusline-command.d.ts.map +1 -0
- package/lib/harness/statusline-command.js +161 -0
- package/lib/harness/statusline-command.js.map +1 -0
- package/lib/harness/statusline-payload.d.ts +79 -0
- package/lib/harness/statusline-payload.d.ts.map +1 -0
- package/lib/harness/statusline-payload.js +93 -0
- package/lib/harness/statusline-payload.js.map +1 -0
- package/lib/harness/statusline-settings.d.ts +47 -0
- package/lib/harness/statusline-settings.d.ts.map +1 -0
- package/lib/harness/statusline-settings.js +57 -0
- package/lib/harness/statusline-settings.js.map +1 -0
- package/lib/harness/statusline-wiring.d.ts +45 -0
- package/lib/harness/statusline-wiring.d.ts.map +1 -0
- package/lib/harness/statusline-wiring.js +247 -0
- package/lib/harness/statusline-wiring.js.map +1 -0
- package/lib/harness/usage-view.d.ts +84 -0
- package/lib/harness/usage-view.d.ts.map +1 -0
- package/lib/harness/usage-view.js +199 -0
- package/lib/harness/usage-view.js.map +1 -0
- package/lib/harness/worktree-exit.d.ts +105 -0
- package/lib/harness/worktree-exit.d.ts.map +1 -0
- package/lib/harness/worktree-exit.js +168 -0
- package/lib/harness/worktree-exit.js.map +1 -0
- package/lib/history.d.ts +50 -0
- package/lib/history.d.ts.map +1 -0
- package/lib/history.js +139 -0
- package/lib/history.js.map +1 -0
- package/lib/index.d.ts +63 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +54 -0
- package/lib/index.js.map +1 -0
- package/lib/input.d.ts +158 -0
- package/lib/input.d.ts.map +1 -0
- package/lib/input.js +400 -0
- package/lib/input.js.map +1 -0
- package/lib/invariant.d.ts +14 -0
- package/lib/invariant.d.ts.map +1 -0
- package/lib/invariant.js +20 -0
- package/lib/invariant.js.map +1 -0
- package/lib/mode-cycle.d.ts +22 -0
- package/lib/mode-cycle.d.ts.map +1 -0
- package/lib/mode-cycle.js +32 -0
- package/lib/mode-cycle.js.map +1 -0
- package/lib/model-catalog.d.ts +22 -0
- package/lib/model-catalog.d.ts.map +1 -0
- package/lib/model-catalog.js +45 -0
- package/lib/model-catalog.js.map +1 -0
- package/lib/packaged-preset.d.ts +32 -0
- package/lib/packaged-preset.d.ts.map +1 -0
- package/lib/packaged-preset.js +94 -0
- package/lib/packaged-preset.js.map +1 -0
- package/lib/plugin.d.ts +11 -0
- package/lib/plugin.d.ts.map +1 -0
- package/lib/plugin.js +88 -0
- package/lib/plugin.js.map +1 -0
- package/lib/profile.d.ts +4 -0
- package/lib/profile.d.ts.map +1 -0
- package/lib/profile.js +7 -0
- package/lib/profile.js.map +1 -0
- package/lib/project-sessions.d.ts +29 -0
- package/lib/project-sessions.d.ts.map +1 -0
- package/lib/project-sessions.js +60 -0
- package/lib/project-sessions.js.map +1 -0
- package/lib/project.d.ts +75 -0
- package/lib/project.d.ts.map +1 -0
- package/lib/project.js +196 -0
- package/lib/project.js.map +1 -0
- package/lib/provider-actions.d.ts +37 -0
- package/lib/provider-actions.d.ts.map +1 -0
- package/lib/provider-actions.js +417 -0
- package/lib/provider-actions.js.map +1 -0
- package/lib/provider-command.d.ts +109 -0
- package/lib/provider-command.d.ts.map +1 -0
- package/lib/provider-command.js +220 -0
- package/lib/provider-command.js.map +1 -0
- package/lib/provider-detail.d.ts +15 -0
- package/lib/provider-detail.d.ts.map +1 -0
- package/lib/provider-detail.js +201 -0
- package/lib/provider-detail.js.map +1 -0
- package/lib/provider-flow.d.ts +191 -0
- package/lib/provider-flow.d.ts.map +1 -0
- package/lib/provider-flow.js +192 -0
- package/lib/provider-flow.js.map +1 -0
- package/lib/provider-presets.d.ts +32 -0
- package/lib/provider-presets.d.ts.map +1 -0
- package/lib/provider-presets.js +105 -0
- package/lib/provider-presets.js.map +1 -0
- package/lib/provider-read.d.ts +63 -0
- package/lib/provider-read.d.ts.map +1 -0
- package/lib/provider-read.js +115 -0
- package/lib/provider-read.js.map +1 -0
- package/lib/provider-settings.d.ts +30 -0
- package/lib/provider-settings.d.ts.map +1 -0
- package/lib/provider-settings.js +65 -0
- package/lib/provider-settings.js.map +1 -0
- package/lib/resume-target.d.ts +59 -0
- package/lib/resume-target.d.ts.map +1 -0
- package/lib/resume-target.js +143 -0
- package/lib/resume-target.js.map +1 -0
- package/lib/slash.d.ts +44 -0
- package/lib/slash.d.ts.map +1 -0
- package/lib/slash.js +81 -0
- package/lib/slash.js.map +1 -0
- package/lib/state/driver-types.d.ts +505 -0
- package/lib/state/driver-types.d.ts.map +1 -0
- package/lib/state/driver-types.js +8 -0
- package/lib/state/driver-types.js.map +1 -0
- package/lib/state/driver-usage-types.d.ts +59 -0
- package/lib/state/driver-usage-types.d.ts.map +1 -0
- package/lib/state/driver-usage-types.js +8 -0
- package/lib/state/driver-usage-types.js.map +1 -0
- package/lib/statusline.d.ts +63 -0
- package/lib/statusline.d.ts.map +1 -0
- package/lib/statusline.js +97 -0
- package/lib/statusline.js.map +1 -0
- package/lib/store/pickers.d.ts +34 -0
- package/lib/store/pickers.d.ts.map +1 -0
- package/lib/store/pickers.js +111 -0
- package/lib/store/pickers.js.map +1 -0
- package/lib/store/provider-panel.d.ts +107 -0
- package/lib/store/provider-panel.d.ts.map +1 -0
- package/lib/store/provider-panel.js +151 -0
- package/lib/store/provider-panel.js.map +1 -0
- package/lib/store/question.d.ts +21 -0
- package/lib/store/question.d.ts.map +1 -0
- package/lib/store/question.js +59 -0
- package/lib/store/question.js.map +1 -0
- package/lib/store/queue.d.ts +27 -0
- package/lib/store/queue.d.ts.map +1 -0
- package/lib/store/queue.js +34 -0
- package/lib/store/queue.js.map +1 -0
- package/lib/store/session.d.ts +73 -0
- package/lib/store/session.d.ts.map +1 -0
- package/lib/store/session.js +172 -0
- package/lib/store/session.js.map +1 -0
- package/lib/store/subagents.d.ts +16 -0
- package/lib/store/subagents.d.ts.map +1 -0
- package/lib/store/subagents.js +44 -0
- package/lib/store/subagents.js.map +1 -0
- package/lib/store/todos.d.ts +35 -0
- package/lib/store/todos.d.ts.map +1 -0
- package/lib/store/todos.js +68 -0
- package/lib/store/todos.js.map +1 -0
- package/lib/store/usage.d.ts +15 -0
- package/lib/store/usage.d.ts.map +1 -0
- package/lib/store/usage.js +27 -0
- package/lib/store/usage.js.map +1 -0
- package/lib/store/views.d.ts +419 -0
- package/lib/store/views.d.ts.map +1 -0
- package/lib/store/views.js +3 -0
- package/lib/store/views.js.map +1 -0
- package/lib/store.d.ts +19 -0
- package/lib/store.d.ts.map +1 -0
- package/lib/store.js +10 -0
- package/lib/store.js.map +1 -0
- package/lib/terminal/lease.d.ts +33 -0
- package/lib/terminal/lease.d.ts.map +1 -0
- package/lib/terminal/lease.js +99 -0
- package/lib/terminal/lease.js.map +1 -0
- package/lib/tool-card.d.ts +75 -0
- package/lib/tool-card.d.ts.map +1 -0
- package/lib/tool-card.js +109 -0
- package/lib/tool-card.js.map +1 -0
- package/lib/tool-verbs.d.ts +12 -0
- package/lib/tool-verbs.d.ts.map +1 -0
- package/lib/tool-verbs.js +29 -0
- package/lib/tool-verbs.js.map +1 -0
- package/lib/transcript.d.ts +40 -0
- package/lib/transcript.d.ts.map +1 -0
- package/lib/transcript.js +413 -0
- package/lib/transcript.js.map +1 -0
- package/lib/working-line.d.ts +44 -0
- package/lib/working-line.d.ts.map +1 -0
- package/lib/working-line.js +56 -0
- package/lib/working-line.js.map +1 -0
- package/package.json +72 -0
- package/presets/cc/.dsh-cc-managed.json +5 -0
- package/presets/cc/agent.cordis.yml +524 -0
- package/presets/cc/preset.yml +3 -0
- package/scripts/stage-preset.mjs +26 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statusline HUD + sessionProjections feed for the TUI driver.
|
|
3
|
+
*
|
|
4
|
+
* Migrated out of createDriver (harness/driver.ts) as a free-function
|
|
5
|
+
* collaborator so the factory stays under the line budget. Receives a
|
|
6
|
+
* structural {@link DriverHudCtx} instead of importing the factory (no cycle).
|
|
7
|
+
*
|
|
8
|
+
* Owned state: the git-branch probe result, the sessionProjections handle, and
|
|
9
|
+
* the derived HUD patch path. Exposes back to createDriver the pieces the
|
|
10
|
+
* factory (runLocal usage panel) and switchSession still need: applyUsage,
|
|
11
|
+
* projections, statusLineOf, seedHud, seedTodos, refreshBranch.
|
|
12
|
+
* @module @dsh-cc/tui/harness/driver-hud
|
|
13
|
+
*/
|
|
14
|
+
import { setHud, setTodos, setTurnActive, setUsage, } from "../store.js";
|
|
15
|
+
import { breakdownOf, occupancyOf, percentOf, sameTodos, sameUsage, todosOf, tokensOf, totalsOf, usageViewOf, } from "./usage-view.js";
|
|
16
|
+
import { formatModeLine, formatStatusLine } from "../statusline.js";
|
|
17
|
+
import { truncateToWidth } from '@dsh-cc/pi-tui';
|
|
18
|
+
/**
|
|
19
|
+
* Build the statusline HUD section. Runs the boot sequence on construction —
|
|
20
|
+
* in original order: branch probe, seed HUD/todos from live projections, anchor
|
|
21
|
+
* the working line if busy, then subscribe to the change feed — so createDriver
|
|
22
|
+
* needs no extra call.
|
|
23
|
+
*/
|
|
24
|
+
export function createHudSection(rt) {
|
|
25
|
+
const { state, emit, ctx, cwd, current, selection, branchProbe, statusline } = rt;
|
|
26
|
+
// --- Branch: one best-effort probe at boot and after each switchSession (the
|
|
27
|
+
// cwd may differ per session). Async is fine — a late landing re-emits so
|
|
28
|
+
// the footer picks it up; a probe superseded by a switch is dropped by the
|
|
29
|
+
// sequence check. The probe never throws; failures just omit the segment.
|
|
30
|
+
// No timer, one probe per (re)bind — zero polling.
|
|
31
|
+
let branch;
|
|
32
|
+
let branchSeq = 0;
|
|
33
|
+
const refreshBranch = () => {
|
|
34
|
+
const seq = ++branchSeq;
|
|
35
|
+
const dir = current.agent.session.header.cwd ?? cwd;
|
|
36
|
+
void Promise.resolve(branchProbe(dir))
|
|
37
|
+
.catch(() => undefined)
|
|
38
|
+
.then(next => {
|
|
39
|
+
if (seq !== branchSeq || next === branch)
|
|
40
|
+
return;
|
|
41
|
+
branch = next;
|
|
42
|
+
// Same-reference emit: re-notifies subscribers so root re-reads the
|
|
43
|
+
// statusline getter with the fresh branch.
|
|
44
|
+
emit(state());
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
refreshBranch();
|
|
48
|
+
// Projections: seed once from stateOf (a resumed session may already be
|
|
49
|
+
// populated), then keep the hud fresh from the change feed — event-driven,
|
|
50
|
+
// filtered to the live session so late events from a disposed session are
|
|
51
|
+
// dropped by the id mismatch.
|
|
52
|
+
const projections = ctx.get('sessionProjections');
|
|
53
|
+
const applyHud = (patch) => {
|
|
54
|
+
const hud = state().hud;
|
|
55
|
+
const percentSame = patch.contextPercent === undefined || hud?.contextPercent === patch.contextPercent;
|
|
56
|
+
const tokens = patch.tokens;
|
|
57
|
+
const tokensSame = tokens === undefined
|
|
58
|
+
|| (hud?.tokens !== undefined && hud.tokens.input === tokens.input && hud.tokens.output === tokens.output);
|
|
59
|
+
const detail = patch.contextTokens;
|
|
60
|
+
const detailSame = detail === undefined
|
|
61
|
+
|| (hud?.contextTokens !== undefined
|
|
62
|
+
&& hud.contextTokens.used === detail.used
|
|
63
|
+
&& hud.contextTokens.window === detail.window);
|
|
64
|
+
if (percentSame && tokensSame && detailSame)
|
|
65
|
+
return; // emit only on an actual change
|
|
66
|
+
emit(setHud(state(), patch));
|
|
67
|
+
};
|
|
68
|
+
const applyUsage = (patch) => {
|
|
69
|
+
if (patch === undefined)
|
|
70
|
+
return;
|
|
71
|
+
const s = state();
|
|
72
|
+
const merged = { ...s.usage, ...patch };
|
|
73
|
+
if (sameUsage(s.usage, merged))
|
|
74
|
+
return;
|
|
75
|
+
emit(setUsage(s, merged));
|
|
76
|
+
};
|
|
77
|
+
const seedHud = () => {
|
|
78
|
+
statusline?.onRebind();
|
|
79
|
+
const s = state();
|
|
80
|
+
const patch = {};
|
|
81
|
+
if (projections !== undefined) {
|
|
82
|
+
const tokens = tokensOf(projections.stateOf(current.agent.session, 'tokenUsage'));
|
|
83
|
+
if (tokens !== undefined)
|
|
84
|
+
patch.tokens = tokens;
|
|
85
|
+
const pressure = projections.stateOf(current.agent.session, 'contextPressure');
|
|
86
|
+
const percent = percentOf(pressure);
|
|
87
|
+
if (percent !== undefined)
|
|
88
|
+
patch.contextPercent = percent;
|
|
89
|
+
const occupancy = occupancyOf(pressure);
|
|
90
|
+
if (occupancy !== undefined)
|
|
91
|
+
patch.contextTokens = occupancy;
|
|
92
|
+
}
|
|
93
|
+
// Replace wholesale: clear first so stale fields from a previous session
|
|
94
|
+
// never leak, then apply whatever the new session actually has.
|
|
95
|
+
let next = setHud(s, undefined);
|
|
96
|
+
if (patch.contextPercent !== undefined || patch.tokens !== undefined || patch.contextTokens !== undefined) {
|
|
97
|
+
next = setHud(next, patch);
|
|
98
|
+
}
|
|
99
|
+
if (next !== s)
|
|
100
|
+
emit(next);
|
|
101
|
+
};
|
|
102
|
+
// Todos: same seeding contract as the HUD — stateOf at (re)bind, then the
|
|
103
|
+
// change feed. Absent (`null` before the first write) clears the strip so
|
|
104
|
+
// no cross-session leak survives a switch.
|
|
105
|
+
const seedTodos = () => {
|
|
106
|
+
const s = state();
|
|
107
|
+
const value = projections === undefined
|
|
108
|
+
? undefined
|
|
109
|
+
: projections.stateOf(current.agent.session, 'todos');
|
|
110
|
+
const todos = todosOf(value);
|
|
111
|
+
if (sameTodos(s.todos, todos))
|
|
112
|
+
return;
|
|
113
|
+
emit(setTodos(s, todos));
|
|
114
|
+
};
|
|
115
|
+
seedHud();
|
|
116
|
+
seedTodos();
|
|
117
|
+
// Boot may resume a log that ended mid-turn (crashed process): the setBusy
|
|
118
|
+
// sync above flipped busy from the ground-truth agent status, so anchor the
|
|
119
|
+
// working line here — deliberately after seedHud, so outputBase reads the
|
|
120
|
+
// seeded token totals instead of pinning an unseeded baseline.
|
|
121
|
+
if (state().busy) {
|
|
122
|
+
emit(setTurnActive(state(), { startedAt: Date.now(), outputBase: state().hud?.tokens?.output }));
|
|
123
|
+
}
|
|
124
|
+
if (projections !== undefined) {
|
|
125
|
+
projections.onChanged((session, key, value) => {
|
|
126
|
+
if (session.id !== current.agent.session.id)
|
|
127
|
+
return;
|
|
128
|
+
statusline?.onProjection(key);
|
|
129
|
+
if (key === 'tokenUsage') {
|
|
130
|
+
const usage = value;
|
|
131
|
+
const tokens = tokensOf(usage);
|
|
132
|
+
if (tokens !== undefined)
|
|
133
|
+
applyHud({ tokens });
|
|
134
|
+
applyUsage(usageViewOf(totalsOf(usage), undefined, undefined));
|
|
135
|
+
// Working-line rebase guard: an anchor created before the HUD was
|
|
136
|
+
// seeded carries outputBase === undefined; the first tokenUsage
|
|
137
|
+
// change pins it. Strictly turn-MODIFYING (turn must already exist) —
|
|
138
|
+
// a tokenUsage emit while idle must never conjure a phantom anchor.
|
|
139
|
+
// setTurnActive re-derives verbIndex deterministically from the
|
|
140
|
+
// unchanged startedAt, so this is a pure baseline pin; the live
|
|
141
|
+
// stepStartedAt passes through so pinning never resets a mid-step
|
|
142
|
+
// clock.
|
|
143
|
+
const turn = state().turn;
|
|
144
|
+
if (turn !== undefined && turn.outputBase === undefined && tokens !== undefined) {
|
|
145
|
+
emit(setTurnActive(state(), { startedAt: turn.startedAt, outputBase: tokens.output, stepStartedAt: turn.stepStartedAt }));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if (key === 'contextPressure') {
|
|
149
|
+
const pressure = value;
|
|
150
|
+
const percent = percentOf(pressure);
|
|
151
|
+
const occupancy = occupancyOf(pressure);
|
|
152
|
+
if (percent === undefined && occupancy === undefined)
|
|
153
|
+
return;
|
|
154
|
+
applyHud({
|
|
155
|
+
...percent === undefined ? {} : { contextPercent: percent },
|
|
156
|
+
...occupancy === undefined ? {} : { contextTokens: occupancy },
|
|
157
|
+
});
|
|
158
|
+
applyUsage(usageViewOf(undefined, occupancy, undefined));
|
|
159
|
+
}
|
|
160
|
+
else if (key === 'todos') {
|
|
161
|
+
const todos = todosOf(value);
|
|
162
|
+
if (sameTodos(state().todos, todos))
|
|
163
|
+
return;
|
|
164
|
+
emit(setTodos(state(), todos));
|
|
165
|
+
}
|
|
166
|
+
else if (key === 'contextBreakdown') {
|
|
167
|
+
applyUsage(usageViewOf(undefined, undefined, breakdownOf(value)));
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const statusLineOf = (width) => {
|
|
172
|
+
// Custom statusLine (plan §3.2/D3/D4): active → the command's rows with
|
|
173
|
+
// padding plus a client-drawn mode row below; inactive → today's built-in
|
|
174
|
+
// line, byte-identical.
|
|
175
|
+
const custom = statusline?.override();
|
|
176
|
+
if (custom !== undefined) {
|
|
177
|
+
// Blank detection must trim: with padding > 0 an all-blank settle is
|
|
178
|
+
// whitespace, not ''. Blank → the mode row alone.
|
|
179
|
+
if (custom.trim().length === 0)
|
|
180
|
+
return formatModeLine(state().permissionMode);
|
|
181
|
+
const rows = custom.split('\n');
|
|
182
|
+
const clipped = width === undefined
|
|
183
|
+
? rows
|
|
184
|
+
: rows.map(row => truncateToWidth(row, width));
|
|
185
|
+
return `${clipped.join('\n')}\n${formatModeLine(state().permissionMode)}`;
|
|
186
|
+
}
|
|
187
|
+
const effort = selection.current?.reasoningEffort;
|
|
188
|
+
const s = state();
|
|
189
|
+
return formatStatusLine({
|
|
190
|
+
cwd: current.agent.session.header.cwd ?? cwd,
|
|
191
|
+
sessionId: String(current.agent.session.id),
|
|
192
|
+
permissionMode: s.permissionMode,
|
|
193
|
+
...selection.current === undefined ? {} : { model: selection.current.model },
|
|
194
|
+
...effort === undefined ? {} : { effort },
|
|
195
|
+
...branch === undefined ? {} : { branch },
|
|
196
|
+
...s.hud?.contextPercent === undefined ? {} : { contextPercent: s.hud.contextPercent },
|
|
197
|
+
...s.hud?.contextTokens === undefined ? {} : { contextTokens: s.hud.contextTokens },
|
|
198
|
+
...s.hud?.tokens === undefined ? {} : { tokens: s.hud.tokens },
|
|
199
|
+
busy: s.busy,
|
|
200
|
+
}, width === undefined ? {} : { width });
|
|
201
|
+
};
|
|
202
|
+
return { refreshBranch, seedHud, seedTodos, applyUsage, projections, statusLineOf };
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=driver-hud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-hud.js","sourceRoot":"","sources":["../../src/harness/driver-hud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live session folds shared by the driver factory and its sections: the
|
|
3
|
+
* effective permission mode (plan overlay, else the durable override) and the
|
|
4
|
+
* LIVE session working directory (the session-cwd plugin's durable
|
|
5
|
+
* `worktree/entered` fold, then the boot-time header cwd).
|
|
6
|
+
*
|
|
7
|
+
* @module @dsh-cc/tui/harness/driver-live
|
|
8
|
+
*/
|
|
9
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
10
|
+
export declare function liveMode(agent: Agent, fallback: string): string;
|
|
11
|
+
/** Duck-typed face of the host context carrying the permission-rules engine. */
|
|
12
|
+
type RulesHostCtx = {
|
|
13
|
+
get(key: string): unknown;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The LIVE merged settings `permissions.defaultMode` (the engine rebuilds it
|
|
17
|
+
* on settings reload), falling back to the literal `'default'` when the
|
|
18
|
+
* permission-rules engine is not mounted. Structural on purpose: the driver
|
|
19
|
+
* must not depend on the engine's class shape.
|
|
20
|
+
*/
|
|
21
|
+
export declare function liveDefaultMode(ctx: RulesHostCtx): string;
|
|
22
|
+
/**
|
|
23
|
+
* `liveMode` with the F1 fallback bound to the host context: sections call
|
|
24
|
+
* `liveMode(agent)` and the fallback resolves to the permission-rules
|
|
25
|
+
* engine's LIVE merged settings defaultMode (literal `'default'` when the
|
|
26
|
+
* engine is not mounted). An explicit `fallback` still wins.
|
|
27
|
+
*/
|
|
28
|
+
export declare function liveModeWithDefault(ctx: RulesHostCtx): (agent: Agent, fallback?: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* The LIVE session working directory: the session-cwd plugin's durable
|
|
31
|
+
* `worktree/entered` fold first (authoritative across EnterWorktree/
|
|
32
|
+
* ExitWorktree moves), then the boot-time header cwd.
|
|
33
|
+
*/
|
|
34
|
+
export declare function liveSessionCwd(agent: Agent, fallback: string): string;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=driver-live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-live.d.ts","sourceRoot":"","sources":["../../src/harness/driver-live.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAKnD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,gFAAgF;AAChF,KAAK,YAAY,GAAG;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAA;AAEjD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAGzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,YAAY,GAChB,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live session folds shared by the driver factory and its sections: the
|
|
3
|
+
* effective permission mode (plan overlay, else the durable override) and the
|
|
4
|
+
* LIVE session working directory (the session-cwd plugin's durable
|
|
5
|
+
* `worktree/entered` fold, then the boot-time header cwd).
|
|
6
|
+
*
|
|
7
|
+
* @module @dsh-cc/tui/harness/driver-live
|
|
8
|
+
*/
|
|
9
|
+
import { foldPlanMode } from '@deepseek-ai/dsh-plan-mode';
|
|
10
|
+
import { foldPermissionMode } from '@dsh-cc/permission-rules';
|
|
11
|
+
import { foldSessionCwd } from '@dsh-cc/session-cwd';
|
|
12
|
+
export function liveMode(agent, fallback) {
|
|
13
|
+
if (foldPlanMode(agent.session.events))
|
|
14
|
+
return 'plan';
|
|
15
|
+
return foldPermissionMode(agent.session.events) ?? fallback;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The LIVE merged settings `permissions.defaultMode` (the engine rebuilds it
|
|
19
|
+
* on settings reload), falling back to the literal `'default'` when the
|
|
20
|
+
* permission-rules engine is not mounted. Structural on purpose: the driver
|
|
21
|
+
* must not depend on the engine's class shape.
|
|
22
|
+
*/
|
|
23
|
+
export function liveDefaultMode(ctx) {
|
|
24
|
+
const rules = ctx.get('permissionRules');
|
|
25
|
+
return rules?.defaultMode ?? 'default';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `liveMode` with the F1 fallback bound to the host context: sections call
|
|
29
|
+
* `liveMode(agent)` and the fallback resolves to the permission-rules
|
|
30
|
+
* engine's LIVE merged settings defaultMode (literal `'default'` when the
|
|
31
|
+
* engine is not mounted). An explicit `fallback` still wins.
|
|
32
|
+
*/
|
|
33
|
+
export function liveModeWithDefault(ctx) {
|
|
34
|
+
return (agent, fallback) => liveMode(agent, fallback ?? liveDefaultMode(ctx));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The LIVE session working directory: the session-cwd plugin's durable
|
|
38
|
+
* `worktree/entered` fold first (authoritative across EnterWorktree/
|
|
39
|
+
* ExitWorktree moves), then the boot-time header cwd.
|
|
40
|
+
*/
|
|
41
|
+
export function liveSessionCwd(agent, fallback) {
|
|
42
|
+
return foldSessionCwd(agent.session.events) ?? agent.session.header.cwd ?? fallback;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=driver-live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-live.js","sourceRoot":"","sources":["../../src/harness/driver-live.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,UAAU,QAAQ,CAAC,KAAY,EAAE,QAAgB;IACrD,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IACrD,OAAO,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAA;AAC7D,CAAC;AAKD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAiB;IAC/C,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAyC,CAAA;IAChF,OAAO,KAAK,EAAE,WAAW,IAAI,SAAS,CAAA;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAiB;IAEjB,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC,CAAA;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,QAAgB;IAC3D,OAAO,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAA;AACrF,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal pipeline (approvals + questions sharing one FIFO) extracted from
|
|
3
|
+
* harness/driver.ts. Free-function collaborator: `createModalQueue` takes a
|
|
4
|
+
* {@link DriverModalCtx} instead of closing over createDriver's locals, so the
|
|
5
|
+
* harness factory stays out of this leaf. Emits re-read the current view-model
|
|
6
|
+
* via `rt.state()` after every emit (createDriver rebinds `state` on emit).
|
|
7
|
+
* @module @dsh-cc/tui/harness/driver-modal
|
|
8
|
+
*/
|
|
9
|
+
import { type ApprovalPreview, type ApprovalView, type QuestionView } from '../store.ts';
|
|
10
|
+
import type { ApprovalOutcome } from '@deepseek-ai/dsh-user-approval';
|
|
11
|
+
import type { AskUserQuestionAnswer } from '@deepseek-ai/dsh-user-questions';
|
|
12
|
+
import type { DriverModalCtx } from './driver-ctx.ts';
|
|
13
|
+
export type ApprovalEntry = {
|
|
14
|
+
kind: 'approval';
|
|
15
|
+
view: ApprovalView;
|
|
16
|
+
resolve: (outcome: ApprovalOutcome) => void;
|
|
17
|
+
/** The requesting agent — carries the session a 'session' grant scopes to. */
|
|
18
|
+
agent?: unknown;
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
};
|
|
21
|
+
export type QuestionEntry = {
|
|
22
|
+
kind: 'question';
|
|
23
|
+
id: string;
|
|
24
|
+
view: QuestionView;
|
|
25
|
+
resolve: (answer: AskUserQuestionAnswer) => void;
|
|
26
|
+
reject: (error: unknown) => void;
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
};
|
|
29
|
+
export type ModalEntry = ApprovalEntry | QuestionEntry;
|
|
30
|
+
/** Deps `answerApproval` threads through to createDriver's persistence layer. */
|
|
31
|
+
export interface ModalAnswerDeps {
|
|
32
|
+
writeAllowRule(toolName: string, preview: ApprovalPreview | undefined): Promise<void>;
|
|
33
|
+
/** Grant the derived rule to the requesting session's allowlist (WS4-PR-B). */
|
|
34
|
+
addSessionRule(agent: unknown, toolName: string, preview: ApprovalPreview | undefined): void;
|
|
35
|
+
showNotice(text: string): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build the modal FIFO. Only the head renders (exactly one of the approval and
|
|
39
|
+
* question slots is set); answering or aborting the head promotes the next
|
|
40
|
+
* entry, and `ask()` during an active modal queues behind it instead of
|
|
41
|
+
* stacking a second box.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createModalQueue(rt: DriverModalCtx): {
|
|
44
|
+
push(entry: ModalEntry): void;
|
|
45
|
+
dequeue(entry: ModalEntry): void;
|
|
46
|
+
publishHead(): void;
|
|
47
|
+
shiftHead(): ModalEntry | undefined;
|
|
48
|
+
peekHead(): ModalEntry | undefined;
|
|
49
|
+
spliceAll(): ModalEntry[];
|
|
50
|
+
answerApproval(kind: 'once' | 'always' | 'session' | 'reject', deps: ModalAnswerDeps): void;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=driver-modal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-modal.d.ts","sourceRoot":"","sources":["../../src/harness/driver-modal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAA;IAC3C,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AACD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,CAAA;IAClB,OAAO,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAChD,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AACD,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,CAAA;AAEtD,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrF,+EAA+E;IAC/E,cAAc,CACZ,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,GAAG,SAAS,GACnC,IAAI,CAAA;IACP,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,cAAc,GAAG;IACpD,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IAC7B,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IAChC,WAAW,IAAI,IAAI,CAAA;IACnB,SAAS,IAAI,UAAU,GAAG,SAAS,CAAA;IACnC,QAAQ,IAAI,UAAU,GAAG,SAAS,CAAA;IAClC,SAAS,IAAI,UAAU,EAAE,CAAA;IACzB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAAA;CAC5F,CA6DA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal pipeline (approvals + questions sharing one FIFO) extracted from
|
|
3
|
+
* harness/driver.ts. Free-function collaborator: `createModalQueue` takes a
|
|
4
|
+
* {@link DriverModalCtx} instead of closing over createDriver's locals, so the
|
|
5
|
+
* harness factory stays out of this leaf. Emits re-read the current view-model
|
|
6
|
+
* via `rt.state()` after every emit (createDriver rebinds `state` on emit).
|
|
7
|
+
* @module @dsh-cc/tui/harness/driver-modal
|
|
8
|
+
*/
|
|
9
|
+
import { setApproval, setQuestion, } from "../store.js";
|
|
10
|
+
/**
|
|
11
|
+
* Build the modal FIFO. Only the head renders (exactly one of the approval and
|
|
12
|
+
* question slots is set); answering or aborting the head promotes the next
|
|
13
|
+
* entry, and `ask()` during an active modal queues behind it instead of
|
|
14
|
+
* stacking a second box.
|
|
15
|
+
*/
|
|
16
|
+
export function createModalQueue(rt) {
|
|
17
|
+
const modalQueue = [];
|
|
18
|
+
/** Publish the queue head into exactly one of the two modal slots. */
|
|
19
|
+
const publishHead = () => {
|
|
20
|
+
const head = modalQueue[0];
|
|
21
|
+
const behind = modalQueue.length - 1;
|
|
22
|
+
if (head === undefined || head.kind !== 'approval')
|
|
23
|
+
rt.emit(setApproval(rt.state(), undefined));
|
|
24
|
+
if (head === undefined || head.kind !== 'question')
|
|
25
|
+
rt.emit(setQuestion(rt.state(), undefined));
|
|
26
|
+
if (head === undefined)
|
|
27
|
+
return;
|
|
28
|
+
if (head.kind === 'approval') {
|
|
29
|
+
rt.emit(setApproval(rt.state(), { ...head.view, ...(behind === 0 ? {} : { pendingCount: behind }) }));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
rt.emit(setQuestion(rt.state(), head.view));
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/** Remove an entry from the queue (no-op if already gone) and republish. */
|
|
36
|
+
const dequeue = (entry) => {
|
|
37
|
+
const index = modalQueue.indexOf(entry);
|
|
38
|
+
if (index < 0)
|
|
39
|
+
return;
|
|
40
|
+
modalQueue.splice(index, 1);
|
|
41
|
+
publishHead();
|
|
42
|
+
};
|
|
43
|
+
const peekHead = () => modalQueue[0];
|
|
44
|
+
const shiftHead = () => modalQueue.shift();
|
|
45
|
+
const spliceAll = () => modalQueue.splice(0);
|
|
46
|
+
const answerApproval = (kind, deps) => {
|
|
47
|
+
const head = modalQueue[0];
|
|
48
|
+
if (head === undefined || head.kind !== 'approval')
|
|
49
|
+
return;
|
|
50
|
+
// Advance the queue BEFORE resolving: a resolution can immediately fire
|
|
51
|
+
// the next approval/request, which must enqueue behind the survivors.
|
|
52
|
+
modalQueue.shift();
|
|
53
|
+
publishHead();
|
|
54
|
+
head.resolve(kind === 'reject' ? 'rejected' : 'allowed-once');
|
|
55
|
+
if (kind === 'always') {
|
|
56
|
+
// Fire-and-forget: the call proceeds while the rule persists; a write
|
|
57
|
+
// failure surfaces as a notice, never as an answer error.
|
|
58
|
+
void deps.writeAllowRule(head.view.toolName, head.view.preview).catch((error) => {
|
|
59
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
60
|
+
deps.showNotice(`Allowed once only — saving the allow rule failed: ${message}`);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (kind === 'session') {
|
|
64
|
+
// Fire-and-forget like 'always': the call proceeds while the derived
|
|
65
|
+
// rule is granted to the requesting session's allowlist (WS4-PR-B,
|
|
66
|
+
// never global settings); a failure surfaces as a notice.
|
|
67
|
+
try {
|
|
68
|
+
deps.addSessionRule(head.agent, head.view.toolName, head.view.preview);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
72
|
+
deps.showNotice(`Allowed once only — adding the session rule failed: ${message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return { push: (e) => modalQueue.push(e), dequeue, publishHead, shiftHead, peekHead, spliceAll, answerApproval };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=driver-modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-modal.js","sourceRoot":"","sources":["../../src/harness/driver-modal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan/mode switching cluster for the in-process driver: the `/plan` channel
|
|
3
|
+
* seam and permission-mode cycling. Verbatim extraction from harness/driver.ts
|
|
4
|
+
* (applyMode / applyModeInner / cyclePermissionMode), reading shared state
|
|
5
|
+
* through a DriverModeCtx instead of createDriver's closures.
|
|
6
|
+
*
|
|
7
|
+
* Plan is owned by plan-mode inside the preset's isolate realm; the ONLY
|
|
8
|
+
* cross-plane write seam is the `/plan` command channel — dispatched bare,
|
|
9
|
+
* never '/plan on' (the upstream handler steers any non-'off' argument into
|
|
10
|
+
* the conversation as a user message).
|
|
11
|
+
* @module @dsh-cc/tui/harness/driver-mode
|
|
12
|
+
*/
|
|
13
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
14
|
+
import { type PermissionCommandMode } from '../mode-cycle.ts';
|
|
15
|
+
import type { TuiState } from '../store.ts';
|
|
16
|
+
import type { DriverModeCtx } from './driver-ctx.ts';
|
|
17
|
+
/** Returns the current permission-rules engine's setMode seam (duck-typed). */
|
|
18
|
+
type PermissionRulesSeam = {
|
|
19
|
+
setMode(agent: Agent, mode: string): void;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Free-function collaborator implementing the plan/mode writepath. Reads all
|
|
23
|
+
* shared state/functions off `rt` (DriverModeCtx) so it never imports the
|
|
24
|
+
* createDriver factory. `modeWrites` is a serialization gate held here; each
|
|
25
|
+
* call chains onto the previous write so concurrent mode switches cannot
|
|
26
|
+
* interleave.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createModeSection(rt: DriverModeCtx): {
|
|
29
|
+
applyMode(mode: PermissionCommandMode): void;
|
|
30
|
+
cyclePermissionMode(): Promise<void>;
|
|
31
|
+
get modeWrites(): Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
export type { PermissionRulesSeam };
|
|
34
|
+
export type { TuiState };
|
|
35
|
+
//# sourceMappingURL=driver-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-mode.d.ts","sourceRoot":"","sources":["../../src/harness/driver-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAwC,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAGnG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,+EAA+E;AAC/E,KAAK,mBAAmB,GAAG;IAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAExE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,aAAa,GAAG;IACpD,SAAS,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAC5C,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAChC,CA8DA;AAED,YAAY,EAAE,mBAAmB,EAAE,CAAA;AACnC,YAAY,EAAE,QAAQ,EAAE,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan/mode switching cluster for the in-process driver: the `/plan` channel
|
|
3
|
+
* seam and permission-mode cycling. Verbatim extraction from harness/driver.ts
|
|
4
|
+
* (applyMode / applyModeInner / cyclePermissionMode), reading shared state
|
|
5
|
+
* through a DriverModeCtx instead of createDriver's closures.
|
|
6
|
+
*
|
|
7
|
+
* Plan is owned by plan-mode inside the preset's isolate realm; the ONLY
|
|
8
|
+
* cross-plane write seam is the `/plan` command channel — dispatched bare,
|
|
9
|
+
* never '/plan on' (the upstream handler steers any non-'off' argument into
|
|
10
|
+
* the conversation as a user message).
|
|
11
|
+
* @module @dsh-cc/tui/harness/driver-mode
|
|
12
|
+
*/
|
|
13
|
+
import { isPermissionMode, nextPermissionMode } from "../mode-cycle.js";
|
|
14
|
+
import { PERMISSION_COMMAND_MODES, planPhaseOf } from '@dsh-cc/command-permissions';
|
|
15
|
+
import { setPermissionMode } from "../store.js";
|
|
16
|
+
/**
|
|
17
|
+
* Free-function collaborator implementing the plan/mode writepath. Reads all
|
|
18
|
+
* shared state/functions off `rt` (DriverModeCtx) so it never imports the
|
|
19
|
+
* createDriver factory. `modeWrites` is a serialization gate held here; each
|
|
20
|
+
* call chains onto the previous write so concurrent mode switches cannot
|
|
21
|
+
* interleave.
|
|
22
|
+
*/
|
|
23
|
+
export function createModeSection(rt) {
|
|
24
|
+
let modeWrites = Promise.resolve();
|
|
25
|
+
const applyMode = (mode) => {
|
|
26
|
+
modeWrites = modeWrites.then(() => applyModeInner(mode)).catch((error) => {
|
|
27
|
+
rt.showNotice(error instanceof Error ? error.message : String(error));
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
const applyModeInner = async (mode) => {
|
|
31
|
+
if (mode === 'plan') {
|
|
32
|
+
const result = await rt.runHarness('/plan');
|
|
33
|
+
if (result === undefined)
|
|
34
|
+
rt.showNotice('plan mode is not mounted in this composition');
|
|
35
|
+
// No optimistic emit: the display re-folds from the committed plan/mode
|
|
36
|
+
// event (see the session/event listener), so a queued mid-turn entry
|
|
37
|
+
// stays truthful until it applies.
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const phase = planPhaseOf(rt.current.agent.session.events, rt.projections?.stateOf(rt.current.agent.session, 'plan'));
|
|
41
|
+
if (phase !== 'off') {
|
|
42
|
+
const exit = await rt.runHarness('/plan off');
|
|
43
|
+
if (exit === null)
|
|
44
|
+
return; // no command registry — runHarness already noticed
|
|
45
|
+
if (exit === undefined) {
|
|
46
|
+
rt.showNotice('plan mode is not mounted in this composition');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// A failed exit must not strand the switch half-done.
|
|
50
|
+
if (exit.kind === 'error')
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const rules = rt.getRules();
|
|
54
|
+
if (rules === undefined) {
|
|
55
|
+
rt.showNotice('The permission-rules engine is not mounted in this composition.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
rules.setMode(rt.current.agent, mode);
|
|
59
|
+
// rebind-proof: emit reassigns createDriver's `state`, so read through the
|
|
60
|
+
// getter for a fresh snapshot to drive setPermissionMode.
|
|
61
|
+
const live = rt.state();
|
|
62
|
+
rt.emit(setPermissionMode(live, mode));
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
applyMode,
|
|
66
|
+
cyclePermissionMode() {
|
|
67
|
+
// F1: the cycle start follows the live settings default when no fold
|
|
68
|
+
// exists — but a settings defaultMode outside PERMISSION_COMMAND_MODES
|
|
69
|
+
// must not become the start (one Tab press would never reach it and the
|
|
70
|
+
// shown mode would be "lost"), so clamp non-members to 'default' first.
|
|
71
|
+
const live = rt.liveMode(rt.current.agent);
|
|
72
|
+
const start = isPermissionMode(live) ? live : 'default';
|
|
73
|
+
const next = nextPermissionMode(start);
|
|
74
|
+
if (!PERMISSION_COMMAND_MODES.includes(next))
|
|
75
|
+
return modeWrites;
|
|
76
|
+
applyMode(next);
|
|
77
|
+
return modeWrites;
|
|
78
|
+
},
|
|
79
|
+
get modeWrites() {
|
|
80
|
+
return modeWrites;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=driver-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-mode.js","sourceRoot":"","sources":["../../src/harness/driver-mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model / effort / permission pickers for the in-process driver. Verbatim
|
|
3
|
+
* extraction from harness/driver.ts (openModelPicker / applyModelSwitch /
|
|
4
|
+
* openEffortPicker / openPermissionPicker plus the return-literal picker
|
|
5
|
+
* bodies), reading shared state through a DriverPickersCtx instead of
|
|
6
|
+
* createDriver's closures.
|
|
7
|
+
*
|
|
8
|
+
* The pickers are stateless overlays: each open parks picker state and each
|
|
9
|
+
* submit reads-then-closes before validating. The bare model switch writes
|
|
10
|
+
* synchronously; a carried effort validates detached via resolveEfforts /
|
|
11
|
+
* stalePair, kept in createDriver and passed in.
|
|
12
|
+
* @module @dsh-cc/tui/harness/driver-pickers
|
|
13
|
+
*/
|
|
14
|
+
import { type TuiState } from '../store.ts';
|
|
15
|
+
import { type CatalogEntry } from '../model-catalog.ts';
|
|
16
|
+
import type { DriverPickersCtx } from './driver-ctx.ts';
|
|
17
|
+
/** A single selection route, matching what selection.current holds. */
|
|
18
|
+
type SelectionRoute = {
|
|
19
|
+
provider: string;
|
|
20
|
+
model: string;
|
|
21
|
+
reasoningEffort?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Free-function collaborator implementing the three pickers. Reads all shared
|
|
25
|
+
* state/functions off `rt` (DriverPickersCtx) so it never imports the
|
|
26
|
+
* createDriver factory. `selection` is passed by reference so writes land on
|
|
27
|
+
* createDriver's live ref across switchSession; resolveEfforts / stalePair /
|
|
28
|
+
* loadCatalog stay in createDriver and arrive on the ctx.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createPickersSection(rt: DriverPickersCtx): {
|
|
31
|
+
openModelPicker(): Promise<void>;
|
|
32
|
+
applyModelSwitch(provider: string, model: string): Promise<void>;
|
|
33
|
+
openEffortPicker(): Promise<void>;
|
|
34
|
+
openPermissionPicker(): void;
|
|
35
|
+
modelPickerMove(delta: -1 | 1): void;
|
|
36
|
+
modelPickerSubmit(): Promise<void>;
|
|
37
|
+
modelPickerCancel(): void;
|
|
38
|
+
effortPickerMove(delta: -1 | 1): void;
|
|
39
|
+
effortPickerSubmit(): Promise<void>;
|
|
40
|
+
effortPickerCancel(): void;
|
|
41
|
+
permissionPickerMove(delta: -1 | 1): void;
|
|
42
|
+
permissionPickerSubmit(): Promise<void>;
|
|
43
|
+
permissionPickerCancel(): void;
|
|
44
|
+
loadModelCatalog(): Promise<CatalogEntry[]>;
|
|
45
|
+
loadModelEfforts(): Promise<string[]>;
|
|
46
|
+
};
|
|
47
|
+
export type { SelectionRoute, CatalogEntry, TuiState };
|
|
48
|
+
//# sourceMappingURL=driver-pickers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver-pickers.d.ts","sourceRoot":"","sources":["../../src/harness/driver-pickers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EASL,KAAK,QAAQ,EACd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAEvD,uEAAuE;AACvE,KAAK,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,gBAAgB,GAAG;IAC1D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,oBAAoB,IAAI,IAAI,CAAA;IAC5B,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACpC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC,iBAAiB,IAAI,IAAI,CAAA;IACzB,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACrC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,kBAAkB,IAAI,IAAI,CAAA;IAC1B,oBAAoB,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;IACzC,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,sBAAsB,IAAI,IAAI,CAAA;IAC9B,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;IAC3C,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;CACtC,CAyNA;AAED,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAA"}
|