context injection — named reference blurbs from contexts.toml injected ahead of a
dictated instruction, read-before-send (never auto-submits):
- new contexts.py mirrors config.py: [contexts] name = "blurb"; missing file = empty
set; names validated as simple words, looked up on a despaced/lowercased key so
"web hooks"/"web-hooks"/"webhooks" all resolve the same block.
- grammar: context|prepare <name> <instruction> -> Action("context", (name, dictation)).
same-utterance dictation (everything after <name> is literal, incl. "send"); bare
context <name> injects just the blurb. one-shot targeting composes:
[target <name>] [context <ctx>] [filler] <dictation>.
- daemon assembles blurb + (Shift+Enter soft newline | flattened separator) + dictation
via the existing send_literal/type path, tracks the uncommitted-input buffer, and
WAITS. config-gated by behavior.context_multiline / context_separator. unknown context
name announces and injects nothing.
system daemon-control namespace — lands the pass-through vs control split the router was
structured for. reserved leading "system" routes to _do_system (never injects to
claude): system status (mode/target/model/contexts) and system reload [config|contexts].
live reload — voice reload + CLI claudedo reload (SIGHUP) re-read config.toml +
contexts.toml without reinitializing the loaded whisper model. customs now lists loaded
contexts. install.sh installs the contexts.toml template copy-if-absent (else .new).
keys.NEWLINE (S-Enter) added for the soft-newline assembly. wake list unchanged.
Signed-off-by: disqualifier <dev@disqualifier.me>
64 lines
2.4 KiB
Python
64 lines
2.4 KiB
Python
"""the claude code prompt keymap — single source of truth.
|
|
|
|
these keystrokes were confirmed empirically against a live ``claude`` v2.1.191
|
|
session in a throwaway tmux session (capture-pane observation of benign prompts:
|
|
the folder-trust prompt and a bash-command permission prompt). do not guess or
|
|
assume — if claude code changes its prompt ui, re-confirm against a live session
|
|
and update here.
|
|
|
|
confirmed behaviour (claude code v2.1.191):
|
|
- numbered select menus (trust prompt, permission prompt): pressing the bare
|
|
digit selects AND confirms IMMEDIATELY. NO trailing enter. (sending an extra
|
|
enter would leak into the next prompt or the input box.)
|
|
- arrow keys (Up/Down) move the highlight WITHOUT acting; Enter then confirms —
|
|
available as a robust alternative, modelled as a sequence.
|
|
- the permission prompt is "1. Yes / 2. Yes, and don't ask again / 3. No".
|
|
- Escape backs out of / cancels a prompt ("Esc to cancel" footer).
|
|
- the main input box: literal text is inserted via ``send-keys -l`` without
|
|
submitting; a bare Enter submits.
|
|
|
|
each value is a list of tmux key tokens to send in order. a single-element list
|
|
is a single keypress. ``type`` literal text is handled separately by inject.py
|
|
via ``send-keys -l`` and is not part of this keymap.
|
|
"""
|
|
|
|
YES = ["1"]
|
|
NO = ["3"]
|
|
|
|
SELECT_1 = ["1"]
|
|
SELECT_2 = ["2"]
|
|
SELECT_3 = ["3"]
|
|
SELECT_4 = ["4"]
|
|
|
|
APPROVE = ["1"]
|
|
APPROVE_ALWAYS = ["2"]
|
|
DENY = ["3"]
|
|
|
|
SUBMIT = ["Enter"]
|
|
CANCEL = ["Escape"]
|
|
|
|
# NEWLINE is a soft newline inside the input box that does NOT submit — Shift+Enter,
|
|
# which tmux names ``S-Enter`` (requires the extended-keys / xterm extkeys tmux
|
|
# settings install.sh appends). used to separate a context blurb from the dictated
|
|
# instruction in multiline assembly; if it proves flaky the daemon flattens to one
|
|
# line with a separator instead (behavior.context_multiline = false).
|
|
NEWLINE = ["S-Enter"]
|
|
|
|
# BACKSPACE deletes one char left; SPACE inserts one literal space. both are emitted
|
|
# repeatedly for `backspace <n>` / `space <n>` and for `erase` (n = the daemon's
|
|
# tracked uncommitted-input count). BSpace is tmux's name for the backspace key.
|
|
BACKSPACE = ["BSpace"]
|
|
SPACE = [" "]
|
|
|
|
SELECT_BY_INDEX = {
|
|
1: SELECT_1,
|
|
2: SELECT_2,
|
|
3: SELECT_3,
|
|
4: SELECT_4,
|
|
}
|
|
|
|
SELECT_1_ARROW = ["Up", "Up", "Up", "Enter"]
|
|
SELECT_2_ARROW = ["Up", "Up", "Enter"]
|
|
SELECT_3_ARROW = ["Up", "Enter"]
|
|
SELECT_4_ARROW = ["Enter"]
|