@knightcodeai/cli-darwin-x64 0.9.3 → 0.10.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/bin/CHANGELOG.md +56 -0
- package/bin/docs/configuration.md +1 -1
- package/bin/docs/custom-provider.md +43 -4
- package/bin/docs/extensions.md +7 -0
- package/bin/docs/packages.md +3 -1
- package/bin/docs/rpc-commands.md +9 -3
- package/bin/docs/rpc.md +3 -1
- package/bin/docs/sdk.md +1 -1
- package/bin/docs/settings.md +1 -1
- package/bin/docs/slash-commands.md +1 -1
- package/bin/docs/themes.md +33 -7
- package/bin/docs/tui.md +18 -0
- package/bin/docs/usage.md +9 -1
- package/bin/export-html/template.css +10 -0
- package/bin/export-html/template.js +50 -17
- package/bin/knightcode +2 -2
- package/bin/package.json +6 -6
- package/bin/theme/dark.json +57 -70
- package/bin/theme/light.json +57 -69
- package/bin/theme/theme-schema.json +7 -2
- package/package.json +1 -1
package/bin/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# @knightcodeai/cli
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Added a classifier gate to `/tools` that asks a classifier model such as Jev whether each shell or file-editing call is risky and asks for confirmation before running it, and exposed `classify()` to extensions through the model registry.
|
|
8
|
+
|
|
9
|
+
- Added image and classifier models to the shared model catalog, including the Jev classifier through OpenRouter and Cloudflare Workers AI, so they are listed, authenticated and refreshed like chat models.
|
|
10
|
+
|
|
11
|
+
- Added a `system` theme that follows the terminal's light or dark appearance and switches when it changes. Themes can now use OKLab/OKHSL color values and text styles, and the built-in dark and light themes were redrawn with them.
|
|
12
|
+
|
|
13
|
+
- Added GPT-6 Sol and GPT-6 Luna, and the new GitHub Copilot models.
|
|
14
|
+
|
|
15
|
+
- Added a toggle to HTML exports that shows or hides hidden messages.
|
|
16
|
+
|
|
17
|
+
- Added provider stream events for extensions: a handler receives every raw provider chunk, including metadata the normalized events drop.
|
|
18
|
+
|
|
19
|
+
- Added the prompt's disposition to RPC `prompt` and `follow_up` responses, so a client can tell whether the prompt started a run, was queued, or was consumed by an extension.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Changed the Fireworks default model to Kimi K3; Kimi K2.6 is no longer served.
|
|
24
|
+
|
|
25
|
+
- Changed the startup header to drop the themes section; themes stay available from `/settings`.
|
|
26
|
+
|
|
27
|
+
- Changed the build to TypeScript 7 with an ES2024 target.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Fixed path autocomplete after an opening parenthesis or backtick, and skill autocomplete while typing the `skill:` prefix.
|
|
32
|
+
|
|
33
|
+
- Fixed Claude Opus 5.5 on GitHub Copilot offering effort levels the endpoint rejects.
|
|
34
|
+
|
|
35
|
+
- Fixed custom themes rendering with 256 colors on truecolor terminals.
|
|
36
|
+
|
|
37
|
+
- Fixed an extension loaded through two paths starting two runtimes.
|
|
38
|
+
|
|
39
|
+
- Fixed pricing for OpenAI Fast mode, which is now billed like the priority service tier, and for Vercel AI Gateway 1-hour cache writes.
|
|
40
|
+
|
|
41
|
+
- Fixed Kitty images being stretched; the placement size is now chosen by the smallest aspect distortion.
|
|
42
|
+
|
|
43
|
+
- Fixed Mistral GLM responses splitting thinking and opening empty blocks on empty content deltas.
|
|
44
|
+
|
|
45
|
+
- Fixed the terminal cursor staying hidden when an overlay closes after the UI stopped.
|
|
46
|
+
|
|
47
|
+
- Fixed pinned temporary git extensions reusing the cache folder of a different ref.
|
|
48
|
+
|
|
49
|
+
- Fixed read calls with a null offset or limit showing a line range instead of a full-file read.
|
|
50
|
+
|
|
51
|
+
- Fixed `RpcClient` skipping the next listener when one unsubscribes while an event is dispatched.
|
|
52
|
+
|
|
53
|
+
- Fixed model `samplingParams` being ignored by direct `stream()` and `complete()` calls.
|
|
54
|
+
|
|
55
|
+
- Fixed new sessions not being written to disk until the first assistant reply; the session file is now saved at the first user message.
|
|
56
|
+
|
|
57
|
+
- Fixed X11 clipboard text being read as an image when no image type was advertised.
|
|
58
|
+
|
|
3
59
|
## 0.9.3
|
|
4
60
|
|
|
5
61
|
### Changed
|
|
@@ -14,7 +14,7 @@ The agent directory is shown as `<agent-dir>` below. Set its location with the `
|
|
|
14
14
|
| `<agent-dir>/keybindings.json` | Custom terminal UI and application [keybindings](keybindings.md). |
|
|
15
15
|
| `<agent-dir>/models.json` | [Compatible endpoints, models, and model overrides](models.md#configure-a-compatible-endpoint). |
|
|
16
16
|
| `<agent-dir>/auth.json` | Saved API keys and OAuth credentials. |
|
|
17
|
-
| `<agent-dir>/tools.json` | [Web tool](usage.md#web-tools) and
|
|
17
|
+
| `<agent-dir>/tools.json` | [Web tool](usage.md#web-tools), scratchpad, and classifier gate settings written by `/tools`, including the Brave Search key. |
|
|
18
18
|
| `<agent-dir>/AGENTS.override.md`, `AGENTS.md`, `AGENTS.MD`, `CLAUDE.md`, or `CLAUDE.MD` | User instructions applied across working directories. |
|
|
19
19
|
| `<agent-dir>/SYSTEM.md` | Replaces KnightCode’s default system prompt. |
|
|
20
20
|
| `<agent-dir>/APPEND_SYSTEM.md` | Adds instructions to KnightCode’s system prompt. |
|
|
@@ -27,7 +27,45 @@ There are two registration forms:
|
|
|
27
27
|
|
|
28
28
|
Prefer a complete provider for new integrations that own more than static endpoint and model metadata. KnightCode composes `models.json` overrides above a registered native provider.
|
|
29
29
|
|
|
30
|
-
Registering only `baseUrl` or `headers` for an existing provider preserves its built-in models. Supplying `models` in the legacy form replaces
|
|
30
|
+
Registering only `baseUrl` or `headers` for an existing provider preserves its built-in models. Supplying `models` in the legacy form replaces that provider's models across chat, image, and classifier operations. An omitted `type` means `"chat"`; image and classifier models require explicit discriminants and implementations keyed by their `api` values through the `images` and `classifiers` fields.
|
|
31
|
+
|
|
32
|
+
For example, a mixed-operation provider can register non-chat models and their implementations together:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
knightcode.registerProvider("media-tools", {
|
|
36
|
+
apiKey: "$MEDIA_TOOLS_API_KEY",
|
|
37
|
+
models: [
|
|
38
|
+
{
|
|
39
|
+
type: "image",
|
|
40
|
+
id: "image-v1",
|
|
41
|
+
name: "Image V1",
|
|
42
|
+
api: "media-images",
|
|
43
|
+
baseUrl: "https://media.example.com/v1",
|
|
44
|
+
input: ["text"],
|
|
45
|
+
output: ["image"],
|
|
46
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
type: "classifier",
|
|
50
|
+
id: "classifier-v1",
|
|
51
|
+
name: "Classifier V1",
|
|
52
|
+
api: "media-classifier",
|
|
53
|
+
baseUrl: "https://media.example.com/v1",
|
|
54
|
+
input: ["text"],
|
|
55
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
56
|
+
contextWindow: 64000,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
images: {
|
|
60
|
+
"media-images": { generateImages: async (model, context, options) => result },
|
|
61
|
+
},
|
|
62
|
+
classifiers: {
|
|
63
|
+
"media-classifier": { classify: async (model, context, options) => result },
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Model-level `baseUrl` values take precedence over the provider endpoint. If no `models` list is supplied, built-in models of every operation remain registered. Equal model IDs in different operations remain distinct, including their model-specific headers.
|
|
31
69
|
|
|
32
70
|
Calls made after initial extension loading take effect immediately. Use `knightcode.unregisterProvider()` to remove the dynamic provider and restore built-in behavior that it replaced.
|
|
33
71
|
|
|
@@ -52,7 +90,7 @@ Never write access tokens, refresh tokens, authorization headers, or complete pr
|
|
|
52
90
|
|
|
53
91
|
## Supply and refresh models
|
|
54
92
|
|
|
55
|
-
Every model needs an ID, display name, input capabilities, context window
|
|
93
|
+
Every model needs an ID, display name, input capabilities, and cost metadata. Chat and classifier models also need a context window; chat models need an output limit and reasoning support; image models declare their output modalities. Choose the API implementation at the provider level unless one model requires an override.
|
|
56
94
|
|
|
57
95
|
Set `promptCache.short` or `promptCache.long` to the provider's best-effort cache lifetime in seconds when KnightCode should keep an idle prompt cache warm. Leave them unset to disable cache warming for that retention tier.
|
|
58
96
|
|
|
@@ -65,7 +103,7 @@ Use `refreshModels` when the available catalog comes from a live service. Pass `
|
|
|
65
103
|
The two registration forms have different refresh contracts:
|
|
66
104
|
|
|
67
105
|
- A complete `Provider` returns nothing. It calls `context.publish({ update })` to install provider-owned model state, after which its synchronous `getModels()` exposes the latest list.
|
|
68
|
-
- Legacy `ProviderConfig.refreshModels` returns model definitions. KnightCode replaces that registration’s live models with the returned list and applies any requested persistence.
|
|
106
|
+
- Legacy `ProviderConfig.refreshModels` returns mixed-operation model definitions. KnightCode replaces that registration’s live models with the returned list and applies any requested persistence.
|
|
69
107
|
|
|
70
108
|
Publish persisted catalog data only when it should survive across runs. A live service such as llama.cpp can update its in-memory list without persisting it; a remote catalog can retain a snapshot for offline startup.
|
|
71
109
|
|
|
@@ -102,9 +140,10 @@ The stream must also honor request instrumentation supplied through `SimpleStrea
|
|
|
102
140
|
|
|
103
141
|
- Call `options.onPayload` before sending the provider request and use any replacement payload it returns.
|
|
104
142
|
- Call `options.onResponse` after receiving the response but before consuming its body.
|
|
143
|
+
- Await `options.onProviderStreamEvent?.(providerEvent, model)` for each parsed provider event before normalizing it.
|
|
105
144
|
- Pass through the abort signal and provider-scoped environment.
|
|
106
145
|
|
|
107
|
-
These hooks power extension request inspection
|
|
146
|
+
These hooks power extension request inspection, response-header events, and provider-stream observation. Omitting them makes the provider behave differently from KnightCode’s built-in providers.
|
|
108
147
|
|
|
109
148
|
## Report failures and usage
|
|
110
149
|
|
package/bin/docs/extensions.md
CHANGED
|
@@ -102,6 +102,12 @@ Events cover resource discovery, sessions, agent and message lifecycle, provider
|
|
|
102
102
|
|
|
103
103
|
`message_end` can replace a finalized message while preserving its role. `tool_call` can mutate input or block execution. `tool_result` handlers compose, with each handler seeing prior changes.
|
|
104
104
|
|
|
105
|
+
<a id="provider_stream_event"></a>
|
|
106
|
+
|
|
107
|
+
`provider_stream_event` fires for each parsed provider stream event before KnightCode normalizes it. The event identifies the provider, API, and model; `event.data` is the earliest structured value available to KnightCode, not necessarily the original HTTP bytes or SSE frame. Treat it as read-only because mutation can affect normalization. The event is notification-only and is not persisted.
|
|
108
|
+
|
|
109
|
+
Handlers are awaited in stream order, so slow handlers delay stream consumption. Handler errors are reported without changing the provider response. See [`debug-provider.ts`](../examples/extensions/debug-provider.ts) for an opt-in viewer that groups raw events by assistant message.
|
|
110
|
+
|
|
105
111
|
<a id="context_with_system"></a>
|
|
106
112
|
|
|
107
113
|
`context` transforms conversation messages without prompt and tool system messages; KnightCode restores that state afterward. Use `context_with_system` only when a request-local transformation must own the complete transcript, and keep a system message at index zero.
|
|
@@ -151,6 +157,7 @@ KnightCode records the initial prompt and tool set in the transcript's first sys
|
|
|
151
157
|
|
|
152
158
|
`ExtensionContext` provides the working directory, mode, UI, session manager, model runtime, abort signal, context usage, and controls for compaction and shutdown.
|
|
153
159
|
Use `ctx.modelRegistry.streamSimple()` for provider-neutral nested model calls.
|
|
160
|
+
Use `ctx.modelRegistry.getAvailableClassifiers()` and `ctx.modelRegistry.classify()` to ask a classifier model structured questions, as the built-in [classifier gate](usage.md#classifier-gate) does.
|
|
154
161
|
|
|
155
162
|
Command handlers receive `ExtensionCommandContext`, which adds operations for waiting until idle, reloading, tree navigation, and session replacement.
|
|
156
163
|
These operations are command-only because calling them from lifecycle handlers can deadlock the runtime.
|
package/bin/docs/packages.md
CHANGED
|
@@ -85,7 +85,9 @@ KnightCode supplies these packages to extensions and skills:
|
|
|
85
85
|
- `@knightcode/tui`
|
|
86
86
|
- `typebox`
|
|
87
87
|
|
|
88
|
-
Declare
|
|
88
|
+
Declare the host-provided packages listed above in `peerDependencies` with a `"*"` range and do not bundle them. KnightCode suppresses automatic peer installation for managed npm packages and git packages installed with npm, pnpm, or Bun. Local packages are not installed or modified, so their dependency tree remains the package author's responsibility.
|
|
89
|
+
|
|
90
|
+
Do not list host-provided packages in `dependencies`. A physical copy can bypass KnightCode's extension module mapping in compiled ESM and create duplicate classes, registries, and initialization work. KnightCode reports an extension warning when it detects this manifest configuration. Other KnightCode packages used as dependencies must be included in the published tarball and referenced through their `node_modules` resource paths.
|
|
89
91
|
|
|
90
92
|
Installed packages load with separate module roots. Do not rely on two packages sharing one dependency instance or one package resolving another package’s undeclared dependency.
|
|
91
93
|
|
package/bin/docs/rpc-commands.md
CHANGED
|
@@ -34,9 +34,11 @@ If the agent is streaming and no `streamingBehavior` is specified, the command r
|
|
|
34
34
|
|
|
35
35
|
Response:
|
|
36
36
|
```json
|
|
37
|
-
{"id": "req-1", "type": "response", "command": "prompt", "success": true}
|
|
37
|
+
{"id": "req-1", "type": "response", "command": "prompt", "success": true, "data": {"disposition": "started"}}
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
`data.disposition` is `"handled"` if an extension command or input handler consumed the prompt, `"queued"` if KnightCode queued it during a run, or `"started"` if KnightCode accepted it to start a run. This describes the submitted prompt, not independent work started by an extension or a guarantee of completion.
|
|
41
|
+
|
|
40
42
|
`success: true` means the prompt was accepted, queued, or handled immediately. `success: false` means the prompt was rejected before acceptance. Failures after acceptance are reported through the normal event and message stream, not as a second `response` for the same request id.
|
|
41
43
|
|
|
42
44
|
The `images` field is optional. Each image uses `ImageContent` format: `{"type": "image", "data": "base64-encoded-data", "mimeType": "image/png"}`.
|
|
@@ -58,9 +60,11 @@ The `images` field is optional. Each image uses `ImageContent` format (same as `
|
|
|
58
60
|
|
|
59
61
|
Response:
|
|
60
62
|
```json
|
|
61
|
-
{"type": "response", "command": "steer", "success": true}
|
|
63
|
+
{"type": "response", "command": "steer", "success": true, "data": {"disposition": "queued"}}
|
|
62
64
|
```
|
|
63
65
|
|
|
66
|
+
`data.disposition` is `"handled"` if an input handler consumed this steer, or `"queued"` if KnightCode queued it (including after a handler transformed it). It does not guarantee this message remains queued.
|
|
67
|
+
|
|
64
68
|
See [set_steering_mode](#set_steering_mode) for controlling how steering messages are processed.
|
|
65
69
|
|
|
66
70
|
### follow_up
|
|
@@ -80,9 +84,11 @@ The `images` field is optional. Each image uses `ImageContent` format (same as `
|
|
|
80
84
|
|
|
81
85
|
Response:
|
|
82
86
|
```json
|
|
83
|
-
{"type": "response", "command": "follow_up", "success": true}
|
|
87
|
+
{"type": "response", "command": "follow_up", "success": true, "data": {"disposition": "queued"}}
|
|
84
88
|
```
|
|
85
89
|
|
|
90
|
+
`data.disposition` has the same `"handled"` or `"queued"` meaning as for `steer`, applied to this follow-up.
|
|
91
|
+
|
|
86
92
|
See [set_follow_up_mode](#set_follow_up_mode) for controlling how follow-up messages are processed.
|
|
87
93
|
|
|
88
94
|
### abort
|
package/bin/docs/rpc.md
CHANGED
|
@@ -61,9 +61,11 @@ A successful `prompt` response means the prompt was accepted, queued, or handled
|
|
|
61
61
|
|
|
62
62
|
```json
|
|
63
63
|
{"id":"req-2","type":"prompt","message":"Review this repository"}
|
|
64
|
-
{"id":"req-2","type":"response","command":"prompt","success":true}
|
|
64
|
+
{"id":"req-2","type":"response","command":"prompt","success":true,"data":{"disposition":"started"}}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
`data.disposition` reports what happened to the prompt. If it is `"handled"`, no run started for this prompt, so don't wait for `agent_settled`. See [RPC Commands](rpc-commands.md#prompt) for all values.
|
|
68
|
+
|
|
67
69
|
Continue consuming [events](json.md) after that response. `agent_end` marks the end of one low-level agent run, but retries, overflow recovery, compaction, steering, or follow-up work can still follow. Wait for `agent_settled` when the client needs to know KnightCode will not continue automatically.
|
|
68
70
|
|
|
69
71
|
Subscribe before sending a prompt to avoid missing a fast completion. `RpcClient.promptAndWait()` does this internally. If using separate `RpcClient` calls, install the event listener before `prompt()` and call `waitForIdle()` only while a run is active.
|
package/bin/docs/sdk.md
CHANGED
|
@@ -65,7 +65,7 @@ After a runtime replacement, subscriptions belong to the old `AgentSession` and
|
|
|
65
65
|
|
|
66
66
|
A prompt sent while the session is already streaming must specify whether it should steer the current run or follow it. Calling `prompt()` without that choice rejects rather than guessing.
|
|
67
67
|
|
|
68
|
-
A steering message enters after the current assistant turn and its tool calls. A follow-up enters after the current run finishes its pending work. `steer()` and `followUp()` expose those behaviors directly.
|
|
68
|
+
A steering message enters after the current assistant turn and its tool calls. A follow-up enters after the current run finishes its pending work. `steer()` and `followUp()` expose those behaviors directly and return `"queued"` if the input was queued (including after an extension transformed it), or `"handled"` if an extension consumed it.
|
|
69
69
|
|
|
70
70
|
`abort()` stops the active operation and waits for the session to become idle. `waitForIdle()` waits without aborting it.
|
|
71
71
|
|
package/bin/docs/settings.md
CHANGED
|
@@ -75,7 +75,7 @@ See [Compaction Reference](compaction.md) for trigger, summarization, and valida
|
|
|
75
75
|
|
|
76
76
|
| Setting | Type | Default | Description |
|
|
77
77
|
|---|---|---|---|
|
|
78
|
-
| `theme` | string |
|
|
78
|
+
| `theme` | string | `"system"` | Built-in or custom theme name. `system` derives colors from the terminal theme. |
|
|
79
79
|
| `quietStartup` | boolean | `false` | Hide the startup header. |
|
|
80
80
|
| `tuiMode` | `"regular" \| "fullscreen"` | `"regular"` | Interactive terminal UI mode. 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)). |
|
|
81
81
|
| `fullscreenExitOutput` | `"transcript" \| "resume-hint"` | `"transcript"` | Output printed when fullscreen mode exits. |
|
|
@@ -14,7 +14,7 @@ Extensions, prompt templates, and skills can add commands. The command menu in K
|
|
|
14
14
|
| `/scoped-models` | Configure the models used by interactive cycling |
|
|
15
15
|
| `/login [provider]` | Add provider authentication |
|
|
16
16
|
| `/logout` | Remove provider authentication |
|
|
17
|
-
| `/tools` | Turn `webfetch`, `websearch`,
|
|
17
|
+
| `/tools` | Turn `webfetch`, `websearch`, the [scratchpad](usage.md#scratchpad), and the [classifier gate](usage.md#classifier-gate) off, on for this session, or on by default; pick the search provider, its key, and the gate's model |
|
|
18
18
|
| `/llama` | Manage models on the configured llama.cpp router |
|
|
19
19
|
|
|
20
20
|
## Sessions and context
|
package/bin/docs/themes.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
# Customize KnightCode with themes
|
|
2
2
|
|
|
3
|
-
Themes control the colors KnightCode uses in interactive mode and HTML exports. KnightCode includes `dark
|
|
3
|
+
Themes control the colors KnightCode uses in interactive mode and HTML exports. KnightCode includes the `system`, `dark`, and `light` themes. You can select one theme, follow your terminal's light or dark appearance, or create your own palette.
|
|
4
|
+
|
|
5
|
+
## Use your terminal's colors
|
|
6
|
+
|
|
7
|
+
The `system` theme is the default. It builds KnightCode's colors from your terminal's theme, so KnightCode matches the terminal instead of bringing its own palette:
|
|
8
|
+
|
|
9
|
+
- KnightCode queries the terminal's default foreground and background colors and its 16 ANSI colors.
|
|
10
|
+
- Each KnightCode color takes its hue from one ANSI color, for example errors from red and links from blue.
|
|
11
|
+
- KnightCode sets each color's lightness so that it stands out from the background by a minimum contrast. Body text keeps at least a 4.5:1 WCAG contrast ratio on the background and every panel.
|
|
12
|
+
- When the terminal switches between light and dark, KnightCode queries the colors again and rebuilds the theme.
|
|
13
|
+
|
|
14
|
+
The theme adapts to what the terminal reports:
|
|
15
|
+
|
|
16
|
+
| Terminal reports | Result |
|
|
17
|
+
|---|---|
|
|
18
|
+
| Background and ANSI colors | Colors from the terminal palette, placed for the actual background. |
|
|
19
|
+
| Background only | KnightCode's own hues, placed for the actual background. |
|
|
20
|
+
| Nothing | ANSI color indices and the terminal's default colors, which the terminal renders itself. Secondary text is faint, and panels have no background color. |
|
|
21
|
+
|
|
22
|
+
KnightCode asks the terminal for its colors when it starts. Terminals usually answer within a few milliseconds, and KnightCode waits at most 100 ms before showing the startup header. If the terminal does not answer in time, KnightCode uses the ANSI color fallback, and it still applies the colors if they arrive later, for example over a slow SSH connection. `system` is a reserved name: a custom theme with that name is ignored.
|
|
4
23
|
|
|
5
24
|
<a id="selecting-a-theme"></a>
|
|
6
25
|
|
|
@@ -16,6 +35,8 @@ The selection is saved as the `theme` [setting](settings.md#terminal-and-display
|
|
|
16
35
|
}
|
|
17
36
|
```
|
|
18
37
|
|
|
38
|
+
Without a `theme` setting, KnightCode uses `system`.
|
|
39
|
+
|
|
19
40
|
Automatic mode stores the light theme first and the dark theme second:
|
|
20
41
|
|
|
21
42
|
```json
|
|
@@ -24,7 +45,7 @@ Automatic mode stores the light theme first and the dark theme second:
|
|
|
24
45
|
}
|
|
25
46
|
```
|
|
26
47
|
|
|
27
|
-
When automatic mode is active, KnightCode changes themes when the terminal reports an appearance change. Theme names cannot contain `/` because KnightCode reserves it for this setting format.
|
|
48
|
+
KnightCode decides whether the terminal is light or dark from its reported background and foreground colors. If the terminal does not report its background, KnightCode uses the terminal's light/dark notification, then the `COLORFGBG` environment variable, then dark. The same decision picks the theme of a light/dark pair and the appearance of `system`. When automatic mode is active, KnightCode changes themes when the terminal reports an appearance change. Theme names cannot contain `/` because KnightCode reserves it for this setting format.
|
|
28
49
|
|
|
29
50
|
Use `--use-theme` to choose the initial theme for one invocation without changing the saved setting:
|
|
30
51
|
|
|
@@ -37,7 +58,7 @@ See [CLI resources](cli.md#resources) for the command-line option.
|
|
|
37
58
|
|
|
38
59
|
## Create a custom theme
|
|
39
60
|
|
|
40
|
-
Copy one of the [built-in themes](https://github.com/KnightCodeAI/knightcode/tree/main/packages/cli/src/modes/interactive/theme) or create a new JSON file conforming to the [schema](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/modes/interactive/theme/theme-schema.json).
|
|
61
|
+
Copy one of the [built-in themes](https://github.com/KnightCodeAI/knightcode/tree/main/packages/cli/src/modes/interactive/theme) or create a new JSON file conforming to the [schema](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/modes/interactive/theme/theme-schema.json). The built-in themes use OKHSL colors, with variables for colors that several roles share, so you can adjust a hue, saturation, or lightness directly.
|
|
41
62
|
|
|
42
63
|
1. Save the file as `<agent-dir>/themes/my-theme.json`. The agent directory defaults to `~/.knightcode/agent`.
|
|
43
64
|
2. Set its `name` to `my-theme`.
|
|
@@ -51,21 +72,26 @@ Use the theme name as the filename. KnightCode hot-reloads the active user theme
|
|
|
51
72
|
| Property | Required | Responsibility |
|
|
52
73
|
|---|---|---|
|
|
53
74
|
| `$schema` | No | Enables editor validation and completion against KnightCode's published schema. |
|
|
54
|
-
| `name` | Yes | Identifies the theme in selectors and settings. It must be unique and cannot
|
|
75
|
+
| `name` | Yes | Identifies the theme in selectors and settings. It must be unique, cannot contain `/`, and cannot be `system`. |
|
|
76
|
+
| `appearance` | No | `"dark"` or `"light"`: the background the theme is designed for. KnightCode detects it from the theme colors when omitted. |
|
|
55
77
|
| `vars` | No | Defines reusable color values. Variables can reference other variables. |
|
|
56
78
|
| `colors` | Yes | Assigns colors to terminal UI roles. The schema identifies required and optional roles. |
|
|
57
79
|
| `export` | No | Overrides page and panel backgrounds in HTML exports. |
|
|
58
80
|
|
|
59
|
-
A color can be written in
|
|
81
|
+
A color can be written in six forms:
|
|
60
82
|
|
|
61
83
|
| Form | Example | Meaning |
|
|
62
84
|
|---|---|---|
|
|
63
|
-
| RGB hexadecimal | `"#00aaff"` | A six-digit
|
|
85
|
+
| RGB hexadecimal | `"#0af"` or `"#00aaff"` | A three- or six-digit sRGB color. |
|
|
86
|
+
| OKLCH | `"oklch(62% 0.1 200)"` | Perceptual lightness, chroma, and hue. |
|
|
87
|
+
| OKHSL | `"okhsl(250 60% 55%)"` | Hue, saturation, and lightness. Saturation is relative to the most the sRGB gamut allows at that hue and lightness, so every value is in gamut and equal saturation looks equally colorful. |
|
|
64
88
|
| 256-color index | `39` | An ANSI palette index from `0` through `255`. |
|
|
65
89
|
| Variable reference | `"primary"` | The value of an entry in `vars`. |
|
|
66
90
|
| Terminal default | `""` | The terminal's default foreground or background color. |
|
|
67
91
|
|
|
68
|
-
|
|
92
|
+
Terminal default colors render as the terminal's own colors. Where KnightCode needs a concrete value, such as HTML export or extension color math, it uses the default colors the terminal reports, or a black or white guess based on the theme's appearance.
|
|
93
|
+
|
|
94
|
+
KnightCode resolves chained variable references. A missing variable or circular reference makes the theme invalid. KnightCode uses truecolor when available, gamut-maps OKLCH to sRGB, and approximates colors for 256-color terminals. HTML exports convert OKHSL values to hexadecimal because CSS does not support them. If colors differ from their source values, check your terminal's truecolor detection and contrast settings. See [Configure Your Terminal](terminal-setup.md#override-detected-capabilities).
|
|
69
95
|
|
|
70
96
|
Use the [theme JSON schema](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/modes/interactive/theme/theme-schema.json) for the exact properties, required colors, and accepted value types.
|
|
71
97
|
|
package/bin/docs/tui.md
CHANGED
|
@@ -79,6 +79,24 @@ See [`overlay-qa-tests.ts`](../examples/extensions/overlay-qa-tests.ts) for posi
|
|
|
79
79
|
|
|
80
80
|
Use the theme passed to the extension or component callback. Theme helpers produce ANSI-styled strings for semantic colors such as accent, muted text, success, warnings, errors, tool output, and Markdown.
|
|
81
81
|
|
|
82
|
+
Use `theme.style()` to combine foreground and background colors with text attributes:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
return new Text(
|
|
86
|
+
theme.style("Done!", {
|
|
87
|
+
fg: "success",
|
|
88
|
+
bg: "toolSuccessBg",
|
|
89
|
+
bold: true,
|
|
90
|
+
}),
|
|
91
|
+
0,
|
|
92
|
+
0,
|
|
93
|
+
);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
A style color can be a semantic theme token or a concrete `Color`. Foreground tokens are accepted as `fg` and background tokens as `bg`; to use a token's color in the other position, pass its concrete color, for example `{ fg: theme.colors.userMessageBg }`. Access concrete colors through `theme.colors` and use utilities such as `mixColors()` from `@knightcode/tui` when color math is needed. Tokens that a theme sets to the terminal default render with the terminal's own color; `theme.colors` reports the color the terminal announced for them, or a guess when it did not. Use `theme.appearance` (`"dark"` or `"light"`) to decide, for example, whether to lighten or darken a color. KnightCode converts the result to truecolor or 256-color output based on terminal capabilities. Theme tokens are converted once per theme; compute concrete colors outside the render path when possible.
|
|
97
|
+
|
|
98
|
+
The existing `theme.fg()` and `theme.bg()` helpers remain available for applying one semantic color.
|
|
99
|
+
|
|
82
100
|
Do not permanently store strings with theme colors unless `invalidate()` rebuilds them. A theme change clears render caches, but it cannot remove old ANSI colors embedded in application state.
|
|
83
101
|
|
|
84
102
|
Theme callbacks evaluated during rendering do not need special rebuilding. Stateless components can also calculate themed output on every render.
|
package/bin/docs/usage.md
CHANGED
|
@@ -49,7 +49,7 @@ Type `/` to search the available commands. The commands you will use most often
|
|
|
49
49
|
- `/thinking` selects how much reasoning the current model uses. Press `Shift+Tab` to cycle through supported levels.
|
|
50
50
|
- `/login` and `/logout` manage provider access.
|
|
51
51
|
- `/settings` changes common preferences.
|
|
52
|
-
- `/tools` turns the [web tools](#web-tools)
|
|
52
|
+
- `/tools` turns the [web tools](#web-tools), the [scratchpad](#scratchpad), and the [classifier gate](#classifier-gate) off, on for this session, or on by default.
|
|
53
53
|
|
|
54
54
|
Prompt templates, skills, and extensions can add more commands to the same menu. See [Choose a Model](models.md), [Configuration](configuration.md), or the complete [Slash Commands reference](slash-commands.md).
|
|
55
55
|
|
|
@@ -116,6 +116,14 @@ The agent keeps its working notes there in `notes.md`: task list, decisions, `fi
|
|
|
116
116
|
|
|
117
117
|
The scratchpad is off by default. When on, it adds about 60 tokens to the system prompt, which is cached; the notes cost tokens only after a compaction. It is not a tool, so `--tools` and `--exclude-tools` do not affect it. `/fork` starts a new, empty directory, and the operating system clears old ones with the rest of its temp files. If `<tmp>/knightcode-<uid>` already exists but is not a private directory you own, as when another user on a shared machine created it first, the scratchpad stays off and KnightCode reports why.
|
|
118
118
|
|
|
119
|
+
## Classifier gate
|
|
120
|
+
|
|
121
|
+
`/tools classifier-gate` asks a classifier model whether each `bash`, `powershell`, `write`, or `edit` call could cause harm that is hard to undo: deleting data beyond the task, exposing secrets, changing system configuration, or publishing to a remote service. A call rated risky (probability 0.5 or higher) asks for confirmation; in print and JSON modes it is blocked.
|
|
122
|
+
|
|
123
|
+
Pick the model in the panel's **Model** row. It lists classifier models from providers you are logged in to, such as TypeSafe Jev through OpenRouter. The gate fails closed: a call runs without asking only when the classifier scores the whole call below 0.5. With no model set, when the classifier errors or returns no answer, or when the call's input is over 4,000 characters (as a large `write` often is), the call asks for confirmation or is blocked. Interrupting the turn closes the confirmation.
|
|
124
|
+
|
|
125
|
+
The gate is off by default. Each gated call is one classifier request, billed by its provider, and adds its latency before the tool runs.
|
|
126
|
+
|
|
119
127
|
## Copy, export, or share results
|
|
120
128
|
|
|
121
129
|
Press `Ctrl+X` or run `/copy` to copy the last assistant response. Use `/export` to save the session as HTML or JSONL.
|
|
@@ -300,6 +300,12 @@
|
|
|
300
300
|
border-color: var(--borderAccent);
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
.header-toggle-btn[aria-pressed="true"] {
|
|
304
|
+
color: var(--accent);
|
|
305
|
+
border-color: var(--accent);
|
|
306
|
+
font-weight: bold;
|
|
307
|
+
}
|
|
308
|
+
|
|
303
309
|
/* Header */
|
|
304
310
|
.header {
|
|
305
311
|
background: var(--container-bg);
|
|
@@ -786,6 +792,10 @@
|
|
|
786
792
|
border-radius: 4px;
|
|
787
793
|
}
|
|
788
794
|
|
|
795
|
+
body:not(.show-hidden-messages) .hook-message-hidden {
|
|
796
|
+
display: none;
|
|
797
|
+
}
|
|
798
|
+
|
|
789
799
|
.hook-type {
|
|
790
800
|
color: var(--customMessageLabel);
|
|
791
801
|
font-weight: bold;
|
|
@@ -1311,9 +1311,10 @@
|
|
|
1311
1311
|
</div>`;
|
|
1312
1312
|
}
|
|
1313
1313
|
|
|
1314
|
-
if (entry.type === 'custom_message'
|
|
1315
|
-
|
|
1316
|
-
|
|
1314
|
+
if (entry.type === 'custom_message') {
|
|
1315
|
+
const hidden = entry.display === false;
|
|
1316
|
+
return `<div class="hook-message${hidden ? ' hook-message-hidden' : ''}" id="${entryDomId}">${tsHtml}
|
|
1317
|
+
<div class="hook-type">[${escapeHtml(entry.customType)}]${hidden ? ' · Hidden in terminal' : ''}</div>
|
|
1317
1318
|
<div class="markdown-content">${safeMarkedParse(typeof entry.content === 'string' ? entry.content : JSON.stringify(entry.content))}</div>
|
|
1318
1319
|
</div>`;
|
|
1319
1320
|
}
|
|
@@ -1389,10 +1390,11 @@
|
|
|
1389
1390
|
<div class="header">
|
|
1390
1391
|
<h1>Session: ${escapeHtml(header?.id || 'unknown')}</h1>
|
|
1391
1392
|
<div class="help-bar">
|
|
1392
|
-
<span class="help-hint">T toggle thinking · O toggle tools</span>
|
|
1393
|
+
<span class="help-hint">T toggle thinking · O toggle tools · H toggle hidden messages</span>
|
|
1393
1394
|
<div class="help-actions">
|
|
1394
|
-
<button type="button" class="header-toggle-btn" data-action="toggle-thinking" title="Toggle thinking (T)">Toggle thinking</button>
|
|
1395
|
-
<button type="button" class="header-toggle-btn" data-action="toggle-tools" title="Toggle tools (O)">Toggle tools</button>
|
|
1395
|
+
<button type="button" class="header-toggle-btn" data-action="toggle-thinking" aria-pressed="${thinkingExpanded}" title="Toggle thinking (T)">Toggle thinking</button>
|
|
1396
|
+
<button type="button" class="header-toggle-btn" data-action="toggle-tools" aria-pressed="${toolOutputsExpanded}" title="Toggle tools (O)">Toggle tools</button>
|
|
1397
|
+
<button type="button" class="header-toggle-btn" data-action="toggle-hidden-messages" aria-pressed="${showHiddenMessages}" title="Show custom messages marked as hidden in the terminal (H).">${showHiddenMessages ? 'Hide hidden messages' : 'Show hidden messages'}</button>
|
|
1396
1398
|
<button type="button" class="download-json-btn" onclick="downloadSessionJson()" title="Download session as JSONL">↓ JSONL</button>
|
|
1397
1399
|
</div>
|
|
1398
1400
|
</div>
|
|
@@ -1500,6 +1502,10 @@
|
|
|
1500
1502
|
function navigateTo(targetId, scrollMode = 'target', scrollToEntryId = null) {
|
|
1501
1503
|
currentLeafId = targetId;
|
|
1502
1504
|
currentTargetId = scrollToEntryId || targetId;
|
|
1505
|
+
const targetEntry = byId.get(currentTargetId);
|
|
1506
|
+
if (scrollMode === 'target' && targetEntry?.type === 'custom_message' && targetEntry.display === false) {
|
|
1507
|
+
setHiddenMessagesVisible(true);
|
|
1508
|
+
}
|
|
1503
1509
|
const path = getPath(targetId);
|
|
1504
1510
|
|
|
1505
1511
|
renderTree();
|
|
@@ -1521,6 +1527,10 @@
|
|
|
1521
1527
|
messagesEl.innerHTML = '';
|
|
1522
1528
|
messagesEl.appendChild(fragment);
|
|
1523
1529
|
|
|
1530
|
+
// Cached nodes contain their initial presentation; reapply the viewer's toggle states.
|
|
1531
|
+
setThinkingExpanded(thinkingExpanded);
|
|
1532
|
+
setToolOutputsExpanded(toolOutputsExpanded);
|
|
1533
|
+
|
|
1524
1534
|
// Attach click handlers for copy-link buttons
|
|
1525
1535
|
messagesEl.querySelectorAll('.copy-link-btn').forEach(btn => {
|
|
1526
1536
|
btn.addEventListener('click', (e) => {
|
|
@@ -1793,19 +1803,32 @@
|
|
|
1793
1803
|
// Toggle states
|
|
1794
1804
|
let thinkingExpanded = true;
|
|
1795
1805
|
let toolOutputsExpanded = false;
|
|
1806
|
+
let showHiddenMessages = false;
|
|
1807
|
+
|
|
1808
|
+
function setHiddenMessagesVisible(visible) {
|
|
1809
|
+
showHiddenMessages = visible;
|
|
1810
|
+
document.body.classList.toggle('show-hidden-messages', visible);
|
|
1811
|
+
const button = document.querySelector('[data-action="toggle-hidden-messages"]');
|
|
1812
|
+
if (button) {
|
|
1813
|
+
button.setAttribute('aria-pressed', String(visible));
|
|
1814
|
+
button.textContent = visible ? 'Hide hidden messages' : 'Show hidden messages';
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1796
1817
|
|
|
1797
|
-
|
|
1798
|
-
thinkingExpanded =
|
|
1818
|
+
function setThinkingExpanded(expanded) {
|
|
1819
|
+
thinkingExpanded = expanded;
|
|
1820
|
+
document.querySelector('[data-action="toggle-thinking"]')?.setAttribute('aria-pressed', String(expanded));
|
|
1799
1821
|
document.querySelectorAll('.thinking-text').forEach(el => {
|
|
1800
1822
|
el.style.display = thinkingExpanded ? '' : 'none';
|
|
1801
1823
|
});
|
|
1802
1824
|
document.querySelectorAll('.thinking-collapsed').forEach(el => {
|
|
1803
1825
|
el.style.display = thinkingExpanded ? 'none' : 'block';
|
|
1804
1826
|
});
|
|
1805
|
-
}
|
|
1827
|
+
}
|
|
1806
1828
|
|
|
1807
|
-
|
|
1808
|
-
toolOutputsExpanded =
|
|
1829
|
+
function setToolOutputsExpanded(expanded) {
|
|
1830
|
+
toolOutputsExpanded = expanded;
|
|
1831
|
+
document.querySelector('[data-action="toggle-tools"]')?.setAttribute('aria-pressed', String(expanded));
|
|
1809
1832
|
document.querySelectorAll('.tool-output.expandable').forEach(el => {
|
|
1810
1833
|
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
1811
1834
|
});
|
|
@@ -1815,11 +1838,18 @@
|
|
|
1815
1838
|
document.querySelectorAll('.skill-invocation').forEach(el => {
|
|
1816
1839
|
el.classList.toggle('expanded', toolOutputsExpanded);
|
|
1817
1840
|
});
|
|
1818
|
-
}
|
|
1841
|
+
}
|
|
1819
1842
|
|
|
1820
1843
|
const attachHeaderHandlers = () => {
|
|
1821
|
-
document.querySelector('[data-action="toggle-thinking"]')?.addEventListener('click',
|
|
1822
|
-
|
|
1844
|
+
document.querySelector('[data-action="toggle-thinking"]')?.addEventListener('click', () => {
|
|
1845
|
+
setThinkingExpanded(!thinkingExpanded);
|
|
1846
|
+
});
|
|
1847
|
+
document.querySelector('[data-action="toggle-tools"]')?.addEventListener('click', () => {
|
|
1848
|
+
setToolOutputsExpanded(!toolOutputsExpanded);
|
|
1849
|
+
});
|
|
1850
|
+
document.querySelector('[data-action="toggle-hidden-messages"]')?.addEventListener('click', () => {
|
|
1851
|
+
setHiddenMessagesVisible(!showHiddenMessages);
|
|
1852
|
+
});
|
|
1823
1853
|
};
|
|
1824
1854
|
|
|
1825
1855
|
const isEditableTarget = (element) => {
|
|
@@ -1839,17 +1869,20 @@
|
|
|
1839
1869
|
navigateTo(leafId, 'bottom');
|
|
1840
1870
|
}
|
|
1841
1871
|
|
|
1842
|
-
if (isEditableTarget(document.activeElement)) {
|
|
1872
|
+
if (e.ctrlKey || e.metaKey || e.altKey || isEditableTarget(document.activeElement)) {
|
|
1843
1873
|
return;
|
|
1844
1874
|
}
|
|
1845
1875
|
|
|
1846
1876
|
const key = e.key.toLowerCase();
|
|
1847
1877
|
if (key === 't') {
|
|
1848
1878
|
e.preventDefault();
|
|
1849
|
-
|
|
1879
|
+
setThinkingExpanded(!thinkingExpanded);
|
|
1850
1880
|
} else if (key === 'o') {
|
|
1851
1881
|
e.preventDefault();
|
|
1852
|
-
|
|
1882
|
+
setToolOutputsExpanded(!toolOutputsExpanded);
|
|
1883
|
+
} else if (key === 'h') {
|
|
1884
|
+
e.preventDefault();
|
|
1885
|
+
setHiddenMessagesVisible(!showHiddenMessages);
|
|
1853
1886
|
}
|
|
1854
1887
|
});
|
|
1855
1888
|
|
package/bin/knightcode
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/bin/knightcode
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 80044368 bytes
|
|
4
|
+
sha256: 0adea2003ebba3c8d3fb42f75c4506c8a143fa9fb5c4c8c240982b40138690c5
|
package/bin/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knightcodeai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "KnightCode — a local, BYOK terminal coding agent powered by OpenRouter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"test": "vitest --run"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@knightcodeai/cli-linux-x64": "0.
|
|
41
|
-
"@knightcodeai/cli-linux-arm64": "0.
|
|
42
|
-
"@knightcodeai/cli-darwin-x64": "0.
|
|
43
|
-
"@knightcodeai/cli-darwin-arm64": "0.
|
|
44
|
-
"@knightcodeai/cli-win32-x64": "0.
|
|
40
|
+
"@knightcodeai/cli-linux-x64": "0.10.0",
|
|
41
|
+
"@knightcodeai/cli-linux-arm64": "0.10.0",
|
|
42
|
+
"@knightcodeai/cli-darwin-x64": "0.10.0",
|
|
43
|
+
"@knightcodeai/cli-darwin-arm64": "0.10.0",
|
|
44
|
+
"@knightcodeai/cli-win32-x64": "0.10.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@agentclientprotocol/sdk": "1.4.0",
|
package/bin/theme/dark.json
CHANGED
|
@@ -1,91 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/KnightCodeAI/knightcode/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "dark",
|
|
4
|
+
"appearance": "dark",
|
|
4
5
|
"vars": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
6
|
+
"text": "okhsl(234 3% 89%)",
|
|
7
|
+
"muted": "okhsl(229 6% 67%)",
|
|
8
|
+
"violet": "okhsl(295 50% 67%)",
|
|
9
|
+
"blue": "okhsl(232 54% 67%)",
|
|
7
10
|
"green": "#57ab5a",
|
|
8
11
|
"red": "#e5534b",
|
|
9
|
-
"yellow": "
|
|
10
|
-
"
|
|
11
|
-
"gray": "#808080",
|
|
12
|
-
"dimGray": "#666666",
|
|
13
|
-
"darkGray": "#505050",
|
|
14
|
-
"accent": "#8abeb7",
|
|
15
|
-
"selectedBg": "#3a3a4a",
|
|
16
|
-
"userMsgBg": "#343541",
|
|
17
|
-
"toolPendingBg": "#282832",
|
|
18
|
-
"toolSuccessBg": "#283228",
|
|
19
|
-
"toolErrorBg": "#3c2828",
|
|
20
|
-
"customMsgBg": "#2d2838"
|
|
12
|
+
"yellow": "okhsl(83 88% 67%)",
|
|
13
|
+
"blueBg": "okhsl(233 41% 24%)"
|
|
21
14
|
},
|
|
22
15
|
"colors": {
|
|
23
|
-
"accent": "
|
|
24
|
-
"border": "
|
|
25
|
-
"borderAccent": "
|
|
26
|
-
"borderMuted": "
|
|
16
|
+
"accent": "violet",
|
|
17
|
+
"border": "okhsl(231 57% 65%)",
|
|
18
|
+
"borderAccent": "okhsl(295 53% 64%)",
|
|
19
|
+
"borderMuted": "okhsl(229 8% 53%)",
|
|
27
20
|
"success": "green",
|
|
28
21
|
"error": "red",
|
|
29
22
|
"warning": "yellow",
|
|
30
|
-
"muted": "
|
|
31
|
-
"dim": "
|
|
23
|
+
"muted": "muted",
|
|
24
|
+
"dim": "okhsl(229 8% 56%)",
|
|
32
25
|
"text": "text",
|
|
33
|
-
"thinkingText": "
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"userMessageBg": "userMsgBg",
|
|
26
|
+
"thinkingText": "okhsl(226 7% 65%)",
|
|
27
|
+
"selectedBg": "blueBg",
|
|
28
|
+
"scrollbarTrack": "okhsl(237 7% 33%)",
|
|
29
|
+
"scrollbarThumb": "okhsl(232 7% 65%)",
|
|
30
|
+
"searchMatchBg": "okhsl(53 51% 24%)",
|
|
31
|
+
"searchMatchText": "muted",
|
|
32
|
+
"userMessageBg": "blueBg",
|
|
41
33
|
"userMessageText": "text",
|
|
42
|
-
"customMessageBg": "
|
|
43
|
-
"customMessageText": "
|
|
44
|
-
"customMessageLabel": "
|
|
45
|
-
"toolPendingBg": "
|
|
46
|
-
"toolSuccessBg": "
|
|
47
|
-
"toolErrorBg": "
|
|
34
|
+
"customMessageBg": "okhsl(295 42% 24%)",
|
|
35
|
+
"customMessageText": "muted",
|
|
36
|
+
"customMessageLabel": "violet",
|
|
37
|
+
"toolPendingBg": "okhsl(229 5% 24%)",
|
|
38
|
+
"toolSuccessBg": "okhsl(158 46% 25%)",
|
|
39
|
+
"toolErrorBg": "okhsl(19 54% 25%)",
|
|
48
40
|
"toolTitle": "text",
|
|
49
|
-
"toolOutput": "
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"mdCode": "accent",
|
|
41
|
+
"toolOutput": "muted",
|
|
42
|
+
"mdHeading": "yellow",
|
|
43
|
+
"mdLink": "blue",
|
|
44
|
+
"mdLinkUrl": "muted",
|
|
45
|
+
"mdCode": "violet",
|
|
55
46
|
"mdCodeBlock": "green",
|
|
56
|
-
"mdCodeBlockBorder": "
|
|
57
|
-
"mdQuote": "
|
|
58
|
-
"mdQuoteBorder": "
|
|
59
|
-
"mdHr": "
|
|
60
|
-
"mdListBullet": "
|
|
61
|
-
|
|
47
|
+
"mdCodeBlockBorder": "muted",
|
|
48
|
+
"mdQuote": "muted",
|
|
49
|
+
"mdQuoteBorder": "muted",
|
|
50
|
+
"mdHr": "muted",
|
|
51
|
+
"mdListBullet": "violet",
|
|
62
52
|
"toolDiffAdded": "green",
|
|
63
53
|
"toolDiffRemoved": "red",
|
|
64
|
-
"toolDiffContext": "
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"thinkingMax": "#ff5fff",
|
|
83
|
-
|
|
84
|
-
"bashMode": "green"
|
|
54
|
+
"toolDiffContext": "muted",
|
|
55
|
+
"syntaxComment": "muted",
|
|
56
|
+
"syntaxKeyword": "blue",
|
|
57
|
+
"syntaxFunction": "yellow",
|
|
58
|
+
"syntaxVariable": "okhsl(202 58% 67%)",
|
|
59
|
+
"syntaxString": "okhsl(52 67% 67%)",
|
|
60
|
+
"syntaxNumber": "green",
|
|
61
|
+
"syntaxType": "violet",
|
|
62
|
+
"syntaxOperator": "muted",
|
|
63
|
+
"syntaxPunctuation": "muted",
|
|
64
|
+
"thinkingOff": "okhsl(229 8% 49%)",
|
|
65
|
+
"thinkingMinimal": "okhsl(232 20% 52%)",
|
|
66
|
+
"thinkingLow": "okhsl(232 45% 54%)",
|
|
67
|
+
"thinkingMedium": "okhsl(263 59% 56%)",
|
|
68
|
+
"thinkingHigh": "okhsl(295 73% 59%)",
|
|
69
|
+
"thinkingXhigh": "okhsl(337 81% 61%)",
|
|
70
|
+
"thinkingMax": "okhsl(20 99% 63%)",
|
|
71
|
+
"bashMode": "okhsl(159 64% 65%)"
|
|
85
72
|
},
|
|
86
73
|
"export": {
|
|
87
|
-
"pageBg": "
|
|
88
|
-
"cardBg": "
|
|
89
|
-
"infoBg": "
|
|
74
|
+
"pageBg": "okhsl(262 14% 16%)",
|
|
75
|
+
"cardBg": "okhsl(264 13% 19%)",
|
|
76
|
+
"infoBg": "okhsl(53 51% 24%)"
|
|
90
77
|
}
|
|
91
78
|
}
|
package/bin/theme/light.json
CHANGED
|
@@ -1,90 +1,78 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://raw.githubusercontent.com/KnightCodeAI/knightcode/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "light",
|
|
4
|
+
"appearance": "light",
|
|
4
5
|
"vars": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"lightGray": "#b0b0b0",
|
|
14
|
-
"selectedBg": "#d0d0e0",
|
|
15
|
-
"userMsgBg": "#e8e8e8",
|
|
16
|
-
"toolPendingBg": "#e8e8f0",
|
|
17
|
-
"toolSuccessBg": "#e8f0e8",
|
|
18
|
-
"toolErrorBg": "#f0e8e8",
|
|
19
|
-
"customMsgBg": "#ede7f6"
|
|
6
|
+
"text": "okhsl(225 5% 27%)",
|
|
7
|
+
"muted": "okhsl(229 8% 47%)",
|
|
8
|
+
"violet": "okhsl(295 60% 46%)",
|
|
9
|
+
"blue": "okhsl(231 68% 47%)",
|
|
10
|
+
"green": "okhsl(159 75% 46%)",
|
|
11
|
+
"red": "okhsl(20 91% 47%)",
|
|
12
|
+
"yellow": "okhsl(83 99% 47%)",
|
|
13
|
+
"blueBg": "okhsl(235 19% 91%)"
|
|
20
14
|
},
|
|
21
15
|
"colors": {
|
|
22
|
-
"accent": "
|
|
23
|
-
"border": "
|
|
24
|
-
"borderAccent": "
|
|
25
|
-
"borderMuted": "
|
|
16
|
+
"accent": "violet",
|
|
17
|
+
"border": "okhsl(231 67% 55%)",
|
|
18
|
+
"borderAccent": "okhsl(295 59% 55%)",
|
|
19
|
+
"borderMuted": "okhsl(235 7% 66%)",
|
|
26
20
|
"success": "green",
|
|
27
21
|
"error": "red",
|
|
28
22
|
"warning": "yellow",
|
|
29
|
-
"muted": "
|
|
30
|
-
"dim": "
|
|
23
|
+
"muted": "muted",
|
|
24
|
+
"dim": "okhsl(229 7% 59%)",
|
|
31
25
|
"text": "text",
|
|
32
|
-
"thinkingText": "
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"userMessageBg": "userMsgBg",
|
|
26
|
+
"thinkingText": "okhsl(234 8% 55%)",
|
|
27
|
+
"selectedBg": "blueBg",
|
|
28
|
+
"scrollbarTrack": "okhsl(248 3% 90%)",
|
|
29
|
+
"scrollbarThumb": "okhsl(226 7% 65%)",
|
|
30
|
+
"searchMatchBg": "okhsl(56 22% 91%)",
|
|
31
|
+
"searchMatchText": "muted",
|
|
32
|
+
"userMessageBg": "blueBg",
|
|
40
33
|
"userMessageText": "text",
|
|
41
|
-
"customMessageBg": "
|
|
42
|
-
"customMessageText": "
|
|
43
|
-
"customMessageLabel": "
|
|
44
|
-
"toolPendingBg": "
|
|
45
|
-
"toolSuccessBg": "
|
|
46
|
-
"toolErrorBg": "
|
|
34
|
+
"customMessageBg": "okhsl(295 25% 91%)",
|
|
35
|
+
"customMessageText": "muted",
|
|
36
|
+
"customMessageLabel": "violet",
|
|
37
|
+
"toolPendingBg": "okhsl(248 3% 91%)",
|
|
38
|
+
"toolSuccessBg": "okhsl(156 21% 91%)",
|
|
39
|
+
"toolErrorBg": "okhsl(24 23% 91%)",
|
|
47
40
|
"toolTitle": "text",
|
|
48
|
-
"toolOutput": "
|
|
49
|
-
|
|
41
|
+
"toolOutput": "muted",
|
|
50
42
|
"mdHeading": "yellow",
|
|
51
43
|
"mdLink": "blue",
|
|
52
|
-
"mdLinkUrl": "
|
|
53
|
-
"mdCode": "
|
|
44
|
+
"mdLinkUrl": "muted",
|
|
45
|
+
"mdCode": "violet",
|
|
54
46
|
"mdCodeBlock": "green",
|
|
55
|
-
"mdCodeBlockBorder": "
|
|
56
|
-
"mdQuote": "
|
|
57
|
-
"mdQuoteBorder": "
|
|
58
|
-
"mdHr": "
|
|
59
|
-
"mdListBullet": "
|
|
60
|
-
|
|
47
|
+
"mdCodeBlockBorder": "muted",
|
|
48
|
+
"mdQuote": "muted",
|
|
49
|
+
"mdQuoteBorder": "muted",
|
|
50
|
+
"mdHr": "muted",
|
|
51
|
+
"mdListBullet": "violet",
|
|
61
52
|
"toolDiffAdded": "green",
|
|
62
53
|
"toolDiffRemoved": "red",
|
|
63
|
-
"toolDiffContext": "
|
|
64
|
-
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"thinkingMax": "#af005f",
|
|
82
|
-
|
|
83
|
-
"bashMode": "green"
|
|
54
|
+
"toolDiffContext": "muted",
|
|
55
|
+
"syntaxComment": "muted",
|
|
56
|
+
"syntaxKeyword": "blue",
|
|
57
|
+
"syntaxFunction": "yellow",
|
|
58
|
+
"syntaxVariable": "okhsl(203 73% 46%)",
|
|
59
|
+
"syntaxString": "okhsl(52 84% 46%)",
|
|
60
|
+
"syntaxNumber": "green",
|
|
61
|
+
"syntaxType": "violet",
|
|
62
|
+
"syntaxOperator": "muted",
|
|
63
|
+
"syntaxPunctuation": "muted",
|
|
64
|
+
"thinkingOff": "okhsl(223 5% 80%)",
|
|
65
|
+
"thinkingMinimal": "okhsl(229 14% 78%)",
|
|
66
|
+
"thinkingLow": "okhsl(232 33% 76%)",
|
|
67
|
+
"thinkingMedium": "okhsl(264 48% 74%)",
|
|
68
|
+
"thinkingHigh": "okhsl(295 62% 72%)",
|
|
69
|
+
"thinkingXhigh": "okhsl(337 74% 70%)",
|
|
70
|
+
"thinkingMax": "okhsl(20 98% 68%)",
|
|
71
|
+
"bashMode": "okhsl(159 74% 55%)"
|
|
84
72
|
},
|
|
85
73
|
"export": {
|
|
86
|
-
"pageBg": "
|
|
87
|
-
"cardBg": "
|
|
88
|
-
"infoBg": "
|
|
74
|
+
"pageBg": "okhsl(17 3% 94%)",
|
|
75
|
+
"cardBg": "okhsl(17 5% 97%)",
|
|
76
|
+
"infoBg": "okhsl(56 22% 91%)"
|
|
89
77
|
}
|
|
90
78
|
}
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
"pattern": "^[^/]+$",
|
|
15
15
|
"description": "Theme name. Must not contain '/' because it is reserved for automatic light/dark theme settings."
|
|
16
16
|
},
|
|
17
|
+
"appearance": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"enum": ["dark", "light"],
|
|
20
|
+
"description": "Background the theme is designed for. Detected from the theme colors when omitted."
|
|
21
|
+
},
|
|
17
22
|
"vars": {
|
|
18
23
|
"type": "object",
|
|
19
24
|
"description": "Reusable color variables",
|
|
@@ -21,7 +26,7 @@
|
|
|
21
26
|
"oneOf": [
|
|
22
27
|
{
|
|
23
28
|
"type": "string",
|
|
24
|
-
"description": "Hex color (#RRGGBB), variable reference, or empty string for terminal default"
|
|
29
|
+
"description": "Hex color (#RGB or #RRGGBB), OKLCH or OKHSL color, variable reference, or empty string for terminal default"
|
|
25
30
|
},
|
|
26
31
|
{
|
|
27
32
|
"type": "integer",
|
|
@@ -342,7 +347,7 @@
|
|
|
342
347
|
"oneOf": [
|
|
343
348
|
{
|
|
344
349
|
"type": "string",
|
|
345
|
-
"description": "Hex color (#RRGGBB), variable reference, or empty string for terminal default"
|
|
350
|
+
"description": "Hex color (#RGB or #RRGGBB), OKLCH or OKHSL color, variable reference, or empty string for terminal default"
|
|
346
351
|
},
|
|
347
352
|
{
|
|
348
353
|
"type": "integer",
|