@knightcodeai/cli-darwin-x64 0.6.1 → 0.6.2
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/bin/CHANGELOG.md +56 -0
- package/bin/docs/compaction.md +27 -1
- package/bin/docs/custom-provider.md +1 -0
- package/bin/docs/docs.json +4 -0
- package/bin/docs/extensions.md +7 -1
- package/bin/docs/index.md +1 -1
- package/bin/docs/keybindings.md +2 -2
- package/bin/docs/models.md +3 -2
- package/bin/docs/packages.md +1 -1
- package/bin/docs/quickstart.md +1 -1
- package/bin/docs/sdk.md +2 -0
- package/bin/docs/session-format.md +47 -35
- package/bin/docs/sessions.md +2 -0
- package/bin/docs/settings.md +38 -2
- package/bin/docs/terminal-setup.md +8 -0
- package/bin/docs/tui.md +1 -1
- package/bin/docs/usage.md +3 -3
- package/bin/knightcode +0 -0
- package/bin/package.json +15 -14
- package/package.json +1 -1
package/bin/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# @knightcodeai/cli
|
|
2
2
|
|
|
3
|
+
## 0.6.2
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Added the Environment Variables reference to the documentation navigation, which previously only reached that page through inline links.
|
|
8
|
+
|
|
9
|
+
- Added `ctx.modelRegistry.stream()` and `streamSimple()` so extensions can make model calls through configured providers with resolved authentication, including providers registered by extensions.
|
|
10
|
+
|
|
11
|
+
- Added Ctrl+D as a reliable alternative to Ctrl+S for saving the default model and thinking level. Many terminals (including Windows Terminal) swallow Ctrl+S as XON/XOFF flow control, so the keystroke never reached the app and the default was never saved. Ctrl+S still works where the terminal delivers it.
|
|
12
|
+
|
|
13
|
+
- Added `compaction.modelOverrides`, per-model `reserveTokens` and `keepRecentTokens` budgets keyed by exact `"provider/modelId"`, so a million-token model can hold a large response reserve without inflating it for every other model. Each field falls back independently to the ordinary setting and then the built-in default, and the resolved values drive manual compaction, threshold checks, overflow recovery, and the `session_before_compact` payload.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Changed the DeepSeek catalog to advertise `deepseek-flash` for DeepSeek V4.1 Flash, which accepts images and reasoning levels, in place of the retired `deepseek-v4-flash` and `deepseek-v4-flash-vision-exp` aliases, and refreshed DeepSeek input, output, and cache-read pricing.
|
|
18
|
+
|
|
19
|
+
- Changed OpenRouter requests to send the `x-session-id` affinity header by default on both Chat Completions and Anthropic-compatible models, so cached prompts keep hitting the same upstream replica; setting `sendSessionAffinityHeaders: false` or disabling prompt caching still opts out.
|
|
20
|
+
|
|
21
|
+
- Changed the compaction, branch summarization, and retry spinners to render in the editor border alongside the working indicator; custom editors opt in for all four with the same `embedWorkingStatus` flag.
|
|
22
|
+
|
|
23
|
+
- Changed the runtime dependencies to current releases, including the Anthropic, Bedrock and Google GenAI SDKs, the proxy agents, TypeBox, undici, chalk, marked, ignore, minimatch, semver, esbuild and grok-mermaid. Google's new `TOO_MANY_TOOL_CALLS` finish reason now maps to an error stop reason.
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- Removed GPT-5.4 and GPT-5.4 mini from the OpenAI Codex catalog after ChatGPT accounts lost access to them; selecting either now fails at model resolution instead of at the first request.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Fixed agent-level retry backoff doubling without a ceiling, which left the agent asleep for hours after a long provider outage. Assistant and summarization retries now cap each delay at the new `retry.maxAgentDelayMs` setting, defaulting to 60 seconds.
|
|
32
|
+
|
|
33
|
+
- Fixed OpenAI Codex requests omitting the reasoning effort when thinking is off, so models that need an explicit Off level fell back to the provider default; the model's mapped Off effort is now sent, and models that map Off to `null` still send nothing.
|
|
34
|
+
|
|
35
|
+
- Fixed GitHub Copilot GPT models other than GPT-5 being routed to the completions endpoint, which Copilot does not serve them from.
|
|
36
|
+
|
|
37
|
+
- Fixed the event stream draining its buffered events with `Array.shift()`, which made delivery quadratic on long streams; both the event queue and the waiting-consumer queue now use an amortized O(1) FIFO.
|
|
38
|
+
|
|
39
|
+
- Fixed Fireworks Messages models losing their thinking blocks on replay and collapsing native reasoning effort to a budget-based fallback; the catalog now takes effort levels from provider metadata, allows unsigned thinking, and stops advertising GLM 5.2 and Kimi K3 aliases that map onto the same level.
|
|
40
|
+
|
|
41
|
+
- Fixed Mistral-hosted GLM-5.2 reasoning requests sending `prompt_mode`, which that model ignores, so thinking never turned on; they now send `reasoning_effort`.
|
|
42
|
+
|
|
43
|
+
- Fixed Mistral Medium reasoning requests sending the unsupported `prompt_mode` instead of `reasoning_effort` for reasoning-capable `mistral-medium-*` model IDs such as `mistral-medium-latest`.
|
|
44
|
+
|
|
45
|
+
- Fixed OpenCode and OpenCode Go requests dropping the `x-opencode-session` routing header; every API adapter now maps `sessionId` onto it while leaving an explicit caller override alone.
|
|
46
|
+
|
|
47
|
+
- Fixed extension tools registered without an object parameter schema being accepted, which broke provider request serialization later; registration now rejects them with an error naming the tool and the extension.
|
|
48
|
+
|
|
49
|
+
- Fixed steering and follow-up messages bypassing extension `input` handlers, so extensions could neither transform nor intercept a message queued while the agent was already streaming; both paths now run the handlers and carry their real input source.
|
|
50
|
+
|
|
51
|
+
- Fixed session tree navigation starting while a compaction or another navigation was still running; it now rejects instead of moving the active leaf.
|
|
52
|
+
|
|
53
|
+
- Fixed a rejected `/tree` navigation replacing the running operation's escape handler and status spinner; the compaction or summarization it collided with now keeps its own UI.
|
|
54
|
+
|
|
55
|
+
- Fixed the compiled Windows executable inheriting Bun's own PE resources, so `knightcode.exe` shipped with no icon and a `FileDescription` of "Bun" — the string Windows shows as the process name in Task Manager and the taskbar. The win32 build now embeds KnightCode's own title, publisher, copyright, version, and icon.
|
|
56
|
+
|
|
57
|
+
- Fixed fullscreen mode reserving a blank row for a custom footer that renders nothing.
|
|
58
|
+
|
|
3
59
|
## 0.6.1
|
|
4
60
|
|
|
5
61
|
### Added
|
package/bin/docs/compaction.md
CHANGED
|
@@ -288,7 +288,7 @@ knightcode.on("session_before_compact", async (event, ctx) => {
|
|
|
288
288
|
// preparation.fileOps - extracted file operations
|
|
289
289
|
// preparation.tokensBefore - context tokens before compaction
|
|
290
290
|
// preparation.firstKeptEntryId - where kept messages start
|
|
291
|
-
// preparation.settings -
|
|
291
|
+
// preparation.settings - effective settings after applying model overrides
|
|
292
292
|
|
|
293
293
|
// branchEntries - all entries on current branch (for custom state)
|
|
294
294
|
// reason - "manual" (/compact), "threshold", or "overflow"
|
|
@@ -416,3 +416,29 @@ Configure compaction in `~/.knightcode/agent/settings.json` or `<project-dir>/.k
|
|
|
416
416
|
| `keepRecentTokens` | `20000` | Recent tokens to keep (not summarized) |
|
|
417
417
|
|
|
418
418
|
Disable auto-compaction with `"enabled": false`. You can still compact manually with `/compact`.
|
|
419
|
+
|
|
420
|
+
### Per-model overrides
|
|
421
|
+
|
|
422
|
+
Use `compaction.modelOverrides` to tune token budgets for different models:
|
|
423
|
+
|
|
424
|
+
```json
|
|
425
|
+
{
|
|
426
|
+
"compaction": {
|
|
427
|
+
"reserveTokens": 16384,
|
|
428
|
+
"keepRecentTokens": 20000,
|
|
429
|
+
"modelOverrides": {
|
|
430
|
+
"some-provider/big-model": {
|
|
431
|
+
"reserveTokens": 400000
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
For a model with a 1M context window, this override triggers compaction above 600K tokens and keeps the ordinary 20000 recent tokens. Other models retain the ordinary 16384-token reserve. `reserveTokens` also influences summarization output limits, capped by the model's maximum output tokens; it is not solely a trigger threshold.
|
|
439
|
+
|
|
440
|
+
Keys are exact, case-sensitive `provider/modelId` values, including any slashes within the model ID. Each `reserveTokens` and `keepRecentTokens` value falls back independently from the model override to the ordinary setting to the built-in default. Values must be non-negative safe integers. Invalid values in the matching model override produce an error when read; only omitted fields fall back to the ordinary setting. Model override entries must be objects. Invalid ordinary token settings produce an error when read, even if the active model has a valid override. Only omitted ordinary values use built-in defaults. `enabled` remains global, not model-specific.
|
|
441
|
+
|
|
442
|
+
These resolved values are used for manual compaction, all automatic threshold checks, overflow recovery, and extension-visible `preparation.settings`. Model switches affect subsequent checks and compactions without changing ordinary settings. Compaction already in progress uses the model and settings captured for that operation. Branch summarization settings are unaffected.
|
|
443
|
+
|
|
444
|
+
Overrides work in both global and project settings. The files merge recursively before lookup, so a global model-specific value beats a project-wide fallback; a project must override that model entry to change it. See [settings.md](settings.md#per-model-compaction-overrides) for details.
|
|
@@ -764,6 +764,7 @@ interface ProviderModelConfig {
|
|
|
764
764
|
supportsEagerToolInputStreaming?: boolean;
|
|
765
765
|
supportsLongCacheRetention?: boolean;
|
|
766
766
|
sendSessionAffinityHeaders?: boolean;
|
|
767
|
+
sessionAffinityFormat?: "openrouter";
|
|
767
768
|
supportsCacheControlOnTools?: boolean;
|
|
768
769
|
forceAdaptiveThinking?: boolean;
|
|
769
770
|
allowEmptySignature?: boolean;
|
package/bin/docs/docs.json
CHANGED
package/bin/docs/extensions.md
CHANGED
|
@@ -1016,6 +1016,12 @@ Access to models, providers, and resolved authentication. `ctx.modelRegistry.get
|
|
|
1016
1016
|
|
|
1017
1017
|
`ctx.scopedModels` is the read-only list of models scoped to the current session — the same set the `/scoped-models` command shows. It is resolved at session start from the `--models` CLI flag and the `enabledModels` setting (matched against the available catalogue with minimatch on `provider/modelId` or a bare `modelId`). It is empty when no scoping is configured, meaning every available model is usable. Each entry is `{ model, thinkingLevel? }`, where `thinkingLevel` is set only when a pattern pinned it (e.g. `anthropic/*:high`). Use it to populate a model picker that mirrors the built-in one instead of enumerating the whole catalogue via `ctx.modelRegistry.getAvailable()`.
|
|
1018
1018
|
|
|
1019
|
+
#### Streaming model calls
|
|
1020
|
+
|
|
1021
|
+
Use `ctx.modelRegistry.streamSimple(model, context, options)` for provider-neutral options such as `reasoning`, or `stream()` for API-specific options. Both use configured providers and resolve authentication, including for providers registered with `knightcode.registerProvider()`. Use these instead of `@knightcode/ai/compat` streaming functions, which cannot see extension provider registrations.
|
|
1022
|
+
|
|
1023
|
+
Both return an `AssistantMessageEventStream`. Iterate it for response events and await `.result()` for the final message. Setup failures produce error events and error results.
|
|
1024
|
+
|
|
1019
1025
|
### ctx.signal
|
|
1020
1026
|
|
|
1021
1027
|
The current agent abort signal, or `undefined` when no agent turn is active.
|
|
@@ -1197,7 +1203,7 @@ Options:
|
|
|
1197
1203
|
|
|
1198
1204
|
### ctx.navigateTree(targetId, options?)
|
|
1199
1205
|
|
|
1200
|
-
Navigate to a different point in the session tree:
|
|
1206
|
+
Navigate to a different point in the session tree. Rejects while an agent response, manual or automatic compaction, or another tree navigation is active, even with `summarize: false`. These conflicts leave the active branch unchanged and reject the promise rather than returning `{ cancelled: true }`. Wait for the active operation to finish (for example, with `await ctx.waitForIdle()` in a command handler) and retry:
|
|
1201
1207
|
|
|
1202
1208
|
```typescript
|
|
1203
1209
|
const result = await ctx.navigateTree("entry-id-456", {
|
package/bin/docs/index.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install -g --ignore-scripts @knightcodeai/cli
|
|
|
15
15
|
On Linux or macOS, you can also use the installer:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
curl -fsSL https://knightcode.
|
|
18
|
+
curl -fsSL https://knightcode.dev/install.sh | sh
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
To uninstall knightcode itself, use npm for curl and npm installs:
|
package/bin/docs/keybindings.md
CHANGED
|
@@ -151,9 +151,9 @@ This routing remains configurable through the ordinary action bindings. For exam
|
|
|
151
151
|
| `app.model.select` | `ctrl+l` | Open model selector |
|
|
152
152
|
| `app.model.cycleForward` | `ctrl+p` | Cycle to next model |
|
|
153
153
|
| `app.model.cycleBackward` | `shift+ctrl+p` (`alt+p` on Windows and WSL) | Cycle to previous model |
|
|
154
|
-
| `app.models.save` | `ctrl+s` | Save the selected default model or scoped model configuration to settings |
|
|
154
|
+
| `app.models.save` | `ctrl+s`, `ctrl+d` | Save the selected default model or scoped model configuration to settings (`ctrl+d` because many terminals swallow `ctrl+s`) |
|
|
155
155
|
| `app.thinking.cycle` | `shift+tab` | Cycle thinking level |
|
|
156
|
-
| `app.thinking.save` | `ctrl+s` | Save current thinking level to settings |
|
|
156
|
+
| `app.thinking.save` | `ctrl+s`, `ctrl+d` | Save current thinking level to settings (`ctrl+d` because many terminals swallow `ctrl+s`) |
|
|
157
157
|
| `app.thinking.toggle` | `ctrl+t` | Collapse or expand thinking blocks |
|
|
158
158
|
|
|
159
159
|
### Display and Message Queue
|
package/bin/docs/models.md
CHANGED
|
@@ -429,7 +429,8 @@ Built-in Anthropic models enable `supportsStrictTools` in their model metadata.
|
|
|
429
429
|
|-------|-------------|
|
|
430
430
|
| `supportsEagerToolInputStreaming` | Whether the provider accepts per-tool `eager_input_streaming`. Default: `true`. Set to `false` to omit that field and use the legacy fine-grained tool streaming beta header on tool-enabled requests. |
|
|
431
431
|
| `supportsLongCacheRetention` | Whether the provider accepts Anthropic long cache retention (`cache_control.ttl: "1h"`) when cache retention is `long`. Default: `true`. |
|
|
432
|
-
| `sendSessionAffinityHeaders` | Whether to send
|
|
432
|
+
| `sendSessionAffinityHeaders` | Whether to send a session-affinity header from the session id when caching is enabled. Default: `true` for OpenRouter endpoints, auto-detected for other known providers. |
|
|
433
|
+
| `sessionAffinityFormat` | Session-affinity header name: `openrouter` sends `x-session-id`. When unset, `x-session-affinity` is sent. Default: `openrouter` for OpenRouter endpoints. |
|
|
433
434
|
| `supportsCacheControlOnTools` | Whether the provider accepts Anthropic-style `cache_control` markers on tool definitions. Default: `true`. |
|
|
434
435
|
| `forceAdaptiveThinking` | Whether to send adaptive thinking (`thinking.type: "adaptive"` plus `output_config.effort`) for this model. Built-in adaptive models set this automatically. Default: `false`. |
|
|
435
436
|
| `supportsMidConvoEffort` | Whether the exact Claude model transport supports per-turn effort system messages and thinking binding controls. KnightCode persists native effort levels and always sends `drop_block` when enabled. Default: `false`. |
|
|
@@ -477,7 +478,7 @@ For providers with partial OpenAI compatibility, use the `compat` field.
|
|
|
477
478
|
| `thinkingTokenBudgetField` | Top-level request field used to cap reasoning tokens from `thinkingBudgets`, clamped so at least 1024 tokens remain for the answer. `"thinking_token_budget"` (vLLM), `"thinking_budget"` (Qwen/DashScope/SGLang), `"thinking_budget_tokens"` (llama.cpp). Off by default; not set on the generated catalog. |
|
|
478
479
|
| `supportsThinkingTokenBudget` | Alias for `thinkingTokenBudgetField: "thinking_token_budget"` (vLLM). Prefer `thinkingTokenBudgetField`. Default: `false`. |
|
|
479
480
|
| `cacheControlFormat` | Use Anthropic-style `cache_control` markers on the system prompt, last tool definition, and last user, assistant, or tool-result text content. Currently only `anthropic` is supported. |
|
|
480
|
-
| `sendSessionAffinityHeaders` | For `openai-completions`, send session-affinity headers from the session id when caching is enabled. Default: `false
|
|
481
|
+
| `sendSessionAffinityHeaders` | For `openai-completions`, send session-affinity headers from the session id when caching is enabled. Default: `true` for OpenRouter endpoints, `false` otherwise. |
|
|
481
482
|
| `sessionAffinityFormat` | For `openai-completions` and `openai-responses`, the session-affinity header format: `openai` sends `session_id`/`x-client-request-id` (completions also `x-session-affinity`), `openai-nosession` omits the underscore-containing `session_id` header, `openrouter` sends `x-session-id`. Does not affect the `prompt_cache_key` body param. Default: auto-detected. |
|
|
482
483
|
| `supportsStrictMode` | Whether the provider accepts strict JSON-schema function tool definitions. Defaults depend on the API; built-in OpenAI models carry explicit capability metadata. |
|
|
483
484
|
| `supportsOpenAIGrammarTools` | Whether OpenAI-compatible APIs emit custom Lark/regex grammar tools. When `false`, grammar-constrained tools fall back to normal function tools. Default: `false`; the built-in model catalog enables it for GPT-5+ models on OpenAI, OpenAI Codex, Azure OpenAI, GitHub Copilot, opencode, and Cloudflare AI Gateway. |
|
package/bin/docs/packages.md
CHANGED
|
@@ -134,7 +134,7 @@ Paths are relative to the package root. Arrays support glob patterns and `!exclu
|
|
|
134
134
|
|
|
135
135
|
### Gallery Metadata
|
|
136
136
|
|
|
137
|
-
The [package gallery](https://knightcode.
|
|
137
|
+
The [package gallery](https://knightcode.dev/packages) displays packages tagged with `knightcode-package`. Add `video` or `image` fields to show a preview:
|
|
138
138
|
|
|
139
139
|
```json
|
|
140
140
|
{
|
package/bin/docs/quickstart.md
CHANGED
|
@@ -129,7 +129,7 @@ The command output is sent to the model. Use `!!command` to run a command withou
|
|
|
129
129
|
|
|
130
130
|
### Switch models
|
|
131
131
|
|
|
132
|
-
Use `/model` or Ctrl+L to choose a model for the current session. Press Ctrl+S in the model picker to save the highlighted model as the startup default. Use `/thinking` to choose a thinking level for the current session, or Ctrl+S in that picker to save the startup default thinking level. Use Shift+Tab to cycle thinking level. Use Ctrl+P / Shift+Ctrl+P to cycle through scoped models.
|
|
132
|
+
Use `/model` or Ctrl+L to choose a model for the current session. Press Ctrl+S (or Ctrl+D, if your terminal swallows Ctrl+S) in the model picker to save the highlighted model as the startup default. Use `/thinking` to choose a thinking level for the current session, or Ctrl+S / Ctrl+D in that picker to save the startup default thinking level. Use Shift+Tab to cycle thinking level. Use Ctrl+P / Shift+Ctrl+P to cycle through scoped models.
|
|
133
133
|
|
|
134
134
|
### Continue later
|
|
135
135
|
|
package/bin/docs/sdk.md
CHANGED
|
@@ -111,6 +111,8 @@ interface AgentSession {
|
|
|
111
111
|
}
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
+
`session.navigateTree()` rejects while an agent response, manual or automatic compaction, or another tree navigation is active, even with `summarize: false`. It does not queue navigation or return `{ cancelled: true }` for these conflicts. Wait for the active operation to finish (for example, with `await session.waitForIdle()`) and retry. Rejection leaves the active branch unchanged.
|
|
115
|
+
|
|
114
116
|
Session replacement APIs such as new-session, resume, fork, and import live on `AgentSessionRuntime`, not on `AgentSession`.
|
|
115
117
|
|
|
116
118
|
### createAgentSessionRuntime() and AgentSessionRuntime
|
|
@@ -5,10 +5,10 @@ Sessions are stored as JSONL (JSON Lines) files. Each line is a JSON object with
|
|
|
5
5
|
## File Location
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
~/.knightcode/agent/sessions/--<path>--/<timestamp>_<
|
|
8
|
+
~/.knightcode/agent/sessions/--<path>--/<timestamp>_<session-id>.jsonl
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
By default, `<session-id>` is a UUID. Callers can supply a custom ID through the SDK or `--session-id`. For `<path>`, KnightCode removes the leading path separator and replaces `/`, `\\`, and `:` with `-`.
|
|
12
12
|
|
|
13
13
|
## Deleting Sessions
|
|
14
14
|
|
|
@@ -29,8 +29,8 @@ Existing sessions are automatically migrated to the current version (v3) when lo
|
|
|
29
29
|
## Source Files
|
|
30
30
|
|
|
31
31
|
Source on GitHub ([knightcode](https://github.com/KnightCodeAI/knightcode)):
|
|
32
|
-
- [`packages/
|
|
33
|
-
- [`packages/
|
|
32
|
+
- [`packages/cli/src/core/session-manager.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/core/session-manager.ts) - Session entry types and SessionManager
|
|
33
|
+
- [`packages/cli/src/core/messages.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
|
|
34
34
|
- [`packages/ai/src/types.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
|
|
35
35
|
- [`packages/agent/src/types.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/agent/src/types.ts) - AgentMessage union type
|
|
36
36
|
|
|
@@ -48,6 +48,7 @@ Messages contain arrays of typed content blocks:
|
|
|
48
48
|
interface TextContent {
|
|
49
49
|
type: "text";
|
|
50
50
|
text: string;
|
|
51
|
+
textSignature?: string;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
interface ImageContent {
|
|
@@ -59,6 +60,8 @@ interface ImageContent {
|
|
|
59
60
|
interface ThinkingContent {
|
|
60
61
|
type: "thinking";
|
|
61
62
|
thinking: string;
|
|
63
|
+
thinkingSignature?: string;
|
|
64
|
+
redacted?: boolean;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
interface ToolCall {
|
|
@@ -66,6 +69,8 @@ interface ToolCall {
|
|
|
66
69
|
id: string;
|
|
67
70
|
name: string;
|
|
68
71
|
arguments: Record<string, any>;
|
|
72
|
+
thoughtSignature?: string;
|
|
73
|
+
namespace?: string;
|
|
69
74
|
}
|
|
70
75
|
```
|
|
71
76
|
|
|
@@ -84,9 +89,16 @@ interface AssistantMessage {
|
|
|
84
89
|
api: string;
|
|
85
90
|
provider: string;
|
|
86
91
|
model: string;
|
|
92
|
+
responseModel?: string;
|
|
93
|
+
responseId?: string;
|
|
94
|
+
providerThinkingLevel?: string;
|
|
95
|
+
diagnostics?: AssistantMessageDiagnostic[];
|
|
87
96
|
usage: Usage;
|
|
88
|
-
stopReason: "stop" | "length" | "toolUse" | "error" | "aborted";
|
|
97
|
+
stopReason: "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
|
|
98
|
+
deferred?: DeferredHandle;
|
|
89
99
|
errorMessage?: string;
|
|
100
|
+
rawStopReason?: string;
|
|
101
|
+
endTurn?: boolean;
|
|
90
102
|
timestamp: number;
|
|
91
103
|
}
|
|
92
104
|
|
|
@@ -97,6 +109,7 @@ interface ToolResultMessage {
|
|
|
97
109
|
content: (TextContent | ImageContent)[];
|
|
98
110
|
details?: any; // Tool-specific metadata
|
|
99
111
|
usage?: Usage; // Nested LLM work performed by the tool
|
|
112
|
+
addedToolNames?: string[];
|
|
100
113
|
isError: boolean;
|
|
101
114
|
timestamp: number;
|
|
102
115
|
}
|
|
@@ -106,6 +119,8 @@ interface Usage {
|
|
|
106
119
|
output: number;
|
|
107
120
|
cacheRead: number;
|
|
108
121
|
cacheWrite: number;
|
|
122
|
+
cacheWrite1h?: number;
|
|
123
|
+
reasoning?: number;
|
|
109
124
|
totalTokens: number;
|
|
110
125
|
cost: {
|
|
111
126
|
input: number;
|
|
@@ -117,7 +132,7 @@ interface Usage {
|
|
|
117
132
|
}
|
|
118
133
|
```
|
|
119
134
|
|
|
120
|
-
|
|
135
|
+
`"pending"` is reserved for partial messages in streaming events. Terminal events replace it with a completion reason before knightcode persists the assistant message, so `"pending"` should never appear in session JSONL. `"deferred"` is a terminal reason for a provider response that will complete later; its `deferred` handle contains the provider data needed to retrieve that response.
|
|
121
136
|
|
|
122
137
|
### Extended Message Types (from @knightcodeai/cli)
|
|
123
138
|
|
|
@@ -146,7 +161,7 @@ interface CustomMessage {
|
|
|
146
161
|
interface BranchSummaryMessage {
|
|
147
162
|
role: "branchSummary";
|
|
148
163
|
summary: string;
|
|
149
|
-
fromId: string;
|
|
164
|
+
fromId: string | null; // Previous leaf whose abandoned path was summarized
|
|
150
165
|
timestamp: number;
|
|
151
166
|
}
|
|
152
167
|
|
|
@@ -178,8 +193,8 @@ All entries (except `SessionHeader`) extend `SessionEntryBase`:
|
|
|
178
193
|
```typescript
|
|
179
194
|
interface SessionEntryBase {
|
|
180
195
|
type: string;
|
|
181
|
-
id: string; // 8-char hex ID
|
|
182
|
-
parentId: string | null; // Parent entry ID (null for
|
|
196
|
+
id: string; // Usually an 8-char hex ID; may fall back to a full UUID
|
|
197
|
+
parentId: string | null; // Parent entry ID (null for a root entry)
|
|
183
198
|
timestamp: string; // ISO timestamp
|
|
184
199
|
}
|
|
185
200
|
```
|
|
@@ -205,9 +220,9 @@ For sessions with a parent (created via `/fork`, `/clone`, or `newSession({ pare
|
|
|
205
220
|
A message in the conversation. The `message` field contains an `AgentMessage`.
|
|
206
221
|
|
|
207
222
|
```json
|
|
208
|
-
{"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello"}}
|
|
209
|
-
{"type":"message","id":"b2c3d4e5","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:00:02.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}],"provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop"}}
|
|
210
|
-
{"type":"message","id":"c3d4e5f6","parentId":"b2c3d4e5","timestamp":"2024-12-03T14:00:03.000Z","message":{"role":"toolResult","toolCallId":"call_123","toolName":"bash","content":[{"type":"text","text":"output"}],"isError":false}}
|
|
223
|
+
{"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello","timestamp":1733234401000}}
|
|
224
|
+
{"type":"message","id":"b2c3d4e5","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:00:02.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}],"api":"anthropic-messages","provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop","timestamp":1733234402000}}
|
|
225
|
+
{"type":"message","id":"c3d4e5f6","parentId":"b2c3d4e5","timestamp":"2024-12-03T14:00:03.000Z","message":{"role":"toolResult","toolCallId":"call_123","toolName":"bash","content":[{"type":"text","text":"output"}],"isError":false,"timestamp":1733234403000}}
|
|
211
226
|
```
|
|
212
227
|
|
|
213
228
|
### ModelChangeEntry
|
|
@@ -234,18 +249,12 @@ Created when context is compacted. Stores a summary of earlier messages.
|
|
|
234
249
|
{"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","firstKeptEntryId":"c3d4e5f6","tokensBefore":50000}
|
|
235
250
|
```
|
|
236
251
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
```json
|
|
240
|
-
{"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","tokensBefore":50000,"retainedTail":[{"role":"user","content":"latest request"},{"role":"assistant","content":[{"type":"text","text":"latest reply"}],"provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop"}]}
|
|
241
|
-
```
|
|
252
|
+
`firstKeptEntryId` is required. It identifies the first entry retained from before the compaction entry. When rebuilding context, KnightCode replaces older summarized entries with the compaction summary and keeps the range beginning at this entry.
|
|
242
253
|
|
|
243
254
|
Optional fields:
|
|
244
255
|
- `usage`: LLM usage from generating the summary; included in session token and cost totals
|
|
245
|
-
- `retainedTail`: Materialized `AgentMessage[]` kept after compaction. This is optional only for backward compatibility with older sessions. Newer harness-generated compactions include it so we can rebuild context from this checkpoint without walking older entries before the compaction entry.
|
|
246
256
|
- `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
|
|
247
257
|
- `fromHook`: `true` if generated by an extension, `false`/`undefined` if knightcode-generated (legacy field name)
|
|
248
|
-
- `firstKeptEntryId`: for compatibility with old entry format.
|
|
249
258
|
|
|
250
259
|
### BranchSummaryEntry
|
|
251
260
|
|
|
@@ -255,6 +264,8 @@ Created when switching branches via `/tree` with an LLM generated summary of the
|
|
|
255
264
|
{"type":"branch_summary","id":"g7h8i9j0","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:15:00.000Z","fromId":"f6g7h8i9","summary":"Branch explored approach A..."}
|
|
256
265
|
```
|
|
257
266
|
|
|
267
|
+
`parentId` is the entry from which the new branch continues. `fromId` is the previous leaf whose abandoned path was summarized.
|
|
268
|
+
|
|
258
269
|
Optional fields:
|
|
259
270
|
- `usage`: LLM usage from generating the summary; included in session token and cost totals
|
|
260
271
|
- `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
|
|
@@ -305,11 +316,12 @@ The session name is displayed in the session selector (`/resume`) instead of the
|
|
|
305
316
|
|
|
306
317
|
## Tree Structure
|
|
307
318
|
|
|
308
|
-
Entries form
|
|
309
|
-
-
|
|
310
|
-
- Each
|
|
319
|
+
Entries normally form one tree, but navigation APIs can create multiple roots:
|
|
320
|
+
- A root entry has `parentId: null`; the first entry is initially the root
|
|
321
|
+
- Each non-root entry points to its parent via `parentId`
|
|
311
322
|
- Branching creates new children from an earlier entry
|
|
312
323
|
- The "leaf" is the current position in the tree
|
|
324
|
+
- Calling `resetLeaf()` or `branchWithSummary(null, ...)` allows a later entry to become another root
|
|
313
325
|
|
|
314
326
|
```
|
|
315
327
|
[user msg] ─── [assistant] ─── [user msg] ─── [assistant] ─┬─ [user msg] ← current leaf
|
|
@@ -322,11 +334,10 @@ Entries form a tree:
|
|
|
322
334
|
`buildContextEntries()` walks from the current leaf to the root, producing the active entry list while honoring compaction:
|
|
323
335
|
|
|
324
336
|
1. Collects all entries on the path
|
|
325
|
-
2. If
|
|
337
|
+
2. If one or more `CompactionEntry` values are on the path, uses the latest one:
|
|
326
338
|
- Includes the compaction entry first
|
|
327
|
-
-
|
|
328
|
-
-
|
|
329
|
-
- Then entries after compaction are included
|
|
339
|
+
- Includes entries from `firstKeptEntryId` up to, but not including, the compaction entry
|
|
340
|
+
- Includes entries after the compaction entry
|
|
330
341
|
3. Preserves non-message entries in the selected range so interactive mode can render them
|
|
331
342
|
|
|
332
343
|
`buildSessionContext()` builds on that entry list to produce the message list for the LLM:
|
|
@@ -334,12 +345,12 @@ Entries form a tree:
|
|
|
334
345
|
1. Extracts current model and thinking level settings from the full path
|
|
335
346
|
2. Converts selected entries to messages:
|
|
336
347
|
- `message` -> stored `AgentMessage`
|
|
337
|
-
- `compaction` -> `compactionSummary`
|
|
348
|
+
- `compaction` -> `compactionSummary`
|
|
338
349
|
- `branch_summary` -> `branchSummary`
|
|
339
350
|
- `custom_message` -> `CustomMessage`
|
|
340
351
|
- `custom` -> no context message
|
|
341
352
|
|
|
342
|
-
|
|
353
|
+
The compaction summary replaces entries before `firstKeptEntryId`. The retained entries and all entries after the compaction remain available to the LLM.
|
|
343
354
|
|
|
344
355
|
## Parsing Example
|
|
345
356
|
|
|
@@ -388,18 +399,19 @@ for (const line of lines) {
|
|
|
388
399
|
Key methods for working with sessions programmatically.
|
|
389
400
|
|
|
390
401
|
### Static Creation Methods
|
|
391
|
-
- `SessionManager.create(cwd, sessionDir?)` - New session
|
|
392
|
-
- `SessionManager.open(path, sessionDir?)` - Open existing session file
|
|
402
|
+
- `SessionManager.create(cwd, sessionDir?, options?)` - New session; `options` can set `id` and `parentSession`
|
|
403
|
+
- `SessionManager.open(path, sessionDir?, cwdOverride?)` - Open existing session file
|
|
393
404
|
- `SessionManager.continueRecent(cwd, sessionDir?)` - Continue most recent or create new
|
|
394
|
-
- `SessionManager.inMemory(cwd?)` - No file persistence
|
|
395
|
-
- `SessionManager.forkFrom(sourcePath, targetCwd, sessionDir?)` - Fork session from another project
|
|
405
|
+
- `SessionManager.inMemory(cwd?, options?, entries?)` - No file persistence, optionally initialized from entries
|
|
406
|
+
- `SessionManager.forkFrom(sourcePath, targetCwd, sessionDir?, options?)` - Fork session from another project
|
|
396
407
|
|
|
397
408
|
### Static Listing Methods
|
|
398
409
|
- `SessionManager.list(cwd, sessionDir?, onProgress?)` - List sessions for a directory
|
|
399
410
|
- `SessionManager.listAll(onProgress?)` - List all sessions across all projects
|
|
411
|
+
- `SessionManager.listAll(sessionDir?, onProgress?)` - List sessions from a custom session root
|
|
400
412
|
|
|
401
413
|
### Instance Methods - Session Management
|
|
402
|
-
- `newSession(options?)` - Start a new session (options: `{ parentSession?: string }`)
|
|
414
|
+
- `newSession(options?)` - Start a new session (options: `{ id?: string, parentSession?: string }`)
|
|
403
415
|
- `setSessionFile(path)` - Switch to a different session file
|
|
404
416
|
- `createBranchedSession(leafId)` - Extract branch to new session file
|
|
405
417
|
|
|
@@ -407,7 +419,7 @@ Key methods for working with sessions programmatically.
|
|
|
407
419
|
- `appendMessage(message)` - Add message
|
|
408
420
|
- `appendThinkingLevelChange(level)` - Record thinking change
|
|
409
421
|
- `appendModelChange(provider, modelId)` - Record model change
|
|
410
|
-
- `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?, fromHook?)` - Add compaction
|
|
422
|
+
- `appendCompaction(summary, firstKeptEntryId, tokensBefore, details?, fromHook?, usage?)` - Add compaction
|
|
411
423
|
- `appendCustomEntry(customType, data?)` - Extension state (not in context)
|
|
412
424
|
- `appendSessionInfo(name)` - Set session display name
|
|
413
425
|
- `appendCustomMessageEntry(customType, content, display, details?)` - Extension message (in context)
|
|
@@ -423,7 +435,7 @@ Key methods for working with sessions programmatically.
|
|
|
423
435
|
- `getLabel(id)` - Get label for entry
|
|
424
436
|
- `branch(entryId)` - Move leaf to earlier entry
|
|
425
437
|
- `resetLeaf()` - Reset leaf to null (before any entries)
|
|
426
|
-
- `branchWithSummary(entryId, summary, details?, fromHook?)` - Branch with context summary
|
|
438
|
+
- `branchWithSummary(entryId, summary, details?, fromHook?, usage?)` - Branch with context summary; `entryId` may be `null` to branch from the root
|
|
427
439
|
|
|
428
440
|
### Instance Methods - Context & Info
|
|
429
441
|
- `buildContextEntries()` - Get active branch entries with compaction applied
|
package/bin/docs/sessions.md
CHANGED
|
@@ -70,6 +70,8 @@ Named sessions are easier to find in `/resume` and `knightcode -r`.
|
|
|
70
70
|
|
|
71
71
|
Sessions are stored as trees. Every entry has an `id` and `parentId`, and the current position is the active leaf. `/tree` lets you jump to any previous point and continue from there without creating a new file.
|
|
72
72
|
|
|
73
|
+
Selecting a point while the model is responding cancels that response. Navigation cannot proceed while compaction or another tree navigation is still running; wait for it to finish and retry.
|
|
74
|
+
|
|
73
75
|
<p align="center"><img src="images/tree-view.png" alt="Tree View" width="600"></p>
|
|
74
76
|
|
|
75
77
|
Example shape:
|
package/bin/docs/settings.md
CHANGED
|
@@ -66,7 +66,7 @@ Use `/trust` in interactive mode to save a project trust decision for future ses
|
|
|
66
66
|
| `outputPad` | number | `1` | Horizontal padding for user messages, assistant messages, and thinking (0 or 1) |
|
|
67
67
|
| `autocompleteMaxVisible` | number | `5` | Max visible items in autocomplete dropdown (3-20) |
|
|
68
68
|
| `showHardwareCursor` | boolean | `false` | Show the terminal cursor while TUI positions it for IME support |
|
|
69
|
-
| `tuiMode` | string | `"regular"` | Interactive TUI mode: `"regular"` or experimental `"fullscreen"`. Changes from `/settings` apply immediately; `--tui-mode` overrides this setting at startup |
|
|
69
|
+
| `tuiMode` | string | `"regular"` | Interactive TUI mode: `"regular"` or experimental `"fullscreen"`. Fullscreen captures the mouse and owns text selection, so dragging copies to the clipboard; regular leaves selection and copying to the terminal emulator (see [Text selection and copy](terminal-setup.md#text-selection-and-copy)). Changes from `/settings` apply immediately; `--tui-mode` overrides this setting at startup |
|
|
70
70
|
| `fullscreenExitOutput` | string | `"transcript"` | Fullscreen exit output: `"transcript"` prints the final transcript and resume hint, while `"resume-hint"` restores the previous screen and prints only the resume hint. Has no effect in regular TUI mode |
|
|
71
71
|
| `fullscreenScrollbar` | string | `"auto"` | Fullscreen transcript scrollbar: `"auto"` shows it temporarily while scrolling or while the pointer is over its rightmost-column track, `"always"` reserves that column and keeps it visible, and `"hidden"` hides it. Has no effect in regular TUI mode |
|
|
72
72
|
| `fullscreenCopyOnSelect` | boolean | `true` | Automatically copy selected text in fullscreen mode. When disabled, selections stay highlighted and `Ctrl+X` copies the active selection. Has no effect in regular TUI mode |
|
|
@@ -81,7 +81,7 @@ For VS Code, include `--wait` so knightcode resumes after the editor exits:
|
|
|
81
81
|
|
|
82
82
|
### Telemetry and update checks
|
|
83
83
|
|
|
84
|
-
`enableInstallTelemetry` controls the anonymous install/update ping to `https://knightcode.
|
|
84
|
+
`enableInstallTelemetry` controls the anonymous install/update ping to `https://knightcode.dev/api/report-install` and KnightCode attribution headers for OpenRouter, NVIDIA NIM, and Cloudflare provider requests. Opting out disables both. It does not disable update checks; KnightCode can still fetch `https://knightcode.dev/api/latest-version` to look for the latest version.
|
|
85
85
|
|
|
86
86
|
Set `KNIGHTCODE_SKIP_VERSION_CHECK=1` to disable the KnightCode version update check. Use `--offline` or `KNIGHTCODE_OFFLINE=1` to disable all startup network operations described here, including update checks, package update checks, and install/update telemetry.
|
|
87
87
|
|
|
@@ -118,6 +118,7 @@ Set `KNIGHTCODE_SKIP_VERSION_CHECK=1` to disable the KnightCode version update c
|
|
|
118
118
|
| `compaction.enabled` | boolean | `true` | Enable auto-compaction |
|
|
119
119
|
| `compaction.reserveTokens` | number | `16384` | Tokens reserved for LLM response |
|
|
120
120
|
| `compaction.keepRecentTokens` | number | `20000` | Recent tokens to keep (not summarized) |
|
|
121
|
+
| `compaction.modelOverrides` | object | - | Per-model `reserveTokens` and `keepRecentTokens` overrides keyed by exact `"provider/modelId"` |
|
|
121
122
|
|
|
122
123
|
```json
|
|
123
124
|
{
|
|
@@ -129,6 +130,37 @@ Set `KNIGHTCODE_SKIP_VERSION_CHECK=1` to disable the KnightCode version update c
|
|
|
129
130
|
}
|
|
130
131
|
```
|
|
131
132
|
|
|
133
|
+
#### Per-model compaction overrides
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"compaction": {
|
|
138
|
+
"enabled": true,
|
|
139
|
+
"reserveTokens": 16384,
|
|
140
|
+
"keepRecentTokens": 20000,
|
|
141
|
+
"modelOverrides": {
|
|
142
|
+
"some-provider/big-model": {
|
|
143
|
+
"reserveTokens": 400000
|
|
144
|
+
},
|
|
145
|
+
"local/small-model": {
|
|
146
|
+
"reserveTokens": 2048,
|
|
147
|
+
"keepRecentTokens": 4096
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Keys match exact, case-sensitive `provider/modelId` values, not names or glob patterns. Model IDs may contain slashes (for example, `openrouter/anthropic/claude-sonnet-4`).
|
|
155
|
+
|
|
156
|
+
Each token setting resolves independently: matching model override → ordinary `compaction` setting → built-in default. In the example, `some-provider/big-model` keeps the ordinary 20000 recent tokens. Token values must be non-negative safe integers. Invalid values in the matching model override produce an error when read; only omitted fields fall back to the ordinary setting. Model override entries must be objects. Invalid ordinary token settings produce an error when read, even if the active model has a valid override. Only omitted ordinary values use built-in defaults. Zero is accepted, but `reserveTokens: 0` leaves no response margin and also sets the summarization output budget to zero.
|
|
157
|
+
|
|
158
|
+
Global and project settings merge recursively **before** model lookup. A project can override one field for a model without replacing its other fields or other models. A global model-specific value takes precedence over a project-wide fallback; override the same model entry in the project to change it.
|
|
159
|
+
|
|
160
|
+
`enabled` is not model-specific. The active model's token settings apply to manual compaction, automatic threshold checks (including between assistant turns), and overflow recovery. Switching models takes effect on the next check or compaction. Configure overrides in JSON; `/settings` retains the ordinary auto-compaction toggle.
|
|
161
|
+
|
|
162
|
+
See [compaction.md](compaction.md) for trigger and summarization behavior.
|
|
163
|
+
|
|
132
164
|
### Branch Summary
|
|
133
165
|
|
|
134
166
|
| Setting | Type | Default | Description |
|
|
@@ -143,10 +175,13 @@ Set `KNIGHTCODE_SKIP_VERSION_CHECK=1` to disable the KnightCode version update c
|
|
|
143
175
|
| `retry.enabled` | boolean | `true` | Enable automatic agent-level retry on transient errors |
|
|
144
176
|
| `retry.maxRetries` | number | `3` | Maximum agent-level retry attempts |
|
|
145
177
|
| `retry.baseDelayMs` | number | `2000` | Base delay for agent-level exponential backoff (2s, 4s, 8s) |
|
|
178
|
+
| `retry.maxAgentDelayMs` | number | `60000` | Max agent-level retry delay (60s) |
|
|
146
179
|
| `retry.provider.timeoutMs` | number | SDK default | Provider/SDK request timeout in milliseconds |
|
|
147
180
|
| `retry.provider.maxRetries` | number | `0` | Provider/SDK retry attempts |
|
|
148
181
|
| `retry.provider.maxRetryDelayMs` | number | `60000` | Max server-requested delay before failing (60s) |
|
|
149
182
|
|
|
183
|
+
Agent-level retries use exponential backoff capped by `retry.maxAgentDelayMs`, so long retry runs stay responsive after prolonged outages.
|
|
184
|
+
|
|
150
185
|
When a provider requests a retry delay longer than `retry.provider.maxRetryDelayMs`, the request fails immediately with an informative error instead of waiting silently. Set it to `0` to disable the limit.
|
|
151
186
|
|
|
152
187
|
Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explicitly needed. Setting it above `0` can make SDK/provider retries handle out-of-usage-limit errors before KnightCode sees them, which may block the agent until the provider quota resets in some circumstances.
|
|
@@ -157,6 +192,7 @@ Keep `retry.provider.maxRetries` at `0` unless provider-level retries are explic
|
|
|
157
192
|
"enabled": true,
|
|
158
193
|
"maxRetries": 3,
|
|
159
194
|
"baseDelayMs": 2000,
|
|
195
|
+
"maxAgentDelayMs": 60000,
|
|
160
196
|
"provider": {
|
|
161
197
|
"timeoutMs": 3600000,
|
|
162
198
|
"maxRetries": 0,
|
|
@@ -14,6 +14,14 @@ KnightCode auto-detects OSC 8 hyperlinks, inline image protocols, and truecolor.
|
|
|
14
14
|
|
|
15
15
|
Settings take precedence over environment variables; unset or `auto` preserves detection. Only force capabilities supported by the complete terminal path, since unsupported escape sequences can corrupt rendering.
|
|
16
16
|
|
|
17
|
+
## Text Selection and Copy
|
|
18
|
+
|
|
19
|
+
Which side owns a mouse drag depends on the [TUI mode](usage.md#other-options).
|
|
20
|
+
|
|
21
|
+
In `fullscreen` mode, knightcode enables mouse reporting and owns text selection itself. Dragging with the primary button selects, and the selection is copied to the clipboard on release. Set `fullscreenCopyOnSelect` to `false` to keep the selection highlighted and copy it with `Ctrl+X` instead. To reach the terminal's own selection while knightcode captures the mouse, hold the terminal's bypass modifier — usually `Shift`, `Option` in iTerm2, and `Shift+Command`/`Shift+Ctrl` in Ghostty.
|
|
22
|
+
|
|
23
|
+
In `regular` mode, knightcode never enables mouse reporting, so a drag is the terminal emulator's own selection and knightcode is not involved in copying it. Use the terminal's copy shortcut — `Ctrl+Shift+C` on most Linux and Windows terminals, `Command+C` on macOS — or enable the terminal's copy-on-select option. Dragging alone does not reach the clipboard in terminals where that option is off by default, which includes Windows Terminal (`copyOnSelect` defaults to `false`) and Apple Terminal, which has no such option. Switch to `fullscreen` if you want drag-to-copy without depending on the terminal.
|
|
24
|
+
|
|
17
25
|
## Kitty
|
|
18
26
|
|
|
19
27
|
Works out of the box.
|
package/bin/docs/tui.md
CHANGED
|
@@ -930,7 +930,7 @@ export default function (knightcode: ExtensionAPI) {
|
|
|
930
930
|
|
|
931
931
|
- **Extend `CustomEditor`** (not base `Editor`) to get app keybindings (escape to abort, ctrl+d to exit, model switching, etc.)
|
|
932
932
|
- **Call `super.handleInput(data)`** for keys you don't handle
|
|
933
|
-
- **
|
|
933
|
+
- **Status spinners**: custom editors keep standalone status rows by default. Pass `{ embedWorkingStatus: true }` as the fourth `CustomEditor` constructor argument to embed working, compaction, branch summarization, and retry spinners in the editor border instead.
|
|
934
934
|
- **Factory pattern**: `setEditorComponent` receives a factory function that gets `tui`, `theme`, and `keybindings`
|
|
935
935
|
- **Pass `undefined`** to restore the default editor: `ctx.ui.setEditorComponent(undefined)`
|
|
936
936
|
|
package/bin/docs/usage.md
CHANGED
|
@@ -38,8 +38,8 @@ Type `/` in the editor to open command completion. Extensions can register custo
|
|
|
38
38
|
|---------|-------------|
|
|
39
39
|
| `/login`, `/logout` | Manage OAuth or API-key credentials |
|
|
40
40
|
| [`/llama`](llama-cpp.md) | Download, load, and unload llama.cpp router models |
|
|
41
|
-
| `/model` | Switch models; Ctrl+S in the picker saves the startup default |
|
|
42
|
-
| `/thinking` | Switch thinking level; Ctrl+S in the picker saves the startup default |
|
|
41
|
+
| `/model` | Switch models; Ctrl+S or Ctrl+D in the picker saves the startup default |
|
|
42
|
+
| `/thinking` | Switch thinking level; Ctrl+S or Ctrl+D in the picker saves the startup default |
|
|
43
43
|
| `/scoped-models` | Enable/disable models for Ctrl+P cycling |
|
|
44
44
|
| `/settings` | Theme, message delivery, transport, and other preferences |
|
|
45
45
|
| `/resume` | Pick from previous sessions |
|
|
@@ -249,7 +249,7 @@ knightcode --no-extensions -e ./my-extension.ts
|
|
|
249
249
|
| `-h`, `--help` | Show help |
|
|
250
250
|
| `-v`, `--version` | Show version |
|
|
251
251
|
|
|
252
|
-
In `fullscreen` mode, the transcript scrolls inside the terminal viewport while queued messages, working status, extension widgets, editor, and footer remain fixed at the bottom. Mouse/trackpad input scrolls the region under the pointer; keyboard viewport actions always remain available. Inline images work in terminals that support the Kitty graphics protocol, including Kitty and Ghostty. In iTerm2 they render as text placeholders because its inline-image protocol cannot delete or crop placements during application-owned scrolling. In `regular` mode, knightcode uses the main screen and terminal-owned scrollback, and iTerm2 inline images continue to render normally. See [Terminal setup](terminal-setup.md) for terminal-specific settings and workarounds.
|
|
252
|
+
In `fullscreen` mode, the transcript scrolls inside the terminal viewport while queued messages, working status, extension widgets, editor, and footer remain fixed at the bottom. Mouse/trackpad input scrolls the region under the pointer; keyboard viewport actions always remain available. Inline images work in terminals that support the Kitty graphics protocol, including Kitty and Ghostty. In iTerm2 they render as text placeholders because its inline-image protocol cannot delete or crop placements during application-owned scrolling. In `regular` mode, knightcode uses the main screen and terminal-owned scrollback, and iTerm2 inline images continue to render normally. Text selection differs between the two modes: fullscreen captures the mouse and owns selection, so dragging copies to the clipboard on release, while regular mode never captures the mouse and leaves both selecting and copying to the terminal emulator. See [Text selection and copy](terminal-setup.md#text-selection-and-copy) for the per-terminal shortcuts, and [Terminal setup](terminal-setup.md) for other terminal-specific settings and workarounds.
|
|
253
253
|
|
|
254
254
|
Set **TUI mode** in `/settings` to switch between `regular` and `fullscreen` immediately and choose the default for future sessions. **Fullscreen exit output** controls whether exiting fullscreen prints the final transcript or restores the previous screen and prints only the session resume hint.
|
|
255
255
|
|
package/bin/knightcode
CHANGED
|
Binary file
|
package/bin/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knightcodeai/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "KnightCode — a local, BYOK terminal coding agent powered by OpenRouter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/KnightCodeAI/knightcode.git"
|
|
9
9
|
},
|
|
10
|
-
"homepage": "https://knightcode.
|
|
10
|
+
"homepage": "https://knightcode.dev",
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"knightcodeConfig": {
|
|
13
13
|
"configDir": ".knightcode"
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"test": "vitest --run"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@knightcodeai/cli-linux-x64": "0.6.
|
|
41
|
-
"@knightcodeai/cli-linux-arm64": "0.6.
|
|
42
|
-
"@knightcodeai/cli-darwin-x64": "0.6.
|
|
43
|
-
"@knightcodeai/cli-darwin-arm64": "0.6.
|
|
44
|
-
"@knightcodeai/cli-win32-x64": "0.6.
|
|
40
|
+
"@knightcodeai/cli-linux-x64": "0.6.2",
|
|
41
|
+
"@knightcodeai/cli-linux-arm64": "0.6.2",
|
|
42
|
+
"@knightcodeai/cli-darwin-x64": "0.6.2",
|
|
43
|
+
"@knightcodeai/cli-darwin-arm64": "0.6.2",
|
|
44
|
+
"@knightcodeai/cli-win32-x64": "0.6.2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@knightcode/agent": "workspace:*",
|
|
@@ -56,19 +56,20 @@
|
|
|
56
56
|
"@types/hosted-git-info": "3.0.5",
|
|
57
57
|
"@types/proper-lockfile": "4.1.4",
|
|
58
58
|
"@types/semver": "7.7.1",
|
|
59
|
-
"chalk": "
|
|
59
|
+
"chalk": "6.0.0",
|
|
60
60
|
"cross-spawn": "7.0.6",
|
|
61
61
|
"diff": "8.0.4",
|
|
62
|
-
"grok-mermaid": "0.2.
|
|
62
|
+
"grok-mermaid": "0.2.3",
|
|
63
63
|
"highlight.js": "10.7.3",
|
|
64
64
|
"hosted-git-info": "9.0.3",
|
|
65
|
-
"ignore": "7.0.
|
|
65
|
+
"ignore": "7.0.8",
|
|
66
66
|
"jiti": "2.7.0",
|
|
67
|
-
"
|
|
67
|
+
"marked": "18.0.11",
|
|
68
|
+
"minimatch": "10.2.6",
|
|
68
69
|
"proper-lockfile": "4.1.2",
|
|
69
|
-
"semver": "7.8.
|
|
70
|
-
"typebox": "1.3.
|
|
71
|
-
"undici": "8.
|
|
70
|
+
"semver": "7.8.5",
|
|
71
|
+
"typebox": "1.3.27",
|
|
72
|
+
"undici": "8.10.2",
|
|
72
73
|
"yaml": "2.9.0"
|
|
73
74
|
}
|
|
74
75
|
}
|