@sagmans/dsh-tui 0.6.0 → 0.8.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 +83 -0
- package/.agents/skills/dsh-tui-dogfood/references/home-state.md +78 -0
- package/.agents/skills/dsh-tui-dogfood/scripts/clone-links.mjs +133 -0
- package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +417 -0
- package/.agents/skills/dsh-tui-update-models/SKILL.md +199 -0
- package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +292 -0
- package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +314 -0
- package/README.md +154 -27
- package/lib/agent/present.d.ts.map +1 -1
- package/lib/agent/present.js +2 -1
- package/lib/agent/present.js.map +1 -1
- package/lib/cards/composition.d.ts +68 -0
- package/lib/cards/composition.d.ts.map +1 -0
- package/lib/cards/composition.js +117 -0
- package/lib/cards/composition.js.map +1 -0
- package/lib/cards/presenter.d.ts +23 -0
- package/lib/cards/presenter.d.ts.map +1 -0
- package/lib/cards/presenter.js +394 -0
- package/lib/cards/presenter.js.map +1 -0
- package/lib/cards/preview.d.ts +42 -0
- package/lib/cards/preview.d.ts.map +1 -0
- package/lib/cards/preview.js +51 -0
- package/lib/cards/preview.js.map +1 -0
- package/lib/cards.d.ts +12 -120
- package/lib/cards.d.ts.map +1 -1
- package/lib/cards.js +4 -556
- package/lib/cards.js.map +1 -1
- package/lib/compat/section.d.ts +29 -0
- package/lib/compat/section.d.ts.map +1 -0
- package/lib/compat/section.js +82 -0
- package/lib/compat/section.js.map +1 -0
- package/lib/config.d.ts +27 -2
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +61 -1
- package/lib/config.js.map +1 -1
- package/lib/contracts.d.ts +28 -0
- package/lib/contracts.d.ts.map +1 -1
- package/lib/fold-cursor.d.ts +8 -0
- package/lib/fold-cursor.d.ts.map +1 -1
- package/lib/fold-cursor.js +18 -0
- package/lib/fold-cursor.js.map +1 -1
- package/lib/gates/question-card.d.ts +77 -0
- package/lib/gates/question-card.d.ts.map +1 -0
- package/lib/gates/question-card.js +113 -0
- package/lib/gates/question-card.js.map +1 -0
- package/lib/gates/questions.d.ts +127 -0
- package/lib/gates/questions.d.ts.map +1 -0
- package/lib/gates/questions.js +418 -0
- package/lib/gates/questions.js.map +1 -0
- package/lib/gates.d.ts +1 -113
- package/lib/gates.d.ts.map +1 -1
- package/lib/gates.js +1 -484
- package/lib/gates.js.map +1 -1
- package/lib/herdr/client.d.ts +8 -0
- package/lib/herdr/client.d.ts.map +1 -1
- package/lib/herdr/client.js +13 -1
- package/lib/herdr/client.js.map +1 -1
- package/lib/herdr/constants.d.ts +18 -0
- package/lib/herdr/constants.d.ts.map +1 -1
- package/lib/herdr/constants.js +18 -0
- package/lib/herdr/constants.js.map +1 -1
- package/lib/herdr/reporter.d.ts +20 -4
- package/lib/herdr/reporter.d.ts.map +1 -1
- package/lib/herdr/reporter.js +70 -20
- package/lib/herdr/reporter.js.map +1 -1
- package/lib/herdr/state.d.ts +10 -0
- package/lib/herdr/state.d.ts.map +1 -1
- package/lib/herdr/state.js +21 -4
- package/lib/herdr/state.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +348 -2602
- package/lib/index.js.map +1 -1
- package/lib/input/action-catalog.d.ts +74 -0
- package/lib/input/action-catalog.d.ts.map +1 -0
- package/lib/input/action-catalog.js +137 -0
- package/lib/input/action-catalog.js.map +1 -0
- package/lib/input/actions.d.ts +5 -81
- package/lib/input/actions.d.ts.map +1 -1
- package/lib/input/actions.js +4 -625
- package/lib/input/actions.js.map +1 -1
- package/lib/input/completion.d.ts +1 -1
- package/lib/input/completion.d.ts.map +1 -1
- package/lib/input/completion.js +2 -1
- package/lib/input/completion.js.map +1 -1
- package/lib/input/file-index.d.ts +40 -0
- package/lib/input/file-index.d.ts.map +1 -0
- package/lib/input/file-index.js +141 -0
- package/lib/input/file-index.js.map +1 -0
- package/lib/input/file-search.d.ts +1 -38
- package/lib/input/file-search.d.ts.map +1 -1
- package/lib/input/file-search.js +1 -487
- package/lib/input/file-search.js.map +1 -1
- package/lib/input/key-press.d.ts +57 -0
- package/lib/input/key-press.d.ts.map +1 -0
- package/lib/input/key-press.js +218 -0
- package/lib/input/key-press.js.map +1 -0
- package/lib/input/keymap-conflicts.d.ts +59 -0
- package/lib/input/keymap-conflicts.d.ts.map +1 -0
- package/lib/input/keymap-conflicts.js +292 -0
- package/lib/input/keymap-conflicts.js.map +1 -0
- package/lib/input/keymap-settings.js +1 -1
- package/lib/input/keymap-settings.js.map +1 -1
- package/lib/input/keymap.d.ts.map +1 -1
- package/lib/input/keymap.js +3 -1
- package/lib/input/keymap.js.map +1 -1
- package/lib/input/workspace-files.d.ts +10 -0
- package/lib/input/workspace-files.d.ts.map +1 -0
- package/lib/input/workspace-files.js +359 -0
- package/lib/input/workspace-files.js.map +1 -0
- package/lib/install-skills.d.ts +39 -0
- package/lib/install-skills.d.ts.map +1 -0
- package/lib/install-skills.js +273 -0
- package/lib/install-skills.js.map +1 -0
- package/lib/keys-command.d.ts +2 -1
- package/lib/keys-command.d.ts.map +1 -1
- package/lib/keys-command.js +2 -1
- package/lib/keys-command.js.map +1 -1
- package/lib/model-list.d.ts +37 -0
- package/lib/model-list.d.ts.map +1 -0
- package/lib/model-list.js +60 -0
- package/lib/model-list.js.map +1 -0
- package/lib/startup.d.ts +8 -0
- package/lib/startup.d.ts.map +1 -1
- package/lib/startup.js +120 -24
- package/lib/startup.js.map +1 -1
- package/lib/subagents.d.ts +7 -3
- package/lib/subagents.d.ts.map +1 -1
- package/lib/subagents.js +28 -4
- package/lib/subagents.js.map +1 -1
- package/lib/surface/appearance-preferences.d.ts +26 -0
- package/lib/surface/appearance-preferences.d.ts.map +1 -0
- package/lib/surface/appearance-preferences.js +139 -0
- package/lib/surface/appearance-preferences.js.map +1 -0
- package/lib/surface/appearance.d.ts +87 -0
- package/lib/surface/appearance.d.ts.map +1 -0
- package/lib/surface/appearance.js +353 -0
- package/lib/surface/appearance.js.map +1 -0
- package/lib/surface/background-work.d.ts +51 -0
- package/lib/surface/background-work.d.ts.map +1 -0
- package/lib/surface/background-work.js +172 -0
- package/lib/surface/background-work.js.map +1 -0
- package/lib/surface/commands.d.ts +82 -0
- package/lib/surface/commands.d.ts.map +1 -0
- package/lib/surface/commands.js +370 -0
- package/lib/surface/commands.js.map +1 -0
- package/lib/surface/modal-input.d.ts +59 -0
- package/lib/surface/modal-input.d.ts.map +1 -0
- package/lib/surface/modal-input.js +243 -0
- package/lib/surface/modal-input.js.map +1 -0
- package/lib/surface/model-choice.d.ts +54 -0
- package/lib/surface/model-choice.d.ts.map +1 -0
- package/lib/surface/model-choice.js +325 -0
- package/lib/surface/model-choice.js.map +1 -0
- package/lib/surface/preset-choice.d.ts +78 -0
- package/lib/surface/preset-choice.d.ts.map +1 -0
- package/lib/surface/preset-choice.js +163 -0
- package/lib/surface/preset-choice.js.map +1 -0
- package/lib/surface/prompt-input.d.ts +97 -0
- package/lib/surface/prompt-input.d.ts.map +1 -0
- package/lib/surface/prompt-input.js +215 -0
- package/lib/surface/prompt-input.js.map +1 -0
- package/lib/surface/prompt-memory.d.ts +76 -0
- package/lib/surface/prompt-memory.d.ts.map +1 -0
- package/lib/surface/prompt-memory.js +167 -0
- package/lib/surface/prompt-memory.js.map +1 -0
- package/lib/surface/session-lifecycle.d.ts +120 -0
- package/lib/surface/session-lifecycle.d.ts.map +1 -0
- package/lib/surface/session-lifecycle.js +324 -0
- package/lib/surface/session-lifecycle.js.map +1 -0
- package/lib/surface/session-picker.d.ts +39 -0
- package/lib/surface/session-picker.d.ts.map +1 -0
- package/lib/surface/session-picker.js +107 -0
- package/lib/surface/session-picker.js.map +1 -0
- package/lib/surface/session-view.d.ts +86 -0
- package/lib/surface/session-view.d.ts.map +1 -0
- package/lib/surface/session-view.js +215 -0
- package/lib/surface/session-view.js.map +1 -0
- package/lib/surface/staged-turns.d.ts +81 -0
- package/lib/surface/staged-turns.d.ts.map +1 -0
- package/lib/surface/staged-turns.js +206 -0
- package/lib/surface/staged-turns.js.map +1 -0
- package/lib/surface/terminal-lifecycle.d.ts +76 -0
- package/lib/surface/terminal-lifecycle.d.ts.map +1 -0
- package/lib/surface/terminal-lifecycle.js +222 -0
- package/lib/surface/terminal-lifecycle.js.map +1 -0
- package/lib/terminal-text/scan.d.ts +44 -0
- package/lib/terminal-text/scan.d.ts.map +1 -0
- package/lib/terminal-text/scan.js +195 -0
- package/lib/terminal-text/scan.js.map +1 -0
- package/lib/terminal-text/sgr.d.ts +32 -0
- package/lib/terminal-text/sgr.d.ts.map +1 -0
- package/lib/terminal-text/sgr.js +203 -0
- package/lib/terminal-text/sgr.js.map +1 -0
- package/lib/terminal-text.d.ts +1 -1
- package/lib/terminal-text.d.ts.map +1 -1
- package/lib/terminal-text.js +2 -379
- package/lib/terminal-text.js.map +1 -1
- package/lib/theme-command.js +2 -1
- package/lib/theme-command.js.map +1 -1
- package/lib/theme-defaults.d.ts +64 -0
- package/lib/theme-defaults.d.ts.map +1 -0
- package/lib/theme-defaults.js +248 -0
- package/lib/theme-defaults.js.map +1 -0
- package/lib/theme-files.d.ts +1 -1
- package/lib/theme-files.d.ts.map +1 -1
- package/lib/theme-files.js +1 -1
- package/lib/theme-files.js.map +1 -1
- package/lib/theme-resolver.d.ts +36 -0
- package/lib/theme-resolver.d.ts.map +1 -0
- package/lib/theme-resolver.js +112 -0
- package/lib/theme-resolver.js.map +1 -0
- package/lib/theme-schema.d.ts.map +1 -1
- package/lib/theme-schema.js +3 -2
- package/lib/theme-schema.js.map +1 -1
- package/lib/theme-settings.d.ts +5 -7
- package/lib/theme-settings.d.ts.map +1 -1
- package/lib/theme-settings.js +37 -21
- package/lib/theme-settings.js.map +1 -1
- package/lib/theme-tokens.d.ts +0 -89
- package/lib/theme-tokens.d.ts.map +1 -1
- package/lib/theme-tokens.js +0 -356
- package/lib/theme-tokens.js.map +1 -1
- package/lib/theme.d.ts +1 -1
- package/lib/theme.d.ts.map +1 -1
- package/lib/theme.js +2 -1
- package/lib/theme.js.map +1 -1
- package/lib/tool-display.d.ts.map +1 -1
- package/lib/tool-display.js +2 -1
- package/lib/tool-display.js.map +1 -1
- package/lib/transcript/message-content.d.ts +21 -0
- package/lib/transcript/message-content.d.ts.map +1 -0
- package/lib/transcript/message-content.js +61 -0
- package/lib/transcript/message-content.js.map +1 -0
- package/lib/transcript/tool-calls.d.ts +106 -0
- package/lib/transcript/tool-calls.d.ts.map +1 -0
- package/lib/transcript/tool-calls.js +254 -0
- package/lib/transcript/tool-calls.js.map +1 -0
- package/lib/transcript.d.ts +14 -55
- package/lib/transcript.d.ts.map +1 -1
- package/lib/transcript.js +31 -253
- package/lib/transcript.js.map +1 -1
- package/lib/ui/dock.d.ts +14 -2
- package/lib/ui/dock.d.ts.map +1 -1
- package/lib/ui/dock.js +52 -10
- package/lib/ui/dock.js.map +1 -1
- package/lib/ui/editor.d.ts.map +1 -1
- package/lib/ui/editor.js +2 -1
- package/lib/ui/editor.js.map +1 -1
- package/lib/ui/keymap-picker.d.ts +2 -1
- package/lib/ui/keymap-picker.d.ts.map +1 -1
- package/lib/ui/keymap-picker.js +1 -0
- package/lib/ui/keymap-picker.js.map +1 -1
- package/lib/ui/view/gate-card.d.ts +21 -0
- package/lib/ui/view/gate-card.d.ts.map +1 -0
- package/lib/ui/view/gate-card.js +104 -0
- package/lib/ui/view/gate-card.js.map +1 -0
- package/lib/ui/view/tool-card.d.ts +149 -0
- package/lib/ui/view/tool-card.d.ts.map +1 -0
- package/lib/ui/view/tool-card.js +429 -0
- package/lib/ui/view/tool-card.js.map +1 -0
- package/lib/ui/view/transcript-message.d.ts +62 -0
- package/lib/ui/view/transcript-message.d.ts.map +1 -0
- package/lib/ui/view/transcript-message.js +158 -0
- package/lib/ui/view/transcript-message.js.map +1 -0
- package/lib/ui/view.d.ts +105 -223
- package/lib/ui/view.d.ts.map +1 -1
- package/lib/ui/view.js +132 -679
- package/lib/ui/view.js.map +1 -1
- package/package.json +3 -1
- package/themes/violet-orbit.yaml +7 -5
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
2
|
+
import type { ForkInheritance, TuiAgent } from '../agent/host.ts';
|
|
3
|
+
import { type PresetRoster } from '../agent/presets.ts';
|
|
4
|
+
import type { Keymap } from '../input/actions.ts';
|
|
5
|
+
import type { Picker } from './modal-input.ts';
|
|
6
|
+
/**
|
|
7
|
+
* What the mode owner needs from the surface that composes it.
|
|
8
|
+
*
|
|
9
|
+
* The roster arrives as a handle because the open path mounts through it as
|
|
10
|
+
* well, and the stored mode is a property of a log this surface only reads. The
|
|
11
|
+
* screen, the keyboard, the notice, and the session the reader is watching
|
|
12
|
+
* belong to the surface that owns them; the keys move with a settings edit, so
|
|
13
|
+
* they are read per press.
|
|
14
|
+
*/
|
|
15
|
+
export interface PresetChoicePorts {
|
|
16
|
+
readonly agentPresets: PresetRoster | undefined;
|
|
17
|
+
/** The mode named on the command line, which is the only one that may conflict. */
|
|
18
|
+
readonly requestedPreset: string | undefined;
|
|
19
|
+
/** The mode a stored session's own log recorded, absent when it recorded none. */
|
|
20
|
+
readonly storedPreset: (id: SessionId) => Promise<string | undefined>;
|
|
21
|
+
/** The mode a live session runs right now, which only its own projection knows. */
|
|
22
|
+
readonly livePreset: (id: SessionId) => string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* The agent this terminal drives, read at call time.
|
|
25
|
+
*
|
|
26
|
+
* Opening a session replaces it, so a command typed after that switch has to
|
|
27
|
+
* reach the agent now on screen rather than the one it replaced.
|
|
28
|
+
*/
|
|
29
|
+
readonly drivingAgent: () => TuiAgent | undefined;
|
|
30
|
+
readonly keymap: () => Keymap;
|
|
31
|
+
/** Take the keyboard for a list and answer with the pick id it settled on. */
|
|
32
|
+
readonly openPicker: (picker: Picker) => Promise<string | undefined>;
|
|
33
|
+
readonly notice: (message: string) => void;
|
|
34
|
+
readonly render: () => void;
|
|
35
|
+
/**
|
|
36
|
+
* Show the session this terminal drives again.
|
|
37
|
+
*
|
|
38
|
+
* Navigation belongs to the surface that owns the view, so the mode owner only
|
|
39
|
+
* decides when a switch needs the reader looking at the session it landed on.
|
|
40
|
+
*/
|
|
41
|
+
readonly returnToDrivenSession: () => Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/** The launch a run was started for, as the mode it named has to be read. */
|
|
44
|
+
export interface PresetLaunch {
|
|
45
|
+
/** The session this run opens. */
|
|
46
|
+
readonly sessionId: SessionId;
|
|
47
|
+
readonly resume: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Whether a bare `--resume` still has to ask which session to open.
|
|
50
|
+
*
|
|
51
|
+
* The mode a stored session recorded can only be compared with the run's own
|
|
52
|
+
* flag once that pick lands, so the conflict waits for the chosen session.
|
|
53
|
+
*/
|
|
54
|
+
readonly resumePicker: boolean;
|
|
55
|
+
}
|
|
56
|
+
/** The reads and operations the composing surface routes to the mode owner. */
|
|
57
|
+
export interface PresetChoice {
|
|
58
|
+
/** The mode one agent joins. */
|
|
59
|
+
readonly presetFor: (id: SessionId, resume: boolean, fork: ForkInheritance | undefined) => Promise<string | undefined>;
|
|
60
|
+
/** Resolve the named mode and refuse a launch that cannot run it. */
|
|
61
|
+
readonly validateLaunch: (launch: PresetLaunch) => Promise<void>;
|
|
62
|
+
/** Show or choose the mode this session runs. */
|
|
63
|
+
readonly runPresetCommand: (argument: string) => void;
|
|
64
|
+
/** The mode a session starting now would take. */
|
|
65
|
+
readonly currentSeat: () => string | undefined;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Which mode a session runs — its seat in the roster — and the two ways it
|
|
69
|
+
* changes.
|
|
70
|
+
*
|
|
71
|
+
* The seat is one value for the whole run: a launch flag seeds it and a
|
|
72
|
+
* successful switch updates it, so `/new` and `/fork` land in the mode the
|
|
73
|
+
* reader last chose. A resumed session keeps the mode its own log recorded,
|
|
74
|
+
* because swapping it would leave logged tool calls the new composition cannot
|
|
75
|
+
* make — the same reason the harness refuses a switch once a turn has run.
|
|
76
|
+
*/
|
|
77
|
+
export declare function createPresetChoice(ports: PresetChoicePorts): PresetChoice;
|
|
78
|
+
//# sourceMappingURL=preset-choice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-choice.d.ts","sourceRoot":"","sources":["../../src/surface/preset-choice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EAAuB,KAAK,YAAY,EAAsB,MAAM,qBAAqB,CAAA;AAChG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,SAAS,CAAA;IAC/C,mFAAmF;IACnF,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,kFAAkF;IAClF,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACrE,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,MAAM,GAAG,SAAS,CAAA;IAC1D;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAA;IAC7B,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACpE,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC/B;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,GAAG,SAAS,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACtH,qEAAqE;IACrE,QAAQ,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,iDAAiD;IACjD,QAAQ,CAAC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD,kDAAkD;IAClD,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;CAC/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAyJzE"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { parsePresetArgument } from "../agent/presets.js";
|
|
2
|
+
import { PresetPicker } from "../ui/picker.js";
|
|
3
|
+
/**
|
|
4
|
+
* Which mode a session runs — its seat in the roster — and the two ways it
|
|
5
|
+
* changes.
|
|
6
|
+
*
|
|
7
|
+
* The seat is one value for the whole run: a launch flag seeds it and a
|
|
8
|
+
* successful switch updates it, so `/new` and `/fork` land in the mode the
|
|
9
|
+
* reader last chose. A resumed session keeps the mode its own log recorded,
|
|
10
|
+
* because swapping it would leave logged tool calls the new composition cannot
|
|
11
|
+
* make — the same reason the harness refuses a switch once a turn has run.
|
|
12
|
+
*/
|
|
13
|
+
export function createPresetChoice(ports) {
|
|
14
|
+
const requestedPreset = ports.requestedPreset;
|
|
15
|
+
/**
|
|
16
|
+
* The mode a session the reader starts from here on joins.
|
|
17
|
+
*
|
|
18
|
+
* A launch flag seeds it and a successful switch updates it, so `/new` and
|
|
19
|
+
* `/fork` land in the mode the reader last chose; nothing is written to
|
|
20
|
+
* settings, because the mode of a session is not a property of the machine.
|
|
21
|
+
* Unset means nobody chose, which is where the roster's default applies.
|
|
22
|
+
*/
|
|
23
|
+
let seat = requestedPreset;
|
|
24
|
+
/**
|
|
25
|
+
* The mode a session takes its seat in: the reader's latest choice, or the
|
|
26
|
+
* roster's default read at this moment.
|
|
27
|
+
*
|
|
28
|
+
* The default cannot be captured when this row applies: it comes from the
|
|
29
|
+
* settings document, which may be read after that, so a captured copy would
|
|
30
|
+
* pin every later session to the mode the bundle happened to ship.
|
|
31
|
+
*/
|
|
32
|
+
const seatMode = () => seat ?? ports.agentPresets?.defaultId;
|
|
33
|
+
/** The roster as the picker paints it, refreshed when the picker opens. */
|
|
34
|
+
let presetRows = [];
|
|
35
|
+
/** Choose the mode a session that has not started yet will run. */
|
|
36
|
+
const askForPreset = async (currentId) => {
|
|
37
|
+
const roster = ports.agentPresets;
|
|
38
|
+
if (roster === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
presetRows = await roster.list();
|
|
41
|
+
return await ports.openPicker(new PresetPicker(() => presetRows, () => currentId, ports.keymap));
|
|
42
|
+
};
|
|
43
|
+
/** The stored mode's roster row, or undefined when the roster no longer offers it. */
|
|
44
|
+
const resolveStored = async (id, stored) => {
|
|
45
|
+
try {
|
|
46
|
+
return (await ports.agentPresets?.resolve(stored))?.id;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The mode one agent joins.
|
|
54
|
+
*
|
|
55
|
+
* A resumed session keeps the composition its own log recorded, because
|
|
56
|
+
* swapping it would leave logged tool calls the new composition cannot make —
|
|
57
|
+
* the same reason the harness refuses a switch once a turn has run. A session
|
|
58
|
+
* that recorded none, which is every session written before modes existed,
|
|
59
|
+
* takes the seat; a branch inherits the mode its parent is running.
|
|
60
|
+
*/
|
|
61
|
+
const presetFor = async (id, resume, fork) => {
|
|
62
|
+
const roster = ports.agentPresets;
|
|
63
|
+
if (roster === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
if (fork !== undefined)
|
|
66
|
+
return ports.livePreset(fork.from) ?? seatMode();
|
|
67
|
+
if (!resume)
|
|
68
|
+
return seatMode();
|
|
69
|
+
const stored = await ports.storedPreset(id);
|
|
70
|
+
if (stored === undefined)
|
|
71
|
+
return seatMode();
|
|
72
|
+
const resolvedStored = await resolveStored(id, stored);
|
|
73
|
+
if (resolvedStored === undefined) {
|
|
74
|
+
// The composition this session recorded is gone. Naming one explicitly is
|
|
75
|
+
// the reader's only way forward, so that is the one case an override is
|
|
76
|
+
// taken for a stored session.
|
|
77
|
+
if (requestedPreset !== undefined)
|
|
78
|
+
return (await roster.resolve(requestedPreset)).id;
|
|
79
|
+
throw new Error(`session ${id} runs mode "${stored}", which this roster no longer offers; name another with --preset`);
|
|
80
|
+
}
|
|
81
|
+
if (requestedPreset !== undefined && requestedPreset !== resolvedStored) {
|
|
82
|
+
throw new Error(`session ${id} runs mode "${resolvedStored}", so --preset ${requestedPreset} does not apply; /preset ${requestedPreset} switches it before its first turn`);
|
|
83
|
+
}
|
|
84
|
+
return resolvedStored;
|
|
85
|
+
};
|
|
86
|
+
/** Join this session to another mode and remember it for the next session. */
|
|
87
|
+
const applyPreset = async (id) => {
|
|
88
|
+
const roster = ports.agentPresets;
|
|
89
|
+
const agent = ports.drivingAgent();
|
|
90
|
+
if (roster === undefined || agent === undefined)
|
|
91
|
+
return;
|
|
92
|
+
try {
|
|
93
|
+
const chosen = await roster.select(agent.agent, id);
|
|
94
|
+
seat = chosen;
|
|
95
|
+
// The durable selection is folded as a marker on the session it belongs
|
|
96
|
+
// to, so a reader watching a child has to come back to see it.
|
|
97
|
+
await ports.returnToDrivenSession();
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
ports.notice(`could not switch the mode: ${error instanceof Error ? error.message : String(error)}`);
|
|
101
|
+
}
|
|
102
|
+
ports.render();
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Show or choose the mode this session runs.
|
|
106
|
+
*
|
|
107
|
+
* The mode decides which tools, prompt sections, and skills exist at all, so
|
|
108
|
+
* it is fixed once a turn has run: the harness refuses the swap and this
|
|
109
|
+
* surface explains why rather than pretending otherwise. Before the first
|
|
110
|
+
* turn the switch is recorded in the log, which is what keeps the transcript
|
|
111
|
+
* honest about the composition later turns ran under.
|
|
112
|
+
*/
|
|
113
|
+
const runPresetCommand = (argument) => {
|
|
114
|
+
const roster = ports.agentPresets;
|
|
115
|
+
if (roster === undefined) {
|
|
116
|
+
ports.notice('this profile has no agent roster, so there is no mode to choose');
|
|
117
|
+
ports.render();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const agent = ports.drivingAgent();
|
|
121
|
+
if (agent === undefined) {
|
|
122
|
+
ports.notice('the agent is still starting; try again in a moment');
|
|
123
|
+
ports.render();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const session = agent.agent.session;
|
|
127
|
+
const current = roster.current(session);
|
|
128
|
+
const command = parsePresetArgument(argument);
|
|
129
|
+
if (command.kind === 'pick') {
|
|
130
|
+
if (roster.started(session)) {
|
|
131
|
+
ports.notice(`this session runs ${current === undefined ? 'a mode' : `"${current}"`} and has already started, so its mode is fixed — /new starts a fresh session`);
|
|
132
|
+
ports.render();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
void askForPreset(current).then(picked => picked === undefined ? undefined : applyPreset(picked));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
void applyPreset(command.id);
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Resolve the mode named on the command line and refuse a launch that cannot
|
|
142
|
+
* run it.
|
|
143
|
+
*
|
|
144
|
+
* Raised while the launcher still owns the terminal, because the alternate
|
|
145
|
+
* screen closes over whatever was painted on it: a mode this roster does not
|
|
146
|
+
* offer has to be answered here rather than as a blank screen.
|
|
147
|
+
*/
|
|
148
|
+
const validateLaunch = async (launch) => {
|
|
149
|
+
const roster = ports.agentPresets;
|
|
150
|
+
if (requestedPreset !== undefined && roster !== undefined) {
|
|
151
|
+
seat = (await roster.resolve(requestedPreset)).id;
|
|
152
|
+
}
|
|
153
|
+
if (!launch.resumePicker)
|
|
154
|
+
await presetFor(launch.sessionId, launch.resume, undefined);
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
presetFor,
|
|
158
|
+
validateLaunch,
|
|
159
|
+
runPresetCommand,
|
|
160
|
+
currentSeat: seatMode,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=preset-choice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-choice.js","sourceRoot":"","sources":["../../src/surface/preset-choice.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type KeyId } from '@earendil-works/pi-tui';
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
4
|
+
import { type Keymap } from '../input/actions.ts';
|
|
5
|
+
import { type RegisteredCommand } from '../input/completion.ts';
|
|
6
|
+
import { type Submission } from '../input/submission.ts';
|
|
7
|
+
import type { WarningSafeTui } from '../terminal/warning-screen.ts';
|
|
8
|
+
import type { GateInputBar } from '../ui/gate-input.ts';
|
|
9
|
+
import type { PromptBar } from '../ui/prompt.ts';
|
|
10
|
+
/**
|
|
11
|
+
* What the prompt-input owner needs from the surface that composes it.
|
|
12
|
+
*
|
|
13
|
+
* Every read is taken at call time. The keys, their prefix and the chord window
|
|
14
|
+
* belong to the settings document, which is hot-reloaded, so a copy kept here
|
|
15
|
+
* would answer the reader's next press with the map of the day this loaded. The
|
|
16
|
+
* terminal and the bar are reached through readers for the opposite reason: the
|
|
17
|
+
* settings scope applies before either exists, and the chord it has to end is
|
|
18
|
+
* armed at that moment.
|
|
19
|
+
*/
|
|
20
|
+
export interface PromptInputPorts {
|
|
21
|
+
/** The keys in force; the settings document owns them and the surface holds them. */
|
|
22
|
+
readonly keymap: () => Keymap;
|
|
23
|
+
/** The keys that start a chord, and how long one waits; the settings document owns all of it. */
|
|
24
|
+
readonly prefixKeys: () => readonly KeyId[];
|
|
25
|
+
readonly prefixWindowMs: () => number;
|
|
26
|
+
readonly tui: () => WarningSafeTui;
|
|
27
|
+
/** The bar the reader types in, and the question that borrows it. */
|
|
28
|
+
readonly editor: () => GateInputBar;
|
|
29
|
+
readonly promptBar: () => PromptBar;
|
|
30
|
+
/** Drive an open gate or picker; false hands the press back. */
|
|
31
|
+
readonly modalHandleKey: (data: string) => boolean;
|
|
32
|
+
/** Flip one of the folds the transcript is drawn with. */
|
|
33
|
+
readonly toggleCards: () => void;
|
|
34
|
+
readonly toggleSubCalls: () => void;
|
|
35
|
+
readonly toggleReasoning: () => void;
|
|
36
|
+
readonly openEffortPicker: () => void;
|
|
37
|
+
readonly openHistoryPicker: () => void;
|
|
38
|
+
/** Return to this session's own transcript, when a child is on screen. */
|
|
39
|
+
readonly back: () => void;
|
|
40
|
+
/** What the agent has not started yet, which one press takes back. */
|
|
41
|
+
readonly queuedPrompts: () => readonly string[];
|
|
42
|
+
readonly turnRunning: () => boolean;
|
|
43
|
+
readonly viewingChild: () => boolean;
|
|
44
|
+
readonly interrupt: () => void;
|
|
45
|
+
readonly notice: (message: string) => void;
|
|
46
|
+
readonly requestExit: (code: number) => void;
|
|
47
|
+
/** Remember one submitted line; the prompt's own memory owns the store. */
|
|
48
|
+
readonly recordPrompt: (text: string) => void;
|
|
49
|
+
/** Carry out one classified line; the command routing owner takes it over later. */
|
|
50
|
+
readonly runSubmission: (submission: Submission) => void;
|
|
51
|
+
/** The agent this terminal drives, or undefined while it starts. */
|
|
52
|
+
readonly drivenAgent: () => Agent | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* The commands that agent can run, or undefined when no registry answers.
|
|
55
|
+
*
|
|
56
|
+
* A scoped list operation rather than the registry itself: the registry is
|
|
57
|
+
* read through its own owner, and this one only ever needs what is offered.
|
|
58
|
+
*/
|
|
59
|
+
readonly registeredCommands: (agent: Agent) => readonly RegisteredCommand[] | undefined;
|
|
60
|
+
}
|
|
61
|
+
/** The presses, menus and the submit line the composing surface routes here. */
|
|
62
|
+
export interface PromptInput {
|
|
63
|
+
/**
|
|
64
|
+
* Install the reader's keys where the library reads them.
|
|
65
|
+
*
|
|
66
|
+
* Installed where the library reads it, so a remap lands on the next press
|
|
67
|
+
* rather than at the next restart.
|
|
68
|
+
*/
|
|
69
|
+
readonly installBindings: () => void;
|
|
70
|
+
/** A chord armed under the keymap the reader just replaced is not their chord. */
|
|
71
|
+
readonly disarmChord: () => void;
|
|
72
|
+
/** The armed chord as the footer prints it, or undefined when nothing is armed. */
|
|
73
|
+
readonly chordHint: () => string | undefined;
|
|
74
|
+
/** Register this owner's press listener; the answer takes it back off. */
|
|
75
|
+
readonly inputListener: () => () => void;
|
|
76
|
+
/** Give the bar the menu the role it is in calls for. */
|
|
77
|
+
readonly applyCompletion: () => void;
|
|
78
|
+
/** Rebuild both menus from whatever this session can run right now. */
|
|
79
|
+
readonly installCompletion: () => void;
|
|
80
|
+
/** Register the rebuild a newly registered command asks for. */
|
|
81
|
+
readonly commandListeners: () => readonly (() => void)[];
|
|
82
|
+
/** Classify a submitted line, remember it, and hand it to the surface. */
|
|
83
|
+
readonly attachSubmit: () => void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The prompt bar's own presses: the chord, the keys the surface answers itself,
|
|
87
|
+
* and the line it submits.
|
|
88
|
+
*
|
|
89
|
+
* A press reaches the surface's listener before any focused component sees it,
|
|
90
|
+
* so everything that answers a key held at the bar is decided in one place:
|
|
91
|
+
* what a chord may finish, which keys are consumed outright, and where a
|
|
92
|
+
* submitted line goes. The two completion menus share the same seam because
|
|
93
|
+
* they follow the bar's role rather than a session, and the command registry
|
|
94
|
+
* that fills one of them is read live.
|
|
95
|
+
*/
|
|
96
|
+
export declare function createPromptInput(ctx: Context, ports: PromptInputPorts): PromptInput;
|
|
97
|
+
//# sourceMappingURL=prompt-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-input.d.ts","sourceRoot":"","sources":["../../src/surface/prompt-input.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { isKeyRelease, matchesKey, } from '@earendil-works/pi-tui';
|
|
2
|
+
import { surfaceBindings } from "../input/actions.js";
|
|
3
|
+
import { cancelStep, quitStep } from "../input/cancel.js";
|
|
4
|
+
import { createAnswerCompletionProvider, createCompletionProvider } from "../input/completion.js";
|
|
5
|
+
import { createFileIndex } from "../input/file-index.js";
|
|
6
|
+
import { ChordReader, chordBindings, installKeybindings } from "../input/keymap.js";
|
|
7
|
+
import { classifySubmission } from "../input/submission.js";
|
|
8
|
+
/**
|
|
9
|
+
* The prompt bar's own presses: the chord, the keys the surface answers itself,
|
|
10
|
+
* and the line it submits.
|
|
11
|
+
*
|
|
12
|
+
* A press reaches the surface's listener before any focused component sees it,
|
|
13
|
+
* so everything that answers a key held at the bar is decided in one place:
|
|
14
|
+
* what a chord may finish, which keys are consumed outright, and where a
|
|
15
|
+
* submitted line goes. The two completion menus share the same seam because
|
|
16
|
+
* they follow the bar's role rather than a session, and the command registry
|
|
17
|
+
* that fills one of them is read live.
|
|
18
|
+
*/
|
|
19
|
+
export function createPromptInput(ctx, ports) {
|
|
20
|
+
/**
|
|
21
|
+
* The chord between a prefix and the action that follows it.
|
|
22
|
+
*
|
|
23
|
+
* Built before the terminal exists, because the settings scope applies first
|
|
24
|
+
* and has to be able to end a chord armed under the keymap it replaced. The
|
|
25
|
+
* repaint the window also wants is late-bound: only a key press reaches it,
|
|
26
|
+
* and no key can arrive before the surface has started.
|
|
27
|
+
*/
|
|
28
|
+
const keyChord = new ChordReader(() => ports.prefixKeys(), () => chordBindings(ports.keymap()), () => ports.prefixWindowMs(), () => ports.tui().requestRender());
|
|
29
|
+
/**
|
|
30
|
+
* Whether the bar holds anything the reader wrote.
|
|
31
|
+
*
|
|
32
|
+
* Whitespace counts: it is a character the editor holds, and a press that
|
|
33
|
+
* clears it is the press the reader asked for. A paste counts expanded,
|
|
34
|
+
* because a marker is content rather than an absence of it.
|
|
35
|
+
*/
|
|
36
|
+
const barHasText = () => ports.editor().getExpandedText() !== '';
|
|
37
|
+
/**
|
|
38
|
+
* What each key the surface answers itself does; false hands the press back.
|
|
39
|
+
*
|
|
40
|
+
* Keyed by the table's own ids, so a key added to {@link SURFACE_ACTIONS}
|
|
41
|
+
* without a handler here fails to compile rather than doing nothing.
|
|
42
|
+
*/
|
|
43
|
+
const surfaceActions = {
|
|
44
|
+
toolDetail: () => {
|
|
45
|
+
ports.toggleCards();
|
|
46
|
+
ports.tui().requestRender();
|
|
47
|
+
return true;
|
|
48
|
+
},
|
|
49
|
+
subCalls: () => {
|
|
50
|
+
ports.toggleSubCalls();
|
|
51
|
+
ports.tui().requestRender();
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
reasoning: () => {
|
|
55
|
+
ports.toggleReasoning();
|
|
56
|
+
ports.tui().requestRender();
|
|
57
|
+
return true;
|
|
58
|
+
},
|
|
59
|
+
effort: () => {
|
|
60
|
+
ports.openEffortPicker();
|
|
61
|
+
return true;
|
|
62
|
+
},
|
|
63
|
+
history: () => {
|
|
64
|
+
ports.openHistoryPicker();
|
|
65
|
+
return true;
|
|
66
|
+
},
|
|
67
|
+
back: () => {
|
|
68
|
+
ports.back();
|
|
69
|
+
return true;
|
|
70
|
+
},
|
|
71
|
+
interrupt: () => {
|
|
72
|
+
// In raw mode Ctrl+C never reaches the process as SIGINT, so the surface
|
|
73
|
+
// decides what one press takes back — and a press with nothing left to
|
|
74
|
+
// cancel is handed back rather than spent on leaving.
|
|
75
|
+
const queued = ports.queuedPrompts();
|
|
76
|
+
const step = cancelStep({
|
|
77
|
+
barHasText: barHasText(),
|
|
78
|
+
queuedPrompts: queued.length,
|
|
79
|
+
turnRunning: ports.turnRunning(),
|
|
80
|
+
viewingChild: ports.viewingChild(),
|
|
81
|
+
});
|
|
82
|
+
switch (step) {
|
|
83
|
+
case 'clear-editor':
|
|
84
|
+
ports.editor().setText('');
|
|
85
|
+
ports.tui().requestRender();
|
|
86
|
+
return true;
|
|
87
|
+
case 'reclaim-queued':
|
|
88
|
+
// The interrupt drops whatever the agent had not started, so the words
|
|
89
|
+
// are read before it is stopped and handed back to the bar: a key that
|
|
90
|
+
// means "stop" must not be the key that loses the reader's own prompts.
|
|
91
|
+
ports.interrupt();
|
|
92
|
+
ports.editor().setText(queued.join('\n'));
|
|
93
|
+
ports.notice(`interrupt requested · ${queued.length} queued ${queued.length === 1 ? 'prompt' : 'prompts'} back in the bar`);
|
|
94
|
+
ports.tui().requestRender();
|
|
95
|
+
return true;
|
|
96
|
+
case 'interrupt-turn':
|
|
97
|
+
ports.interrupt();
|
|
98
|
+
ports.notice('interrupt requested');
|
|
99
|
+
ports.tui().requestRender();
|
|
100
|
+
return true;
|
|
101
|
+
case 'leave-child-view':
|
|
102
|
+
ports.back();
|
|
103
|
+
return true;
|
|
104
|
+
case 'hand-back':
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
quit: () => {
|
|
109
|
+
// The only key that leaves. Text in the bar keeps it for the editor, so
|
|
110
|
+
// the library's delete forward is never taken from a reader who is editing.
|
|
111
|
+
switch (quitStep({ barHasText: barHasText(), overlayOpen: ports.tui().hasOverlay(), turnRunning: ports.turnRunning() })) {
|
|
112
|
+
case 'cancel-then-quit':
|
|
113
|
+
// An exit that waits on a tool call is not an exit, so the turn is
|
|
114
|
+
// asked to stop and the leave does not wait for the answer.
|
|
115
|
+
ports.interrupt();
|
|
116
|
+
ports.requestExit(0);
|
|
117
|
+
return true;
|
|
118
|
+
case 'quit':
|
|
119
|
+
ports.requestExit(0);
|
|
120
|
+
return true;
|
|
121
|
+
case 'hand-back':
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
/** One scan of the workspace, shared by both menus: the listing is read-only and cached. */
|
|
127
|
+
const fileIndex = createFileIndex(process.cwd());
|
|
128
|
+
/** The menu the prompt bar offers: the commands this session can run, and the workspace's files. */
|
|
129
|
+
let promptCompletion;
|
|
130
|
+
/** The menu an answer offers, which is the same menu without the commands. */
|
|
131
|
+
let answerCompletion;
|
|
132
|
+
/**
|
|
133
|
+
* Give the bar the menu its current role calls for.
|
|
134
|
+
*
|
|
135
|
+
* A question borrows the prompt bar's editor rather than drawing its own, so
|
|
136
|
+
* the provider has to follow the borrow: a slash command is a line this
|
|
137
|
+
* surface would run, and an answer is text the model reads, so the two roles
|
|
138
|
+
* must not share one menu.
|
|
139
|
+
*/
|
|
140
|
+
const applyCompletion = () => {
|
|
141
|
+
const chosen = ports.promptBar().isBorrowed() ? answerCompletion : promptCompletion;
|
|
142
|
+
if (chosen !== undefined)
|
|
143
|
+
ports.editor().setAutocompleteProvider(chosen);
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Offer completion for whatever this session can run right now.
|
|
147
|
+
*
|
|
148
|
+
* The registry is agent-scoped and still empty while the agent starts, so the
|
|
149
|
+
* menu is rebuilt when the agent arrives and whenever a package registers
|
|
150
|
+
* another command. Both providers are built here because the answer's is the
|
|
151
|
+
* prompt bar's own minus the commands, and a rebuild while a question is open
|
|
152
|
+
* must not leave the answer menu unreachable.
|
|
153
|
+
*/
|
|
154
|
+
const installCompletion = () => {
|
|
155
|
+
const current = ports.drivenAgent();
|
|
156
|
+
if (current === undefined)
|
|
157
|
+
return;
|
|
158
|
+
const commands = ports.registeredCommands(current);
|
|
159
|
+
if (commands === undefined)
|
|
160
|
+
return;
|
|
161
|
+
answerCompletion = createAnswerCompletionProvider(process.cwd(), fileIndex);
|
|
162
|
+
promptCompletion = createCompletionProvider(commands, process.cwd(), fileIndex);
|
|
163
|
+
applyCompletion();
|
|
164
|
+
};
|
|
165
|
+
return {
|
|
166
|
+
installBindings: () => installKeybindings(ports.keymap()),
|
|
167
|
+
disarmChord: () => keyChord.disarm(),
|
|
168
|
+
chordHint: () => keyChord.hint(),
|
|
169
|
+
applyCompletion,
|
|
170
|
+
installCompletion,
|
|
171
|
+
commandListeners: () => [ctx.on('commands/change', () => installCompletion())],
|
|
172
|
+
inputListener: () => ports.tui().addInputListener(data => {
|
|
173
|
+
// A key arrives as a press and a release once the surface asks the terminal
|
|
174
|
+
// to report key events, and this library drops the release only for the
|
|
175
|
+
// focused component: a listener sees both halves, so an arrow key that is
|
|
176
|
+
// acted on twice steps a picker two rows and answers a question two options
|
|
177
|
+
// on. Falls through rather than consuming, which leaves a component that
|
|
178
|
+
// asked for releases its own half.
|
|
179
|
+
if (isKeyRelease(data))
|
|
180
|
+
return undefined;
|
|
181
|
+
if (ports.modalHandleKey(data))
|
|
182
|
+
return { consume: true };
|
|
183
|
+
// A chord is the surface's second key: the prefix is consumed and the
|
|
184
|
+
// footer names what may follow, while a key that finishes nothing is handed
|
|
185
|
+
// on. Detail the reader asked for is always available, even mid-turn: the
|
|
186
|
+
// collapsed view is a default, not the only state.
|
|
187
|
+
const chorded = keyChord.handle(data);
|
|
188
|
+
if (chorded !== undefined) {
|
|
189
|
+
if (chorded.kind === 'action')
|
|
190
|
+
ports.runSubmission(chorded.binding.submission);
|
|
191
|
+
ports.tui().requestRender();
|
|
192
|
+
return { consume: true };
|
|
193
|
+
}
|
|
194
|
+
for (const binding of surfaceBindings(ports.keymap())) {
|
|
195
|
+
if (!matchesKey(data, binding.key))
|
|
196
|
+
continue;
|
|
197
|
+
return surfaceActions[binding.action]() ? { consume: true } : undefined;
|
|
198
|
+
}
|
|
199
|
+
return undefined;
|
|
200
|
+
}),
|
|
201
|
+
attachSubmit: () => {
|
|
202
|
+
ports.editor().onSubmit = text => {
|
|
203
|
+
const submission = classifySubmission(text);
|
|
204
|
+
if (submission.kind === 'empty')
|
|
205
|
+
return;
|
|
206
|
+
// The library's own history feeds the up/down keys; the store below feeds
|
|
207
|
+
// ghost completion and reverse search, and is global rather than per-session.
|
|
208
|
+
ports.editor().addToHistory(text);
|
|
209
|
+
ports.recordPrompt(text);
|
|
210
|
+
ports.runSubmission(submission);
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=prompt-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-input.js","sourceRoot":"","sources":["../../src/surface/prompt-input.ts"],"names":[],"mappings":"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"}
|