@knightcodeai/cli-linux-arm64 0.9.1 → 0.9.3

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.
Files changed (45) hide show
  1. package/bin/CHANGELOG.md +60 -0
  2. package/bin/README.md +52 -19
  3. package/bin/docs/cli-integration.md +106 -0
  4. package/bin/docs/cli.md +270 -0
  5. package/bin/docs/compaction.md +56 -37
  6. package/bin/docs/configuration.md +46 -0
  7. package/bin/docs/containerization.md +86 -54
  8. package/bin/docs/custom-provider.md +132 -785
  9. package/bin/docs/docs.json +143 -103
  10. package/bin/docs/environment-variables.md +5 -4
  11. package/bin/docs/extensions.md +134 -2956
  12. package/bin/docs/how-knightcode-works.md +49 -0
  13. package/bin/docs/index.md +24 -69
  14. package/bin/docs/json.md +193 -65
  15. package/bin/docs/keybindings.md +56 -101
  16. package/bin/docs/llama-cpp.md +3 -3
  17. package/bin/docs/message-types.md +261 -0
  18. package/bin/docs/models.md +64 -547
  19. package/bin/docs/packages.md +66 -167
  20. package/bin/docs/prompt-templates.md +31 -68
  21. package/bin/docs/providers.md +103 -241
  22. package/bin/docs/quickstart.md +61 -106
  23. package/bin/docs/rpc-commands.md +854 -0
  24. package/bin/docs/rpc-extension-ui.md +200 -0
  25. package/bin/docs/rpc.md +129 -1556
  26. package/bin/docs/sdk.md +76 -1160
  27. package/bin/docs/security.md +70 -32
  28. package/bin/docs/session-format.md +25 -216
  29. package/bin/docs/sessions.md +38 -143
  30. package/bin/docs/settings.md +111 -389
  31. package/bin/docs/shell-aliases.md +85 -5
  32. package/bin/docs/skills.md +51 -189
  33. package/bin/docs/slash-commands.md +63 -0
  34. package/bin/docs/terminal-setup.md +107 -79
  35. package/bin/docs/termux.md +74 -83
  36. package/bin/docs/themes.md +68 -280
  37. package/bin/docs/tmux.md +31 -39
  38. package/bin/docs/tui.md +69 -923
  39. package/bin/docs/usage.md +79 -286
  40. package/bin/docs/windows.md +43 -17
  41. package/bin/export-html/template.js +6 -1
  42. package/bin/knightcode +2 -2
  43. package/bin/package.json +6 -6
  44. package/package.json +1 -1
  45. package/bin/docs/development.md +0 -71
@@ -1,16 +1,35 @@
1
- # Keybindings
1
+ # Keybindings Reference
2
2
 
3
- All keyboard shortcuts can be customized via `~/.knightcode/agent/keybindings.json`. Each action can be bound to one or more keys.
3
+ KnightCode exposes named actions, such as `app.session.new`, that can be assigned keybindings. You can change default assignments or bind unassigned actions in KnightCode's [user configuration](configuration.md#agent-directory).
4
4
 
5
- The config file uses the same namespaced keybinding ids that knightcode uses internally and that extension authors use in `keyHint()` and injected `keybindings` managers.
5
+ Run `/hotkeys` to see the active shortcuts for the main editor and application.
6
6
 
7
- Older configs using pre-namespaced ids such as `cursorUp` or `expandTools` are migrated automatically to the namespaced ids on startup.
7
+ ## Assign keybindings
8
8
 
9
- After editing `keybindings.json`, run `/reload` in knightcode to apply the changes without restarting the session.
9
+ Create `<agent-dir>/keybindings.json`. The agent directory defaults to `~/.knightcode/agent` and is described in [Agent directory](configuration.md#agent-directory).
10
10
 
11
- ## Key Format
11
+ Map each action identifier to one key or a list of keys:
12
12
 
13
- `modifier+key` where modifiers are `ctrl`, `shift`, `alt`, `super` (combinable) and keys are:
13
+ ```json
14
+ {
15
+ "app.session.new": "ctrl+shift+n",
16
+ "app.session.tree": ["ctrl+shift+t", "alt+shift+t"]
17
+ }
18
+ ```
19
+
20
+ A configured value replaces the default for that action. Use an empty list to disable an action's keybindings:
21
+
22
+ ```json
23
+ {
24
+ "tui.altScreen.pageUp": []
25
+ }
26
+ ```
27
+
28
+ After editing the file, run `/reload` to apply the changes to the active session.
29
+
30
+ ## Key syntax
31
+
32
+ Write a key as `modifier+key`. Modifiers are `ctrl`, `shift`, `alt`, and `super`. You can combine modifiers. Valid keys are:
14
33
 
15
34
  - **Letters:** `a-z`
16
35
  - **Digits:** `0-9`
@@ -18,20 +37,22 @@ After editing `keybindings.json`, run `/reload` in knightcode to apply the chang
18
37
  - **Function:** `f1`-`f12`
19
38
  - **Symbols:** `` ` ``, `-`, `=`, `[`, `]`, `\`, `;`, `'`, `,`, `.`, `/`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `(`, `)`, `_`, `+`, `|`, `~`, `{`, `}`, `:`, `<`, `>`, `?`
20
39
 
21
- Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `super+k`, `ctrl+super+k`, `ctrl+1`, etc.
40
+ Examples: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `super+k`, `ctrl+super+k`, and `ctrl+1`.
22
41
 
23
42
  `super` bindings require a terminal that reports the modifier separately, typically through the Kitty keyboard protocol. They may not work in terminals without that support.
24
43
 
25
- ## All Actions
44
+ ## Actions
45
+
46
+ ### Terminal UI
26
47
 
27
- ### TUI Editor Cursor Movement
48
+ #### Cursor movement
28
49
 
29
50
  | Keybinding id | Default | Description |
30
- |--------|---------|-------------|
51
+ |---|---|---|
31
52
  | `tui.editor.cursorUp` | `up` | Move cursor up, browsing older history at the top |
32
53
  | `tui.editor.cursorDown` | `down` | Move cursor down, browsing newer history at the bottom |
33
- | `tui.editor.historyPrevious` | *(none)* | Select the previous prompt history entry |
34
- | `tui.editor.historyNext` | *(none)* | Select the next prompt history entry |
54
+ | `tui.editor.historyPrevious` | None | Select the previous prompt history entry |
55
+ | `tui.editor.historyNext` | None | Select the next prompt history entry |
35
56
  | `tui.editor.cursorLeft` | `left`, `ctrl+b` | Move cursor left |
36
57
  | `tui.editor.cursorRight` | `right`, `ctrl+f` | Move cursor right |
37
58
  | `tui.editor.cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
@@ -43,39 +64,29 @@ Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, `super+
43
64
  | `tui.editor.pageUp` | `pageUp`, `ctrl+pageUp` | Scroll up by page |
44
65
  | `tui.editor.pageDown` | `pageDown`, `ctrl+pageDown` | Scroll down by page |
45
66
 
46
- The dedicated history actions always change history entries, regardless of the cursor position in a multiline prompt. Explicit history bindings take precedence over application actions while the main editor is focused, so binding `tui.editor.historyPrevious` to `ctrl+p` overrides model cycling in that context without changing `Ctrl+P` in selectors.
67
+ The dedicated history actions browse prompt history regardless of cursor position and take precedence over application actions using the same key.
47
68
 
48
- ### TUI Editor Deletion
69
+ #### Text editing
49
70
 
50
71
  | Keybinding id | Default | Description |
51
- |--------|---------|-------------|
72
+ |---|---|---|
52
73
  | `tui.editor.deleteCharBackward` | `backspace` | Delete character backward |
53
74
  | `tui.editor.deleteCharForward` | `delete`, `ctrl+d` | Delete character forward |
54
75
  | `tui.editor.deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward |
55
76
  | `tui.editor.deleteWordForward` | `alt+d`, `alt+delete` | Delete word forward |
56
77
  | `tui.editor.deleteToLineStart` | `ctrl+u` | Delete to line start |
57
78
  | `tui.editor.deleteToLineEnd` | `ctrl+k` | Delete to line end |
58
-
59
- ### TUI Input
60
-
61
- | Keybinding id | Default | Description |
62
- |--------|---------|-------------|
63
- | `tui.input.newLine` | `shift+enter`, `ctrl+j` | Insert new line |
64
- | `tui.input.submit` | `enter` | Submit input |
65
- | `tui.input.tab` | `tab` | Tab / autocomplete |
66
-
67
- ### TUI Kill Ring
68
-
69
- | Keybinding id | Default | Description |
70
- |--------|---------|-------------|
71
79
  | `tui.editor.yank` | `ctrl+y` | Paste most recently deleted text |
72
80
  | `tui.editor.yankPop` | `alt+y` | Cycle through deleted text after yank |
73
81
  | `tui.editor.undo` | `ctrl+-` (`ctrl+z` on Windows; `alt+z` on WSL) | Undo last edit |
74
82
 
75
- ### TUI Clipboard and Selection
83
+ #### Input and selection
76
84
 
77
85
  | Keybinding id | Default | Description |
78
- |--------|---------|-------------|
86
+ |---|---|---|
87
+ | `tui.input.newLine` | `shift+enter`, `ctrl+j` | Insert new line |
88
+ | `tui.input.submit` | `enter` | Submit input |
89
+ | `tui.input.tab` | `tab` | Tab or autocomplete |
79
90
  | `tui.input.copy` | `ctrl+c` | Copy selection |
80
91
  | `tui.select.up` | `up` | Move selection up |
81
92
  | `tui.select.down` | `down` | Move selection down |
@@ -84,31 +95,18 @@ The dedicated history actions always change history entries, regardless of the c
84
95
  | `tui.select.confirm` | `enter` | Confirm selection |
85
96
  | `tui.select.cancel` | `escape`, `ctrl+c` | Cancel selection |
86
97
 
87
- ### TUI Fullscreen Viewport
88
-
89
- These actions apply when interactive mode uses `--tui-mode fullscreen` and target the primary transcript scroll region. Two-finger trackpad and mouse-wheel input scroll the region under the pointer, falling back to the transcript over the fixed editor/status/footer dock. Clicking an OSC 8 hyperlink opens it in the default handler. Dragging with the primary mouse button selects text and copies it to the clipboard; holding at the transcript's top or bottom edge auto-scrolls into off-screen content. While the transcript is scrolled up, a clickable "Jump to latest message" label on its bottom row shows the `tui.altScreen.bottom` shortcut. See [Terminal setup](terminal-setup.md) for terminal-specific mouse and trackpad behavior.
90
-
91
- Fullscreen transcript bindings take precedence over editor bindings. The default unmodified navigation keys therefore control the transcript in fullscreen mode, while their `ctrl` variants continue to control the editor. Outside fullscreen mode, both variants control the editor.
92
-
93
- The transcript search panel shows the configured previous/next shortcuts and clickable arrow controls. Press `tui.altScreen.search` again, or use `tui.altScreen.searchClose`, to close it.
98
+ #### Fullscreen
94
99
 
95
- | Key | Default mode | Fullscreen mode |
96
- |-----|--------------|-----------------|
97
- | `home`, `end` | Editor | Transcript |
98
- | `ctrl+home`, `ctrl+end` | Editor | Editor |
99
- | `pageUp`, `pageDown` | Editor | Transcript |
100
- | `ctrl+pageUp`, `ctrl+pageDown` | Editor | Editor |
101
-
102
- This routing remains configurable through the ordinary action bindings. For example, `"tui.altScreen.pageUp": "ctrl+pageUp"` makes `pageUp` control the editor and `ctrl+pageUp` control the transcript in fullscreen mode. Bind `tui.altScreen.halfPageUp` and `tui.altScreen.halfPageDown` for half-page steps, or bind `tui.altScreen.lineUp` and `tui.altScreen.lineDown` for single-line steps. Setting `"tui.altScreen.pageUp": []` disables that transcript shortcut entirely. User bindings replace the defaults for that action.
100
+ In fullscreen mode, these actions control the transcript and take precedence over editor actions using the same key.
103
101
 
104
102
  | Keybinding id | Default | Description |
105
- |--------|---------|-------------|
103
+ |---|---|---|
106
104
  | `tui.altScreen.pageUp` | `pageUp` | Scroll the transcript up by one page |
107
105
  | `tui.altScreen.pageDown` | `pageDown` | Scroll the transcript down by one page |
108
- | `tui.altScreen.halfPageUp` | *(none)* | Scroll the transcript up by half a page |
109
- | `tui.altScreen.halfPageDown` | *(none)* | Scroll the transcript down by half a page |
110
- | `tui.altScreen.lineUp` | *(none)* | Scroll the transcript up by one line |
111
- | `tui.altScreen.lineDown` | *(none)* | Scroll the transcript down by one line |
106
+ | `tui.altScreen.halfPageUp` | None | Scroll the transcript up by half a page |
107
+ | `tui.altScreen.halfPageDown` | None | Scroll the transcript down by half a page |
108
+ | `tui.altScreen.lineUp` | None | Scroll the transcript up by one line |
109
+ | `tui.altScreen.lineDown` | None | Scroll the transcript down by one line |
112
110
  | `tui.altScreen.previousPrompt` | `ctrl+shift+up`, `ctrl+up` (`ctrl+up` only on Windows and WSL) | Jump to the previous marked message |
113
111
  | `tui.altScreen.nextPrompt` | `ctrl+shift+down`, `ctrl+down` (`ctrl+down` only on Windows and WSL) | Jump to the next marked message |
114
112
  | `tui.altScreen.search` | `ctrl+shift+f` (`ctrl+f` on Windows and WSL) | Search the rendered transcript |
@@ -125,18 +123,20 @@ This routing remains configurable through the ordinary action bindings. For exam
125
123
  | `app.interrupt` | `escape` | Cancel / abort |
126
124
  | `app.clear` | `ctrl+c` | Clear editor (first) / exit (second) |
127
125
  | `app.exit` | `ctrl+d` | Exit (when editor empty) |
128
- | `app.suspend` | `ctrl+z` (none on Windows) | Suspend to background |
126
+ | `app.suspend` | `ctrl+z` (None on Windows) | Suspend to background |
129
127
  | `app.editor.external` | `ctrl+g` | Open in external editor (`externalEditor`, `$VISUAL`, `$EDITOR`, Notepad on Windows, or `nano` elsewhere) |
130
128
  | `app.clipboard.pasteImage` | `ctrl+v` (`alt+v` on Windows and WSL) | Paste image or text from clipboard |
131
129
 
130
+ On native Windows, `app.suspend` has no default because Windows terminals do not support Unix job control. If you assign it manually, KnightCode shows a status message instead of suspending. WSL uses the normal `ctrl+z` and `fg` behavior.
131
+
132
132
  ### Sessions
133
133
 
134
134
  | Keybinding id | Default | Description |
135
135
  |--------|---------|-------------|
136
- | `app.session.new` | *(none)* | Start a new session (`/new`) |
137
- | `app.session.tree` | *(none)* | Open session tree navigator (`/tree`) |
138
- | `app.session.fork` | *(none)* | Fork current session (`/fork`) |
139
- | `app.session.resume` | *(none)* | Open session resume picker (`/resume`) |
136
+ | `app.session.new` | None | Start a new session (`/new`) |
137
+ | `app.session.tree` | None | Open session tree navigator (`/tree`) |
138
+ | `app.session.fork` | None | Fork current session (`/fork`) |
139
+ | `app.session.resume` | None | Open session resume picker (`/resume`) |
140
140
  | `app.session.togglePath` | `ctrl+p` | Toggle path display |
141
141
  | `app.session.toggleSort` | `ctrl+s` | Toggle sort mode |
142
142
  | `app.session.toggleNamedFilter` | `ctrl+n` | Toggle named-only filter |
@@ -192,48 +192,3 @@ Used inside the scoped models selector (opened via `/scoped-models`).
192
192
  | `app.models.toggleProvider` | `ctrl+p` | Toggle all models for the current provider |
193
193
  | `app.models.reorderUp` | `alt+up` | Move the selected model up in the cycle order |
194
194
  | `app.models.reorderDown` | `alt+down` | Move the selected model down in the cycle order |
195
-
196
- ## Custom Configuration
197
-
198
- Create `~/.knightcode/agent/keybindings.json`:
199
-
200
- ```json
201
- {
202
- "tui.editor.historyPrevious": "ctrl+p",
203
- "tui.editor.historyNext": "ctrl+n",
204
- "tui.editor.deleteWordBackward": ["ctrl+w", "alt+backspace"]
205
- }
206
- ```
207
-
208
- Each action can have a single key or an array of keys. User config overrides defaults.
209
-
210
- On native Windows, `app.suspend` has no default binding because Windows terminals do not support Unix job control. If you bind it manually, knightcode shows a status message instead of suspending. In WSL, the normal Linux `ctrl+z`/`fg` behavior still applies.
211
-
212
- ### Emacs Example
213
-
214
- ```json
215
- {
216
- "tui.editor.historyPrevious": "ctrl+p",
217
- "tui.editor.historyNext": "ctrl+n",
218
- "tui.editor.cursorLeft": ["left", "ctrl+b"],
219
- "tui.editor.cursorRight": ["right", "ctrl+f"],
220
- "tui.editor.cursorWordLeft": ["alt+left", "alt+b"],
221
- "tui.editor.cursorWordRight": ["alt+right", "alt+f"],
222
- "tui.editor.deleteCharForward": ["delete", "ctrl+d"],
223
- "tui.editor.deleteCharBackward": ["backspace", "ctrl+h"],
224
- "tui.input.newLine": ["shift+enter", "ctrl+j"]
225
- }
226
- ```
227
-
228
- ### Vim Example
229
-
230
- ```json
231
- {
232
- "tui.editor.cursorUp": ["up", "alt+k"],
233
- "tui.editor.cursorDown": ["down", "alt+j"],
234
- "tui.editor.cursorLeft": ["left", "alt+h"],
235
- "tui.editor.cursorRight": ["right", "alt+l"],
236
- "tui.editor.cursorWordLeft": ["alt+left", "alt+b"],
237
- "tui.editor.cursorWordRight": ["alt+right", "alt+w"]
238
- }
239
- ```
@@ -1,4 +1,4 @@
1
- # llama.cpp
1
+ # Local Models with llama.cpp
2
2
 
3
3
  KnightCode supports the [llama.cpp](https://github.com/ggml-org/llama.cpp) router server. The router discovers multiple GGUF models and loads or unloads them on demand.
4
4
 
@@ -82,7 +82,7 @@ Hugging Face search uses `HF_TOKEN` when set, then checks `$HF_TOKEN_PATH`, `$HF
82
82
 
83
83
  If other models are loaded, KnightCode asks whether to unload them first or keep them loaded. KnightCode does not silently unload models and never deletes model files. The router may be shared with other clients, so `/llama` always displays the router's current state.
84
84
 
85
- Only loaded models appear in `/model`. After loading a model, run `/model` to select it for the current KnightCode session.
85
+ Loaded and sleeping models appear in `/model`. Sleeping models wake automatically when selected. With router autoload enabled, unloaded preset models also appear and load when selected. With `--no-models-autoload`, load a model through `/llama` before selecting it.
86
86
 
87
87
  If the router disconnects, `/llama` shows **Retry** and **Close**. Retry reconnects and refreshes model state without replaying the interrupted operation.
88
88
 
@@ -96,6 +96,6 @@ curl http://127.0.0.1:8080/models
96
96
  ```
97
97
 
98
98
  - **No models in `/llama`:** Check `--models-dir`, the directory layout, and restart the router.
99
- - **Model missing from `/model`:** Load it with `/llama` first.
99
+ - **Model missing from `/model` with `--no-models-autoload`:** Load it with `/llama` first.
100
100
  - **Load fails or uses too much memory:** Lower `-c` or unload another model.
101
101
  - **Server is not in router mode:** Start it without `--model`, `-m`, or `-hf`.
@@ -0,0 +1,261 @@
1
+ # Message Types
2
+
3
+ KnightCode uses `AgentMessage` values in SDK state, lifecycle events, RPC responses, and persisted session message entries. This page defines those shared messages and their content blocks.
4
+
5
+ Message timestamps are Unix timestamps in milliseconds. They are different from the ISO 8601 timestamps on [session entries](session-format.md#entry-base).
6
+
7
+ Source definitions:
8
+
9
+ - [`packages/ai/src/types.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/ai/src/types.ts) defines provider-facing messages and content blocks.
10
+ - [`packages/agent/src/types.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/agent/src/types.ts) defines the extensible `AgentMessage` union.
11
+ - [`packages/cli/src/core/messages.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/core/messages.ts) adds CLI message roles.
12
+
13
+ ## Content blocks
14
+
15
+ ### TextContent
16
+
17
+ ```typescript
18
+ interface TextContent {
19
+ type: "text";
20
+ text: string;
21
+ textSignature?: string;
22
+ }
23
+ ```
24
+
25
+ `textSignature` contains provider-specific message metadata. Treat it as opaque.
26
+
27
+ ### ImageContent
28
+
29
+ ```typescript
30
+ interface ImageContent {
31
+ type: "image";
32
+ data: string;
33
+ mimeType: string;
34
+ }
35
+ ```
36
+
37
+ `data` is base64-encoded image data. `mimeType` identifies its media type, such as `image/png` or `image/jpeg`.
38
+
39
+ ### ThinkingContent
40
+
41
+ ```typescript
42
+ interface ThinkingContent {
43
+ type: "thinking";
44
+ thinking: string;
45
+ thinkingSignature?: string;
46
+ redacted?: boolean;
47
+ }
48
+ ```
49
+
50
+ Thinking signatures contain provider-specific replay data. Treat them as opaque. A redacted block can have no visible thinking text while retaining an encrypted payload in `thinkingSignature`.
51
+
52
+ ### ToolCall
53
+
54
+ ```typescript
55
+ interface ToolCall {
56
+ type: "toolCall";
57
+ id: string;
58
+ name: string;
59
+ arguments: Record<string, any>;
60
+ thoughtSignature?: string;
61
+ namespace?: string;
62
+ }
63
+ ```
64
+
65
+ `thoughtSignature` is provider-specific. `namespace` identifies an OpenAI Responses namespace for dynamically loaded or namespaced tools.
66
+
67
+ ## Usage
68
+
69
+ Assistant messages always contain usage. Tool results can contain usage when the tool performed nested model work.
70
+
71
+ ```typescript
72
+ interface Usage {
73
+ input: number;
74
+ output: number;
75
+ cacheRead: number;
76
+ cacheWrite: number;
77
+ cacheWrite1h?: number;
78
+ reasoning?: number;
79
+ totalTokens: number;
80
+ cost: {
81
+ input: number;
82
+ output: number;
83
+ cacheRead: number;
84
+ cacheWrite: number;
85
+ total: number;
86
+ };
87
+ }
88
+ ```
89
+
90
+ When present, `reasoning` is already included in `output`; do not add it again. `cacheWrite1h` is the subset of `cacheWrite` written with one-hour retention.
91
+
92
+ ## Base messages
93
+
94
+ ### SystemMessage
95
+
96
+ ```typescript
97
+ interface SystemMessage {
98
+ role: "system";
99
+ content: string | TextContent[];
100
+ sections?: Record<string, string | null>;
101
+ toolsAdded?: Tool[];
102
+ toolsRemoved?: ToolReference[];
103
+ replace?: boolean;
104
+ timestamp: number;
105
+ }
106
+ ```
107
+
108
+ The leading system message declares the initial prompt and tools. Later system messages can append instructions, replace or remove named prompt sections, and add or remove tools. Replaying them in order yields the current state. A message with `replace: true` discards the earlier state and establishes a complete new baseline.
109
+
110
+ ### UserMessage
111
+
112
+ ```typescript
113
+ interface UserMessage {
114
+ role: "user";
115
+ content: string | (TextContent | ImageContent)[];
116
+ timestamp: number;
117
+ }
118
+ ```
119
+
120
+ ### AssistantMessage
121
+
122
+ ```typescript
123
+ interface AssistantMessage {
124
+ role: "assistant";
125
+ content: (TextContent | ThinkingContent | ToolCall)[];
126
+ api: string;
127
+ provider: string;
128
+ model: string;
129
+ responseModel?: string;
130
+ responseId?: string;
131
+ providerThinkingLevel?: string;
132
+ diagnostics?: AssistantMessageDiagnostic[];
133
+ usage: Usage;
134
+ stopReason: "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
135
+ deferred?: DeferredHandle;
136
+ errorMessage?: string;
137
+ rawStopReason?: string;
138
+ endTurn?: boolean;
139
+ timestamp: number;
140
+ }
141
+ ```
142
+
143
+ `responseModel` records a concrete provider response model when it differs from the requested model. `responseId`, `providerThinkingLevel`, `diagnostics`, and `rawStopReason` preserve provider or runtime details.
144
+
145
+ `"pending"` is used for a partial assistant message while it streams. The completed message in `message_end` has a terminal stop reason, and KnightCode does not persist `"pending"` assistant messages in session JSONL.
146
+
147
+ A `"deferred"` response has a `DeferredHandle` with the provider data needed to retrieve it:
148
+
149
+ ```typescript
150
+ interface DeferredHandle {
151
+ provider: string;
152
+ modelId: string;
153
+ api: string;
154
+ id: string;
155
+ expiresAt?: number;
156
+ pollAfterMs?: number;
157
+ data?: JsonValue;
158
+ }
159
+ ```
160
+
161
+ ### ToolResultMessage
162
+
163
+ ```typescript
164
+ interface ToolResultMessage<TDetails = any> {
165
+ role: "toolResult";
166
+ toolCallId: string;
167
+ toolName: string;
168
+ content: (TextContent | ImageContent)[];
169
+ details?: TDetails;
170
+ usage?: Usage;
171
+ isError: boolean;
172
+ timestamp: number;
173
+ }
174
+ ```
175
+
176
+ `details` is tool-specific. Optional `usage` reports nested model work performed by the tool and contributes to full-session statistics, but it is not part of the main model-call usage.
177
+
178
+ ## Coding-agent messages
179
+
180
+ The CLI package extends `AgentMessage` with four roles.
181
+
182
+ ### BashExecutionMessage
183
+
184
+ Created by direct shell commands, including the RPC [`bash`](rpc-commands.md#bash) command. It is not an LLM tool result.
185
+
186
+ ```typescript
187
+ interface BashExecutionMessage {
188
+ role: "bashExecution";
189
+ command: string;
190
+ output: string;
191
+ exitCode: number | undefined;
192
+ cancelled: boolean;
193
+ truncated: boolean;
194
+ fullOutputPath?: string;
195
+ excludeFromContext?: boolean;
196
+ timestamp: number;
197
+ }
198
+ ```
199
+
200
+ Unless `excludeFromContext` is true, KnightCode converts this message to user-role text before the next model request.
201
+
202
+ ### CustomMessage
203
+
204
+ Created when an extension sends a context message.
205
+
206
+ ```typescript
207
+ interface CustomMessage<T = unknown> {
208
+ role: "custom";
209
+ customType: string;
210
+ content: string | (TextContent | ImageContent)[];
211
+ display: boolean;
212
+ details?: T;
213
+ timestamp: number;
214
+ }
215
+ ```
216
+
217
+ KnightCode converts its content to a user message for model requests. `display` controls terminal rendering; `details` is not sent to the model.
218
+
219
+ ### BranchSummaryMessage
220
+
221
+ ```typescript
222
+ interface BranchSummaryMessage {
223
+ role: "branchSummary";
224
+ summary: string;
225
+ fromId: string | null;
226
+ timestamp: number;
227
+ }
228
+ ```
229
+
230
+ KnightCode creates this context message from a persisted `branch_summary` entry.
231
+
232
+ ### CompactionSummaryMessage
233
+
234
+ ```typescript
235
+ interface CompactionSummaryMessage {
236
+ role: "compactionSummary";
237
+ summary: string;
238
+ tokensBefore: number;
239
+ timestamp: number;
240
+ }
241
+ ```
242
+
243
+ KnightCode creates this context message from a persisted `compaction` entry.
244
+
245
+ ## AgentMessage union
246
+
247
+ In the coding agent, the union is equivalent to:
248
+
249
+ ```typescript
250
+ type AgentMessage =
251
+ | SystemMessage
252
+ | UserMessage
253
+ | AssistantMessage
254
+ | ToolResultMessage
255
+ | BashExecutionMessage
256
+ | CustomMessage
257
+ | BranchSummaryMessage
258
+ | CompactionSummaryMessage;
259
+ ```
260
+
261
+ At the lower-level agent package, `AgentMessage` is `Message | CustomAgentMessages[keyof CustomAgentMessages]`. Applications can add roles through TypeScript declaration merging, so consumers should tolerate unknown custom roles when they accept messages from an augmented host.