@knightcodeai/cli-linux-x64 0.11.0 → 0.11.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 +62 -0
- package/bin/docs/cli.md +64 -3
- package/bin/docs/configuration.md +2 -0
- package/bin/docs/docs.json +4 -0
- package/bin/docs/extensions.md +48 -0
- package/bin/docs/llama-cpp.md +3 -1
- package/bin/docs/mcp.md +229 -0
- package/bin/docs/models.md +35 -0
- package/bin/docs/packages.md +1 -1
- package/bin/docs/providers.md +1 -0
- package/bin/docs/sdk.md +6 -1
- package/bin/docs/security.md +2 -0
- package/bin/docs/settings.md +19 -2
- package/bin/docs/windows.md +2 -0
- package/bin/export-html/template.js +16 -0
- package/bin/knightcode +2 -2
- package/bin/package.json +9 -6
- package/package.json +1 -1
package/bin/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# @knightcodeai/cli
|
|
2
2
|
|
|
3
|
+
## 0.11.2
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Added an `oauth.clientName` setting for MCP servers (`knightcode mcp add --oauth-client-name`) to change the client name sent during OAuth client registration, for servers such as Figma that only accept known clients.
|
|
8
|
+
|
|
9
|
+
- Added a `description` field for MCP servers (`knightcode mcp add --description`), shown next to the server in the `codemode` and `tool_search` descriptions, and a `describeNamespace(name)` codemode helper that returns a namespace's instructions and tool names.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Changed the `codemode` description to list MCP servers instead of their tools, so it no longer changes when a server's tool list changes. Scripts find tools with `searchTools()` and read server instructions with `describeNamespace()`; `codemode-deferred` is now an alias for `codemode`, and `direct` exposure keeps tools visible to the model.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Fixed codemode `image()` accepting malformed base64 data or unsupported image types, which stored an invalid image block that made every later provider request fail with HTTP 400. It now throws a `TypeError` unless the data is valid base64 of a PNG, JPEG, GIF, or WebP image, takes the MIME type from the image signature, and strips line breaks from wrapped base64.
|
|
18
|
+
|
|
19
|
+
- Fixed codemode failing to start its script worker from the standalone Windows executable.
|
|
20
|
+
|
|
21
|
+
- Fixed the `/mcp` sign-in URL not being clickable when it wraps across lines. It is now a terminal hyperlink with a `Cmd/Ctrl+click to open` line, like `/login`.
|
|
22
|
+
|
|
23
|
+
- Fixed new sessions intermittently ignoring the saved default model, or warning that no models are available, when it belongs to an extension-registered native provider with a stored credential.
|
|
24
|
+
|
|
25
|
+
- Fixed context overflow errors from the Z.AI China endpoint ("Prompt exceeds max length") not being recognised, so compaction and retry now trigger for them as they do for the global endpoint.
|
|
26
|
+
|
|
27
|
+
## 0.11.1
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Added the `codemode` tool, which runs JavaScript in a sandbox whose only capability is calling tools, including MCP tools that are not declared to the model.
|
|
32
|
+
|
|
33
|
+
- Added the `tool_search` tool so the model can find tools that are not declared yet and declare the matches on its next call.
|
|
34
|
+
|
|
35
|
+
- Added Sign in with ChatGPT for the OpenAI provider. Provider sign-in flows share one local callback server, and the browser page still shows the KnightCode knight.
|
|
36
|
+
|
|
37
|
+
- Added MCP servers, configured in `mcp.json` and managed with `knightcode mcp` and `/mcp`, including OAuth sign-in for HTTP servers.
|
|
38
|
+
|
|
39
|
+
- Added GPT-6.1 Sol (`gpt-6.1-sol`) for OpenAI, Azure OpenAI Responses, and OpenAI Codex, and made it the OpenAI Codex default model.
|
|
40
|
+
|
|
41
|
+
- Added Jev classifier models on Vercel AI Gateway (`typesafe-ai/jev`) and OpenCode (`jev-1.13` and `jev-1.13-free`).
|
|
42
|
+
|
|
43
|
+
- Added the `fullscreenWheelScrollLines` setting so fullscreen mode can scroll one line per wheel event, a fixed number of lines, or speed up fast spins. Alt+wheel moves five times as far.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Changed `defaultTools` so a list of `+name` and `-name` entries adds or removes tools instead of replacing the whole selection.
|
|
48
|
+
|
|
49
|
+
- Changed built-in extensions so `knightcode config` lists them as `builtin:<name>` and settings can disable one with `-builtin:<name>`.
|
|
50
|
+
|
|
51
|
+
- Changed tool calls that have no custom renderer to show their arguments, collapsed on one line until the call is expanded.
|
|
52
|
+
|
|
53
|
+
- Changed session cost to include token usage from codemode classifier calls and from tools those scripts call.
|
|
54
|
+
|
|
55
|
+
- Changed bash results returned to scripts so they keep up to 1 MiB of output, with the full output in `full_output_path` when that is still not enough.
|
|
56
|
+
|
|
57
|
+
- Changed System One classifier results to include token usage and its catalog cost when the service reports token counts.
|
|
58
|
+
|
|
59
|
+
- Changed fullscreen redraws to keep parsed markdown and unpadded child lines across frames, and shell output now drops only control characters and interlinear annotations instead of every format character.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- Fixed llama.cpp context windows so a reload keeps the last known size when the server has not reported one, and a configured `--ctx-size` is used before the training context.
|
|
64
|
+
|
|
3
65
|
## 0.11.0
|
|
4
66
|
|
|
5
67
|
### Added
|
package/bin/docs/cli.md
CHANGED
|
@@ -13,6 +13,7 @@ knightcode update [target] [options]
|
|
|
13
13
|
knightcode list
|
|
14
14
|
knightcode config [options]
|
|
15
15
|
knightcode auth <check|print-api-key|print-bearer-token> [options]
|
|
16
|
+
knightcode mcp <list|login|logout> [options]
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
<a id="modes"></a>
|
|
@@ -124,7 +125,7 @@ See [Settings](settings.md#tools) for configuring the default tool selection.
|
|
|
124
125
|
- `-nt`, `--no-tools`<br>
|
|
125
126
|
Starts with all built-in, extension, and custom tools disabled.
|
|
126
127
|
|
|
127
|
-
Default enabled tools are `read`, `bash`, `edit`, and `write`, unless `defaultTools` changes them.
|
|
128
|
+
Default enabled tools are `read`, `bash`, `edit`, and `write`, unless `defaultTools` changes them. `--tools` replaces the whole selection, so name every tool you want; `defaultTools` also accepts `+name` and `-name` to change the defaults instead.
|
|
128
129
|
|
|
129
130
|
| Built-in | Purpose |
|
|
130
131
|
|---|---|
|
|
@@ -139,6 +140,49 @@ Default enabled tools are `read`, `bash`, `edit`, and `write`, unless `defaultTo
|
|
|
139
140
|
|
|
140
141
|
The [web tools](usage.md#web-tools) `webfetch` and `websearch` are off until enabled with `/tools`. A tool excluded here stays off whatever `/tools` says.
|
|
141
142
|
|
|
143
|
+
Built-in extensions add two more tools. They are off by default; the MCP extension turns them on when an MCP server needs them (see [MCP](mcp.md#exposure)). To enable them yourself, name them in `--tools` or `defaultTools`.
|
|
144
|
+
|
|
145
|
+
| Built-in extension | Purpose |
|
|
146
|
+
|---|---|
|
|
147
|
+
| `codemode` | Run JavaScript that calls the other tools, for example in parallel with `Promise.allSettled`; only the script's output reaches the model |
|
|
148
|
+
| `tool_search` | Search tools that are not declared to the model (`codemode` and `deferred` exposure, such as MCP tools) and declare the matches for the next call |
|
|
149
|
+
|
|
150
|
+
### Enable codemode
|
|
151
|
+
|
|
152
|
+
To turn on `codemode` for every session, add it to the default tools in `~/.knightcode/agent/settings.json` or a project's `.knightcode/settings.json`:
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"defaultTools": ["+codemode"]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This keeps `read`, `bash`, `edit`, and `write` and adds `codemode`. For one invocation, list every tool, since `--tools` replaces the selection:
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
knightcode --tools read,bash,edit,write,codemode
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Codemode is useful without MCP: scripts can run several tool calls in parallel, filter large output before it reaches the model, and call classifier models such as TypeSafe's Jev through `models.classify()` (see [Classifier models](models.md#use-classifier-models)).
|
|
167
|
+
|
|
168
|
+
### How codemode works
|
|
169
|
+
|
|
170
|
+
Codemode scripts run in a QuickJS sandbox that can only reach the other tools, through `tools.<name>(args)`; `ALL_TOOLS` lists them. Output comes from `text(value)`, `image(dataUrlOrImageContent)`, `console.*`, and a top-level `return value`; `exit()` ends the script early. The result starts with `Script completed` or `Script failed`, the wall time, and the output; a failed script keeps its partial output, followed by `Script error:` and the error.
|
|
171
|
+
|
|
172
|
+
A script may start with an options line such as `// @options: {"max_output_tokens": 2000, "timeout_ms": 60000}`. `max_output_tokens` (default 10000) limits the output: longer output keeps its start and end, and the full text is written to a temp file whose path is included in the result. `timeout_ms` is a hard deadline, unset by default.
|
|
173
|
+
|
|
174
|
+
While `codemode` is active, `codemode.mode` in [settings](settings.md#tools) decides how the other tools are presented. With `on` (default) declared tools keep being declared and their descriptions show how to call them from scripts. With `only` they are hidden from the model and listed in the `codemode` description instead, so the model calls them through scripts.
|
|
175
|
+
|
|
176
|
+
The `codemode` description lists the callable tools with their TypeScript declarations, grouped by namespace (for example one MCP server). Tools with `deferred` exposure, which includes MCP tools with the default `codemode` exposure, are not listed; their namespace is listed with its description. Declarations share a budget of 3000 estimated tokens (`codemode.inlineBudget` in [settings](settings.md#tools)), and the description says whether the list is complete. Scripts find the rest with `await searchTools(query, { limit, namespace })`, which ranks tools with BM25, and `await describeTool(name)`, or by filtering `ALL_TOOLS`. `await describeNamespace(name)` returns a namespace's description, its instructions (for MCP servers, the server instructions), and the names of its tools.
|
|
177
|
+
|
|
178
|
+
Tools with an output schema resolve to structured values: `bash` to `{ output, truncated, full_output_path?, exit_code, wall_time_seconds }`, also for non-zero exit codes, and MCP tools to their `CallToolResult`. Other tools resolve to their text output. The `output` of `bash` is not limited to the 2000 lines or 50KB the model sees: it holds up to 1 MiB, and longer output keeps its first and last 512 KiB around an omission marker, with `truncated` set and the full output in `full_output_path`.
|
|
179
|
+
|
|
180
|
+
`store(key, value)` and `load(key)` keep JSON values across `codemode` calls: each successful script that stores values appends a `codemode-store` custom entry to the session, so resumed sessions keep the values and each branch sees only the values written on its path. Scripts can also use `models`: `getModelsOfType`, `getAvailableOfType`, and `getModelOfType` list the model catalog, and `classify(model, context)` runs a classifier model with the session's credentials, at most four at a time per script.
|
|
181
|
+
|
|
182
|
+
### Tool search
|
|
183
|
+
|
|
184
|
+
`tool_search` is off by default; enable it with `"defaultTools": ["+tool_search"]` or `--tools`. It uses the same ranking as `searchTools()` over tools that are not declared yet and declares the matches for the next model call. Loaded tools are recorded in the session like other tool changes, so they stay declared on that branch.
|
|
185
|
+
|
|
142
186
|
<a id="resource-options"></a>
|
|
143
187
|
|
|
144
188
|
## Resources
|
|
@@ -150,9 +194,9 @@ knightcode --extension ./review.ts
|
|
|
150
194
|
See [Configuration](configuration.md) for conventional directories and project trust, [Settings](settings.md#resources) for configured paths, and [KnightCode Packages](packages.md) for package sources.
|
|
151
195
|
|
|
152
196
|
- `-e`, `--extension <path>`<br>
|
|
153
|
-
Loads an extension file or directory and is repeatable.
|
|
197
|
+
Loads an extension file or directory, or a built-in extension such as `builtin:mcp`, and is repeatable.
|
|
154
198
|
- `-ne`, `--no-extensions`<br>
|
|
155
|
-
Disables discovered and
|
|
199
|
+
Disables discovered, configured, and built-in extensions. Explicit `-e` paths still load, so `knightcode -ne -e builtin:mcp` keeps only the built-in MCP support.
|
|
156
200
|
- `--skill <path>`<br>
|
|
157
201
|
Loads a skill file or directory and is repeatable.
|
|
158
202
|
- `-ns`, `--no-skills`<br>
|
|
@@ -268,3 +312,20 @@ Authentication commands require `--provider <provider>` or `--model <model>`. Se
|
|
|
268
312
|
| `--min-expiry <duration>` | `print-bearer-token` | Require remaining token lifetime using `ms`, `s`, `m`, or `h`, such as `30m` |
|
|
269
313
|
|
|
270
314
|
Credential-printing commands write secrets to stdout.
|
|
315
|
+
|
|
316
|
+
## MCP commands
|
|
317
|
+
|
|
318
|
+
These commands work outside a session, so agents can run them through `bash`. See [MCP Servers](mcp.md).
|
|
319
|
+
|
|
320
|
+
| Command | Description |
|
|
321
|
+
|---|---|
|
|
322
|
+
| `knightcode mcp add <server> [options] -- <command> [args...]` | Add or replace a stdio server in `mcp.json`; `--env KEY=VALUE` (repeatable) and `--cwd <dir>` set its environment and working directory. Arguments after the command are passed to it |
|
|
323
|
+
| `knightcode mcp add <server> [options] --url <url>` | Add or replace a streamable HTTP server; `--header KEY=VALUE` (repeatable), `--bearer-token-env-var <NAME>` (sends `Authorization: Bearer ${NAME}`), `--oauth-client-id`, `--oauth-client-secret`, `--oauth-callback-port`, and `--oauth-client-name` configure authentication |
|
|
324
|
+
| `knightcode mcp remove <server>` | Remove a server from `mcp.json`; stored OAuth credentials are kept |
|
|
325
|
+
| `knightcode mcp list [--json]` | Connect to every enabled server and print its state, tools, and errors; exit with `1` when a config entry is invalid or an enabled server is not connected |
|
|
326
|
+
| `knightcode mcp login <server> [--timeout <seconds>]` | Sign in to an OAuth server: open the authorization page and wait for the browser (default 300 seconds); a terminal also accepts the pasted redirect URL |
|
|
327
|
+
| `knightcode mcp logout <server>` | Delete the stored OAuth credentials of a server |
|
|
328
|
+
|
|
329
|
+
`add` and `remove` change `~/.knightcode/agent/mcp.json`, or `.knightcode/mcp.json` in the current directory with `--local` (`-l`). `add` also takes `--exposure <mode>` (see [Exposure](mcp.md#exposure)) and `--description <text>` and does not connect; run `knightcode mcp list` to check the server.
|
|
330
|
+
|
|
331
|
+
Project `.knightcode/mcp.json` files are only read for projects that are already trusted.
|
|
@@ -12,6 +12,7 @@ The agent directory is shown as `<agent-dir>` below. Set its location with the `
|
|
|
12
12
|
|---|---|
|
|
13
13
|
| `<agent-dir>/settings.json` | User-level [settings](settings.md), including preferences, defaults, resource paths, and KnightCode package declarations. |
|
|
14
14
|
| `<agent-dir>/keybindings.json` | Custom terminal UI and application [keybindings](keybindings.md). |
|
|
15
|
+
| `<agent-dir>/mcp.json` | [MCP servers](mcp.md) available in every project. |
|
|
15
16
|
| `<agent-dir>/models.json` | [Compatible endpoints, models, and model overrides](models.md#configure-a-compatible-endpoint). |
|
|
16
17
|
| `<agent-dir>/auth.json` | Saved API keys and OAuth credentials. |
|
|
17
18
|
| `<agent-dir>/tools.json` | [Web tool](usage.md#web-tools), scratchpad, and classifier gate settings written by `/tools`, including the Brave Search key. |
|
|
@@ -28,6 +29,7 @@ The agent directory is shown as `<agent-dir>` below. Set its location with the `
|
|
|
28
29
|
| Path | Responsibility |
|
|
29
30
|
|---|---|
|
|
30
31
|
| `.knightcode/settings.json` | Project-level [settings](settings.md), resource paths, and KnightCode package declarations. |
|
|
32
|
+
| `.knightcode/mcp.json` | Project [MCP servers](mcp.md). |
|
|
31
33
|
| `.knightcode/SYSTEM.md` | Replaces the system prompt for the project. |
|
|
32
34
|
| `.knightcode/APPEND_SYSTEM.md` | Adds project-specific instructions to the system prompt. |
|
|
33
35
|
| `.knightcode/extensions/` | Project extensions. |
|
package/bin/docs/docs.json
CHANGED
package/bin/docs/extensions.md
CHANGED
|
@@ -80,6 +80,7 @@ Automatic retries, recovery, compaction, or queued work can continue afterward.
|
|
|
80
80
|
| Persist non-context session data | `knightcode.appendEntry()` |
|
|
81
81
|
| Change active tools, model, or thinking level | Session control methods on `knightcode` |
|
|
82
82
|
| Add a model provider | `knightcode.registerProvider()` |
|
|
83
|
+
| Add an MCP server | `knightcode.registerMcpServer()` |
|
|
83
84
|
| Route each request to a model | [`knightcode.registerVirtualModel()`](virtual-models.md) |
|
|
84
85
|
| Add terminal rendering | Renderer registration and `ctx.ui` |
|
|
85
86
|
| Communicate with another extension | `knightcode.events` |
|
|
@@ -142,14 +143,61 @@ Use sequential execution when tools share mutable in-memory state.
|
|
|
142
143
|
File-mutating tools should wrap the complete read-modify-write operation with `withFileMutationQueue()`.
|
|
143
144
|
Truncate large model-facing results and tell the model where to read the complete output.
|
|
144
145
|
|
|
146
|
+
Declare `outputSchema` and return a matching `structuredContent` when the result is data. The model still receives `content`; programmatic callers such as codemode scripts receive `structuredContent` instead of the text. Tools without `outputSchema` are passed to scripts as their text content. To report a failure that still carries data, return the result with `isError: true` instead of throwing: the model sees an error, and scripts still receive `structuredContent`.
|
|
147
|
+
|
|
148
|
+
A tool can run other tools with `ctx.executeTool(name, args, { signal, onUpdate })`. Nested calls go through argument validation and the `tool_call` and `tool_result` handlers like model-issued calls, and emit `tool_execution_start`, `tool_execution_update`, and `tool_execution_end`; all of these events carry `parentToolCallId`, and their `toolCallId` is assigned by knightcode as `<parent id>/<n>`. These ids do not appear as tool calls or tool results in the transcript. Nested calls do not add transcript entries: their results only reach the calling tool, which reports them itself, for example through `onUpdate` and `details`. The session keeps a bounded record of them (name, arguments, status, duration, error; never results) as `nestedCalls` on the calling tool's result message. It is used for compaction file lists and shown in HTML exports. Arguments over 8 KiB per call or 32 KiB per tool result are omitted, at most 256 calls are kept, and `complete: false` marks a record that lost anything. The `usage` of nested results, at every depth, is added to the calling tool's result `usage`, so a tool reports only its own usage, not that of the tools it called. `ctx.tools` lists the tools `ctx.executeTool()` can call. `tool_result` handlers that redact `content` should also replace `structuredContent`; replacing only `content` drops it.
|
|
149
|
+
|
|
145
150
|
See [`hello.ts`](../examples/extensions/hello.ts), [`todo.ts`](../examples/extensions/todo.ts), [`dynamic-tools.ts`](../examples/extensions/dynamic-tools.ts), and [`truncated-tool.ts`](../examples/extensions/truncated-tool.ts).
|
|
146
151
|
|
|
152
|
+
### Tool exposure
|
|
153
|
+
|
|
154
|
+
`exposure` controls how the model reaches a tool. "Callable" means callable from other tools through `ctx.executeTool()` (`ctx.tools`), as the `codemode` tool's scripts do:
|
|
155
|
+
|
|
156
|
+
- `direct` (default): declared to the model while active, and callable while active.
|
|
157
|
+
- `model-only`: declared to the model while active, never callable. Use it for tools that orchestrate other tools or ask the user.
|
|
158
|
+
- `codemode`: callable whenever registered, and listed by the `codemode` tool. Not declared to the model unless activated explicitly.
|
|
159
|
+
- `deferred`: like `codemode`, but codemode tools do not list it; `tool_search` can find and activate it.
|
|
160
|
+
- `hidden`: registered but unreachable. Re-register a tool with `exposure: "hidden"` to withdraw it, since tools cannot be unregistered.
|
|
161
|
+
|
|
162
|
+
`namespace: { name, description, instructions }` groups related tools, as MCP servers do. Codemode tools list a namespace under one heading with its `description`. `instructions` holds longer usage guidance; it is not listed, and codemode scripts read it with `describeNamespace(name)`.
|
|
163
|
+
|
|
164
|
+
Registering a `direct` or `model-only` tool activates it; the other exposures are not activated on registration. The active set (`knightcode.getActiveTools()`, `knightcode.setActiveTools()`) is the set of tools declared to the model. `knightcode.getAllTools()` reports each tool's `exposure`, `namespace`, and `annotations`.
|
|
165
|
+
|
|
166
|
+
`annotations` are hints about what a tool does, with the meaning of MCP tool annotations: `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint`. MCP tools carry the hints their server declares. Missing hints take the MCP defaults: a tool is not read-only, and may be destructive and reach an open world. The hints are not verified, but a permission extension can use them to decide which calls to confirm. This confirms the calls Codex asks approval for:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
knightcode.on("tool_call", async (event, ctx) => {
|
|
170
|
+
const hints = knightcode.getAllTools().find((tool) => tool.name === event.toolName)?.annotations;
|
|
171
|
+
const needsApproval =
|
|
172
|
+
hints?.destructiveHint === true ||
|
|
173
|
+
(!hints?.readOnlyHint && ((hints?.destructiveHint ?? true) || (hints?.openWorldHint ?? true)));
|
|
174
|
+
if (needsApproval && !(await ctx.ui.confirm("Allow tool call?", event.toolName))) {
|
|
175
|
+
return { block: true, reason: `${event.toolName} was not approved` };
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
A tool that orchestrates other tools can adjust what the model sees while it is active with `prepareLoadout(loadout)`. It runs whenever the active tools change and receives the declared tools, the callable tools, and every registered tool with its exposure and namespace. It returns replacement `descriptions` for declared tools (including its own) and `hiddenDeclarations`: active tools whose declarations requests leave out while they stay active and callable. `codemode` and `tool_search` use only this hook, `exposure`, and `ctx.executeTool()`, so another tool can implement the same behavior under a different name.
|
|
181
|
+
|
|
147
182
|
### Activate tools dynamically
|
|
148
183
|
|
|
149
184
|
Register every tool first, keep optional tools inactive, and use `knightcode.setActiveTools()` from a loader tool to select the desired active tools. Names must already be registered; unknown names are ignored.
|
|
150
185
|
|
|
151
186
|
KnightCode records the initial prompt and tool set in the transcript's first system message, then appends tool and prompt changes before the next model request. Providers that cannot represent the transition receive a complete transcript checkpoint, which can invalidate the cached prefix.
|
|
152
187
|
|
|
188
|
+
### MCP servers
|
|
189
|
+
|
|
190
|
+
`knightcode.registerMcpServer(name, config)` adds an MCP server for the current session. `config` has the shape of an `mcpServers` entry in [`mcp.json`](mcp.md): `command`, `args`, `env`, and `cwd` for stdio servers, `url`, `headers`, and `oauth` for HTTP servers, plus `exposure`, `toolExposure`, `description`, `enabled`, and `timeout`.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
knightcode.registerMcpServer("jira", { url: "https://mcp.example.com/jira", exposure: "codemode" });
|
|
194
|
+
knightcode.unregisterMcpServer("jira");
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Servers registered while the extension loads connect when the session starts, together with the `mcp.json` servers; servers registered later connect right away, and `knightcode.unregisterMcpServer()` closes the connection and makes the server's tools unreachable. Registrations are not saved: register again on every load, for example based on the extension's own settings. A server in `mcp.json` with the same name takes precedence, and `/mcp` shows the override. Registering the same name again replaces the extension's earlier registration; names registered by another extension, invalid names, and invalid configs throw.
|
|
198
|
+
|
|
199
|
+
The built-in MCP support connects registered servers. When nothing does, because another extension replaced it (see [MCP](mcp.md#other-mcp-extensions)), each registration is reported as an extension error. Other MCP extensions can connect registered servers too: read them with `knightcode.getMcpServers()` on `session_start` and handle the `mcp_servers_change` event for later changes.
|
|
200
|
+
|
|
153
201
|
<a id="extensioncontext"></a>
|
|
154
202
|
<a id="extensioncommandcontext"></a>
|
|
155
203
|
<a id="use-extension-context"></a>
|
package/bin/docs/llama-cpp.md
CHANGED
|
@@ -88,7 +88,7 @@ If the router disconnects, `/llama` shows **Retry** and **Close**. Retry reconne
|
|
|
88
88
|
|
|
89
89
|
## Classification
|
|
90
90
|
|
|
91
|
-
Every model listed for chat is also listed as a classifier model with the same ID and the `llama-cpp-classify` API. Classifier models answer typed `choice`, `bool`, and `score` questions about JSON state, like TypeSafe's Jev models.
|
|
91
|
+
Every model listed for chat is also listed as a classifier model with the same ID and the `llama-cpp-classify` API. Classifier models answer typed `choice`, `bool`, and `score` questions about JSON state, like TypeSafe's Jev models. The model reaches them from [`codemode`](cli.md#enable-codemode) scripts, and extensions through `ctx.modelRegistry.classify()`; see [Classifier models](models.md#use-classifier-models).
|
|
92
92
|
|
|
93
93
|
The model does not generate an answer. Each question becomes one chat prompt: the state, every question of the request, the state again, and then the question with its answers under single-token labels. Labels are letters for a choice (up to 62 options), `Yes`/`No` for a bool, and digits for a score (up to 10 levels). The second copy of the state is read with the questions in view, which improved accuracy on JevBench with small models. KnightCode reads the probabilities of the labels as the next token and normalizes them. A choice returns every option's probability and a confidence of `(n * peak - 1) / (n - 1)`; a score returns the expected level.
|
|
94
94
|
|
|
@@ -110,3 +110,5 @@ curl http://127.0.0.1:8080/models
|
|
|
110
110
|
- **Model missing from `/model` with `--no-models-autoload`:** Load it with `/llama` first.
|
|
111
111
|
- **Load fails or uses too much memory:** Lower `-c` or unload another model.
|
|
112
112
|
- **Server is not in router mode:** Start it without `--model`, `-m`, or `-hf`.
|
|
113
|
+
|
|
114
|
+
To remove the `llama.cpp` provider and `/llama`, disable `llama.cpp` under Built-in in `knightcode config`, or set `"extensions": ["-builtin:llama.cpp"]` in [settings](settings.md#resources).
|
package/bin/docs/mcp.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# MCP Servers
|
|
2
|
+
|
|
3
|
+
KnightCode connects to [Model Context Protocol](https://modelcontextprotocol.io) servers over stdio or streamable HTTP and makes their tools and resources available to the model.
|
|
4
|
+
|
|
5
|
+
## Quick setup
|
|
6
|
+
|
|
7
|
+
Add a local stdio server, check the connection, then start KnightCode:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
knightcode mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem .
|
|
11
|
+
knightcode mcp list
|
|
12
|
+
knightcode
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For a remote server:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
knightcode mcp add docs --url https://example.com/mcp --bearer-token-env-var DOCS_TOKEN
|
|
19
|
+
knightcode mcp list
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
These commands add user-level servers by default. Add `--local` or `-l` to write the project configuration instead:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
knightcode mcp add -l tools --env API_KEY='${TOOLS_KEY}' -- uvx tools-mcp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Use `/mcp` inside an interactive session to inspect connections, sign in, reconnect, change exposure, or enable and disable servers. Run `/reload` after adding, removing, or changing a server outside the session.
|
|
29
|
+
|
|
30
|
+
## Configure servers
|
|
31
|
+
|
|
32
|
+
KnightCode reads user-level servers from `~/.knightcode/agent/mcp.json` and project servers from `.knightcode/mcp.json`. Project configuration is read only after [project trust](security.md#understand-project-trust) is granted. A project entry replaces a user-level entry with the same name.
|
|
33
|
+
|
|
34
|
+
The format matches other MCP clients:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"filesystem": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
|
|
42
|
+
},
|
|
43
|
+
"docs": {
|
|
44
|
+
"url": "https://example.com/mcp",
|
|
45
|
+
"headers": { "Authorization": "Bearer ${DOCS_TOKEN}" },
|
|
46
|
+
"description": "Search and read the product documentation"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Stdio servers use `command`, `args`, `env`, and `cwd`. Relative `cwd` values resolve against the session directory. A leading `~/` in `command`, an argument, or `cwd` names the home directory.
|
|
53
|
+
|
|
54
|
+
HTTP servers use `url`, `headers`, and `oauth` (see [Authenticate with OAuth](#authenticate-with-oauth)). The legacy SSE transport is not supported.
|
|
55
|
+
|
|
56
|
+
Both server types support:
|
|
57
|
+
|
|
58
|
+
- `timeout`: per-request timeout in seconds (default 60). Progress notifications reset it.
|
|
59
|
+
- `enabled: false`: keep the entry without connecting to it.
|
|
60
|
+
- `exposure` and `toolExposure`: control how tools reach the model (see [Control tool exposure](#control-tool-exposure)).
|
|
61
|
+
- `description`: what the server offers, in a sentence. The `codemode` and `tool_search` descriptions show it next to the server, so the model knows what to search for.
|
|
62
|
+
|
|
63
|
+
Keep personal servers and servers with credentials in the user-level file. Use the project file only for servers the project requires, and only in trusted projects.
|
|
64
|
+
|
|
65
|
+
### Configuration rules
|
|
66
|
+
|
|
67
|
+
- Server names may contain only letters, digits, `_`, and `-`. Tools are named `mcp__<server>__<tool>`.
|
|
68
|
+
- `type` is optional. A `command` selects stdio and a `url` selects streamable HTTP. When present, `type` must be `stdio`, `http`, or `streamable-http`.
|
|
69
|
+
- `sse` is rejected. Servers that document an SSE endpoint often also provide streamable HTTP, commonly at `/mcp` instead of `/sse`.
|
|
70
|
+
- `command` is one executable and `args` contains its arguments. It is not a shell command string.
|
|
71
|
+
- `env` and `headers` values can use environment variables such as `${GITHUB_TOKEN}`. They can also run a command with `!command`, but the command must make up the whole value, for example `"Authorization": "!echo Bearer $(gh auth token)"`.
|
|
72
|
+
- Invalid entries are reported and skipped without preventing other servers from connecting.
|
|
73
|
+
|
|
74
|
+
`knightcode mcp add` and `knightcode mcp remove` cover common changes from a shell. See [MCP commands](cli.md#mcp-commands) for their options.
|
|
75
|
+
|
|
76
|
+
### Inspect or change a server
|
|
77
|
+
|
|
78
|
+
`/mcp` lists configured servers with their state, tool count, exposure, and configuration source. Servers that need attention appear first. Select a server to inspect its tools and connection details, reconnect, sign in or out, change exposure, or enable and disable it.
|
|
79
|
+
|
|
80
|
+
Exposure and enabled-state changes are saved to the file that defines the server without replacing unrelated content. Disabled servers remain listed. Outside the interactive TUI, `/mcp` prints server status; `/mcp login <server>`, `/mcp logout <server>`, and `/mcp reconnect <server>` perform those actions directly.
|
|
81
|
+
|
|
82
|
+
Shell commands work without a session: `knightcode mcp add`, `knightcode mcp remove`, `knightcode mcp list`, `knightcode mcp login`, and `knightcode mcp logout`. Shell commands do not load extensions.
|
|
83
|
+
|
|
84
|
+
### Diagnose connection problems
|
|
85
|
+
|
|
86
|
+
Run `knightcode mcp list` to connect to every enabled server and print its state, tools, and errors. It exits with status 1 when an entry is invalid or an enabled server is not connected. `/mcp` shows the full connection error and the tail of stderr from a failed stdio server.
|
|
87
|
+
|
|
88
|
+
KnightCode reports configuration errors, failed connections, and required sign-ins once after startup. Server logging notifications are appended to `~/.knightcode/agent/mcp.log` as `<time> [<server>] <level> <logger>: <message>`. The file moves to `mcp.log.1` after it grows past 5 MB.
|
|
89
|
+
|
|
90
|
+
KnightCode connects when a session starts. The first prompt waits up to 10 seconds for startup connections; tools from slower servers become available when they connect. HTTP network errors and transient statuses (408, 429, and 5xx) are retried twice. A dropped connection is shown as disconnected and reconnects on the next call. When a server announces a changed tool list, new tools are added and withdrawn tools become unreachable.
|
|
91
|
+
|
|
92
|
+
Stopping a stdio server closes its stdin, sends SIGTERM, then sends SIGKILL to its process group. This also stops servers launched through wrappers such as `npx` or `uvx`.
|
|
93
|
+
|
|
94
|
+
## Migrate configuration from another client
|
|
95
|
+
|
|
96
|
+
Move the converted entry under `mcpServers` in `mcp.json`, then run `knightcode mcp list` to validate it.
|
|
97
|
+
|
|
98
|
+
| Client | Conversion |
|
|
99
|
+
|---|---|
|
|
100
|
+
| Claude Desktop, Claude Code, or Cursor | Copy the existing `mcpServers` entry. |
|
|
101
|
+
| VS Code | Move an entry from the top-level `servers` object and replace `${input:...}` prompts with `${NAME}` environment variables. |
|
|
102
|
+
| Codex | Convert `[mcp_servers.<name>]` TOML fields such as `command`, `args`, `env`, and `url` to JSON. |
|
|
103
|
+
| OpenCode | Convert `"type": "local"` to a stdio entry, split its `command` array into `command` and `args`, rename `environment` to `env`, and replace `{env:NAME}` with `${NAME}`. Convert `"type": "remote"` to a URL entry. |
|
|
104
|
+
|
|
105
|
+
## Authenticate with OAuth
|
|
106
|
+
|
|
107
|
+
Remote servers that use OAuth, such as Sentry, need no credentials in `mcp.json`:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"mcpServers": {
|
|
112
|
+
"sentry": { "url": "https://mcp.sentry.dev/mcp" }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
When the server rejects an unauthenticated connection, `/mcp` shows that it needs sign-in. Select "Sign in", run `/mcp login sentry`, or run `knightcode mcp login sentry`. KnightCode opens the authorization page and waits for approval. If the browser runs on another machine, such as over SSH, paste its redirected URL into the sign-in screen. A running session uses the new credentials on its next turn.
|
|
118
|
+
|
|
119
|
+
KnightCode registers itself with the authorization server, stores tokens in `~/.knightcode/agent/mcp-auth.json`, and refreshes access tokens when they expire or the server rejects them. If a server later requests additional scope, KnightCode asks for sign-in again. Signing out deletes the stored credentials.
|
|
120
|
+
|
|
121
|
+
OAuth applies to HTTP servers without an `Authorization` header. For a server that does not support dynamic client registration, configure a registered client:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"example": {
|
|
127
|
+
"url": "https://mcp.example.com/mcp",
|
|
128
|
+
"oauth": { "clientId": "my-client", "clientSecret": "${EXAMPLE_SECRET}", "callbackPort": 8765 }
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The redirect URI must match the registered URI. `callbackPort` uses `http://127.0.0.1:<port>/callback`. To use another URI, set `callbackUrl`; it must use HTTP on `localhost`, `127.0.0.1`, or `[::1]`. KnightCode sends it exactly as written. When `callbackUrl` omits a port, KnightCode uses `callbackPort` or a free port and adds it to the URI, as allowed for loopback redirects by RFC 8252. `clientSecret` is optional and can use an environment variable or command.
|
|
135
|
+
|
|
136
|
+
Set `scope` to a space-separated list for servers that do not advertise their required scopes. Otherwise, KnightCode requests the advertised scopes. Later scope requests are added to the configured value.
|
|
137
|
+
|
|
138
|
+
KnightCode registers as `knightcode`. Some servers only accept registrations from known clients. Set `clientName` to send another name:
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"mcpServers": {
|
|
143
|
+
"figma": { "url": "https://mcp.figma.com/mcp", "oauth": { "clientName": "Claude Code" } }
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The name is only sent when KnightCode registers a client. To register again under a new name, sign out first.
|
|
149
|
+
|
|
150
|
+
## Control tool exposure
|
|
151
|
+
|
|
152
|
+
Each server tool is registered as `mcp__<server>__<tool>`. The server's `exposure` determines how the model reaches it:
|
|
153
|
+
|
|
154
|
+
| Exposure | Behavior | Typical use |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `codemode` (default) | Callable from [`codemode`](cli.md#tools) scripts, but neither declared to the model nor listed one by one. The codemode description lists the server with its `description`; scripts find tools with `searchTools()`, `describeTool()`, or `ALL_TOOLS`. | General MCP servers, especially when scripts should combine or filter calls. |
|
|
157
|
+
| `deferred` | Not declared until [`tool_search`](cli.md#tools) loads a match for the next model call. | Large servers whose tools should be called directly after discovery. |
|
|
158
|
+
| `direct` | Declared to the model like a built-in tool and also callable from codemode. | Small, frequently used tool sets. |
|
|
159
|
+
| `hidden` | Registered but unreachable. | Servers or tools that should remain unavailable. |
|
|
160
|
+
|
|
161
|
+
`codemode-deferred` is accepted as an alias for `codemode`.
|
|
162
|
+
|
|
163
|
+
KnightCode activates `codemode` when a server with `codemode` exposure connects. It activates `tool_search` for a server with `deferred` exposure. To make the model see a tool without searching, give it `direct` exposure with `toolExposure`.
|
|
164
|
+
|
|
165
|
+
`toolExposure` overrides the server exposure for individual tools. Keys are exact server tool names or patterns where `*` matches any characters. Exact names win over patterns; among patterns, the first match wins. A server with `hidden` exposure can expose only selected tools:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"mcpServers": {
|
|
170
|
+
"github": {
|
|
171
|
+
"url": "https://api.githubcopilot.com/mcp/",
|
|
172
|
+
"exposure": "deferred",
|
|
173
|
+
"toolExposure": {
|
|
174
|
+
"search_code": "direct",
|
|
175
|
+
"get_*": "codemode",
|
|
176
|
+
"delete_*": "hidden"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`knightcode mcp list` marks tools whose exposure differs from their server. The Tools view in `/mcp` also shows the effective exposure.
|
|
184
|
+
|
|
185
|
+
Tools with `codemode` or `deferred` exposure can be reached through either indirect mechanism: codemode scripts can call them, and `tool_search` can load them. Codemode calls do not depend on the active tool set, so they remain available after `/tree`, resume, and fork. Tools loaded by `tool_search` are recorded in the transcript and remain declared on that branch.
|
|
186
|
+
|
|
187
|
+
To keep `codemode` active without MCP servers, add `"defaultTools": ["+codemode"]` to [settings](settings.md#tools). To prevent automatic codemode activation, set `"autoEnableCodemode": false` beside `mcpServers`. A project value overrides the user-level value. KnightCode warns once when neither `codemode` nor `tool_search` is active and non-direct tools cannot be called.
|
|
188
|
+
|
|
189
|
+
Text results over 20 KB reach the model with their middle removed around a `…N chars truncated…` marker. The full text is saved to a temporary file named in the result. Codemode scripts receive the complete result and can reduce it before returning output to the model.
|
|
190
|
+
|
|
191
|
+
Codemode scripts receive the complete MCP `CallToolResult`, including `content`, `structuredContent`, and `isError`. A result with `isError` resolves inside scripts but is reported as an error for direct calls. `image(result.content[0])` forwards an image block. Server instructions are not part of any tool description; scripts read them with `describeNamespace("mcp__<server>")`, which also returns the server's tool names.
|
|
192
|
+
|
|
193
|
+
## Use resources
|
|
194
|
+
|
|
195
|
+
When a connected server offers [resources](https://modelcontextprotocol.io/specification/2025-11-25/server/resources), KnightCode adds the resource tools used by Codex and OpenCode:
|
|
196
|
+
|
|
197
|
+
- `list_mcp_resources` lists resources as JSON: `{ server?, resources: [{ server, uri, name, ... }], nextCursor? }`. With `server`, it lists one page; `cursor` continues with the next page. Without `server`, it lists every resource from every server.
|
|
198
|
+
- `list_mcp_resource_templates` lists URI templates for resources the servers do not list directly.
|
|
199
|
+
- `read_mcp_resource` reads a resource by `server` and `uri`. Text reaches the model as text and images as images. Other binary resources are saved to temporary files, and the model receives the path. Scripts receive `{ server, uri, contents }`.
|
|
200
|
+
|
|
201
|
+
These tools reach every enabled, non-hidden server with resources. Their exposure is the widest exposure among those servers: `direct`, then `codemode` or `deferred`. Resource links in tool results identify `read_mcp_resource` and the server.
|
|
202
|
+
|
|
203
|
+
Resources for MCP Apps, identified by `ui://` URIs or `text/html;profile=mcp-app`, are omitted because KnightCode does not render them. Resource icons are also omitted.
|
|
204
|
+
|
|
205
|
+
Reading and listing resources is retried once after a transient HTTP error (408, 429, or 5xx). Tool calls are not retried because the server may already have performed them.
|
|
206
|
+
|
|
207
|
+
## Permissions
|
|
208
|
+
|
|
209
|
+
Every MCP call passes through KnightCode's tool pipeline. Extension `tool_call` and `tool_result` handlers, including permission gates, therefore apply to MCP tools. Calls made from codemode scripts carry the codemode call ID as `parentToolCallId`.
|
|
210
|
+
|
|
211
|
+
`knightcode.getAllTools()` reports the annotations declared by each server: `readOnlyHint`, `destructiveHint`, `idempotentHint`, and `openWorldHint`. Permission extensions can use these hints to decide which calls require confirmation (see [Tool exposure](extensions.md#tool-exposure)). Resource tools are marked read-only.
|
|
212
|
+
|
|
213
|
+
## Extensions and SDK
|
|
214
|
+
|
|
215
|
+
### Add servers from extensions
|
|
216
|
+
|
|
217
|
+
Extensions can add servers for the current session with `knightcode.registerMcpServer(name, config)`, using the same shape as an `mcpServers` entry (see [MCP servers in extensions](extensions.md#mcp-servers)). Registered servers connect like configured servers and appear in `/mcp` with the extension as their source.
|
|
218
|
+
|
|
219
|
+
Changes to enabled state or exposure apply only to the current session. A file-configured server with the same name takes precedence, and `/mcp` lists the overridden registration. `knightcode mcp` shell commands do not load extensions and only see file-configured servers.
|
|
220
|
+
|
|
221
|
+
### Replace the built-in MCP support
|
|
222
|
+
|
|
223
|
+
An installed extension that registers `/mcp`, such as `knightcode-mcp-adapter`, replaces the built-in MCP support for sessions. KnightCode then does not read `mcp.json` or connect its servers in a session, and `/mcp` belongs to the extension. Remove the extension to restore the built-in behavior. To disable built-in MCP support without a replacement, disable `mcp` under Built-in in `knightcode config`, or set `"extensions": ["-builtin:mcp"]` in [settings](settings.md#resources).
|
|
224
|
+
|
|
225
|
+
An extension that registers `codemode` or `tool_search` similarly replaces the built-in tool with that name. Shell-level `knightcode mcp` commands always use the built-in implementation.
|
|
226
|
+
|
|
227
|
+
### Use MCP from the SDK
|
|
228
|
+
|
|
229
|
+
SDK sessions do not load built-in extensions. Add the MCP extension, the codemode extension for `codemode` servers, and the tool-search extension for `deferred` servers to the resource loader. See [Codemode and MCP](sdk.md#codemode-mcp).
|
package/bin/docs/models.md
CHANGED
|
@@ -100,6 +100,41 @@ Choose the conservative end of any published range. A model without a lifetime f
|
|
|
100
100
|
|
|
101
101
|
Compatibility settings should describe verified differences in the endpoint's request or response behavior. Do not enable them based only on an endpoint advertising OpenAI or Anthropic compatibility.
|
|
102
102
|
|
|
103
|
+
## Use classifier models
|
|
104
|
+
|
|
105
|
+
Classifier models do not chat. They answer typed questions about JSON state: pick one of several choices, answer yes or no, or give a score, each with probabilities. KnightCode includes TypeSafe's Jev model from these providers:
|
|
106
|
+
|
|
107
|
+
| Provider | Model IDs | Authentication |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `typesafe` | `jev-latest` | `TYPESAFE_API_KEY` |
|
|
110
|
+
| `openrouter` | `typesafe/jev-1.13`, `~typesafe/jev-latest` | `OPENROUTER_API_KEY` or `/login` |
|
|
111
|
+
| `cloudflare-workers-ai` | `typesafe/jev` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
112
|
+
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
113
|
+
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
114
|
+
|
|
115
|
+
Chat models on a [llama.cpp router](llama-cpp.md#classification) are also listed as classifier models.
|
|
116
|
+
|
|
117
|
+
Classifier models do not appear in `/model`. The [classifier gate](usage.md#classifier-gate) uses one to screen risky tool calls. The model reaches them through the [`codemode`](cli.md#enable-codemode) tool, which is off unless an MCP server turned it on. Enable it with `"defaultTools": ["+codemode"]` in [settings](settings.md#tools). Scripts then list classifier models with `models.getAvailableOfType("classifier")` and call `models.classify(model, { state, questions })`:
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
const jev = await models.getModelOfType("classifier", "typesafe", "jev-latest");
|
|
121
|
+
const result = await models.classify(jev, {
|
|
122
|
+
state: { message: "The change works, thanks." },
|
|
123
|
+
questions: {
|
|
124
|
+
approved: {
|
|
125
|
+
type: "bool",
|
|
126
|
+
instructions: "Does the user approve of the result?",
|
|
127
|
+
criteria: { true: "Approval", false: "No approval" },
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
return result.answers;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
When the service reports token counts, as all System One services do, `result.usage` carries them with their cost. KnightCode adds the usage of a script's classifier calls to the `codemode` tool result, so it counts toward the session cost in the footer and `/session`. The cost uses the model's catalog price; models without one, such as TypeSafe's direct `jev-latest`, report tokens at no cost.
|
|
135
|
+
|
|
136
|
+
Extensions call classifiers through `ctx.modelRegistry.classify()`, without codemode. [Virtual models](virtual-models.md#route-requests) can use them to route requests; see the `jev-router.ts` example.
|
|
137
|
+
|
|
103
138
|
## Add a custom provider
|
|
104
139
|
|
|
105
140
|
Use an extension when the provider needs custom streaming, model discovery, or authentication behavior. See [Custom Providers](custom-provider.md) for the extension workflow.
|
package/bin/docs/packages.md
CHANGED
|
@@ -118,7 +118,7 @@ For each resource type:
|
|
|
118
118
|
|
|
119
119
|
Filters narrow the package manifest. They do not expose resources that the package itself did not declare.
|
|
120
120
|
|
|
121
|
-
Run `knightcode config` to enable or disable discovered resources. It starts with personal configuration; press Tab to switch scope, or run `knightcode config --local` to start with project overrides.
|
|
121
|
+
Run `knightcode config` to enable or disable discovered resources and knightcode's built-in extensions. It starts with personal configuration; press Tab to switch scope, or run `knightcode config --local` to start with project overrides.
|
|
122
122
|
|
|
123
123
|
## Understand scope and identity
|
|
124
124
|
|
package/bin/docs/providers.md
CHANGED
|
@@ -50,6 +50,7 @@ This table covers providers with a single primary API-key variable. Providers th
|
|
|
50
50
|
| ZAI Coding Plan (China) | `ZAI_CODING_CN_API_KEY` |
|
|
51
51
|
| OpenCode Zen and Go | `OPENCODE_API_KEY` |
|
|
52
52
|
| Radius | `RADIUS_API_KEY` |
|
|
53
|
+
| TypeSafe ([classifier models](models.md#use-classifier-models)) | `TYPESAFE_API_KEY` |
|
|
53
54
|
| Hugging Face | `HF_TOKEN` |
|
|
54
55
|
| Fireworks | `FIREWORKS_API_KEY` |
|
|
55
56
|
| Together AI | `TOGETHER_API_KEY` |
|
package/bin/docs/sdk.md
CHANGED
|
@@ -109,7 +109,11 @@ Use `DefaultResourceLoader` when you want standard discovery with selected overr
|
|
|
109
109
|
|
|
110
110
|
<a id="inlineextension"></a>
|
|
111
111
|
|
|
112
|
-
Inline extension factories can be supplied through `DefaultResourceLoader`. Give one an `InlineExtension` name only when it needs a stable name in diagnostics and startup output.
|
|
112
|
+
Inline extension factories can be supplied through `DefaultResourceLoader`. Give one an `InlineExtension` name only when it needs a stable name in diagnostics and startup output. A named inline extension with `replaceable: true` is left out when another extension registers a tool, command, or flag with a name it registers during loading, instead of both loading with a conflict. The CLI's built-in codemode, tool search, and MCP extensions are replaceable. A named entry with `builtin: true` is not an inline extension: it supplies the code of the `builtin:<name>` extension, which loads like a configured extension file. It loads by default, is listed in `knightcode config`, and is disabled by `-builtin:<name>` in the `extensions` setting or by `noExtensions`; `additionalExtensionPaths: ["builtin:<name>"]` loads it explicitly. It loads after project trust is resolved, so it cannot handle `project_trust`. The CLI's built-in extensions use it.
|
|
113
|
+
|
|
114
|
+
<a id="codemode-mcp"></a>
|
|
115
|
+
|
|
116
|
+
The CLI loads `codemode`, `tool_search`, and MCP as built-in extensions. SDK sessions do not; add `createCodemodeExtension()`, `createToolSearchExtension()`, and `createMcpExtension()` to the `extensionFactories` of `DefaultResourceLoader`. `codemode` and `tool_search` are registered inactive: enable them through the `defaultTools` setting (`["+codemode", "+tool_search"]` keeps the other default tools), or let the MCP extension activate them: `codemode` for servers with `codemode` exposure, `tool_search` for servers with `deferred` exposure. The MCP extension connects its servers on `session_start`, so call `session.bindExtensions()`. See [Codemode and MCP](../examples/sdk/14-codemode-mcp.ts).
|
|
113
117
|
|
|
114
118
|
See the focused examples for [models](../examples/sdk/02-custom-model.ts), [tools](../examples/sdk/05-tools.ts), [extensions](../examples/sdk/06-extensions.ts), and [full control](../examples/sdk/12-full-control.ts).
|
|
115
119
|
|
|
@@ -130,6 +134,7 @@ See the focused examples for [models](../examples/sdk/02-custom-model.ts), [tool
|
|
|
130
134
|
| [Sessions](../examples/sdk/11-sessions.ts) | Control session persistence and restoration |
|
|
131
135
|
| [Full control](../examples/sdk/12-full-control.ts) | Replace default discovery and state services |
|
|
132
136
|
| [Session runtime](../examples/sdk/13-session-runtime.ts) | Replace the active session safely |
|
|
137
|
+
| [Codemode and MCP](../examples/sdk/14-codemode-mcp.ts) | Add the `codemode`, `tool_search`, and MCP extensions |
|
|
133
138
|
|
|
134
139
|
<a id="exports"></a>
|
|
135
140
|
|
package/bin/docs/security.md
CHANGED
|
@@ -37,6 +37,7 @@ Project trust does not limit what tool calls can access or affect. After KnightC
|
|
|
37
37
|
KnightCode requires a project-trust decision when it finds any of these resources from the current working directory:
|
|
38
38
|
|
|
39
39
|
- `.knightcode/settings.json`
|
|
40
|
+
- `.knightcode/mcp.json`
|
|
40
41
|
- `.knightcode/extensions`, `.knightcode/skills`, `.knightcode/prompts`, or `.knightcode/themes`
|
|
41
42
|
- `.knightcode/SYSTEM.md` or `.knightcode/APPEND_SYSTEM.md`
|
|
42
43
|
- project `.agents/skills` in the current directory or an ancestor directory
|
|
@@ -46,6 +47,7 @@ A bare `.knightcode` directory does not require project trust.
|
|
|
46
47
|
Granting project trust allows KnightCode to load:
|
|
47
48
|
|
|
48
49
|
- project settings
|
|
50
|
+
- project MCP servers from `.knightcode/mcp.json`
|
|
49
51
|
- extensions, skills, prompt templates, themes, and system-prompt files under `.knightcode`
|
|
50
52
|
- missing packages configured through project settings
|
|
51
53
|
- project-local and project-package extensions
|
package/bin/docs/settings.md
CHANGED
|
@@ -37,9 +37,23 @@ See [Choose a Model](models.md) for model selection and thinking controls.
|
|
|
37
37
|
|
|
38
38
|
| Setting | Type | Default | Description |
|
|
39
39
|
|---|---|---|---|
|
|
40
|
-
| `defaultTools` | `string[]` | `read`, `bash`, `edit`, `write` |
|
|
40
|
+
| `defaultTools` | `string[]` | `read`, `bash`, `edit`, `write` | Tools enabled at startup. Plain names replace the defaults; `+name` adds a tool and `-name` removes one. An empty array disables all built-in tools but not extension or SDK tools. |
|
|
41
|
+
| `codemode.mode` | `"on"` \| `"only"` | `"on"` | How the `codemode` tool presents tools while it is active. `on`: declared tools get their `codemode` declaration appended to their description, and `codemode` lists only tools that are not declared. `only`: `codemode` lists every tool scripts can call, and active built-in and extension tools are hidden from the model, so it reaches them through `codemode`. |
|
|
42
|
+
| `codemode.inlineBudget` | number | `3000` | Estimated tokens (characters / 4) the `codemode` tool's description may spend on tool declarations. Tools that do not fit are left out and found with `searchTools()`. `0` lists only namespaces. |
|
|
41
43
|
|
|
42
|
-
Available built-in tools are `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls`.
|
|
44
|
+
Available built-in tools are `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls`. `defaultTools` can also name `codemode` and `tool_search`, which built-in extensions register inactive, and other extension tools registered inactive.
|
|
45
|
+
|
|
46
|
+
A list of only `+name` and `-name` entries changes the inherited selection instead of replacing it. For example, this enables `codemode` next to the default tools:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"defaultTools": ["+codemode"]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This replaces `bash` with `powershell` and enables `grep`: `["-bash", "+powershell", "+grep"]`. Project settings apply on top of user settings: a project list with only `+name` and `-name` entries changes the user's selection, and a project list with a plain name replaces it. In one list, plain names form the selection, and `+name` and `-name` then apply in order.
|
|
55
|
+
|
|
56
|
+
CLI tool options override this setting for one invocation; `--tools` does not accept `+name` or `-name`. See [Command Line](cli.md#tools).
|
|
43
57
|
|
|
44
58
|
The [web tools](usage.md#web-tools) `webfetch` and `websearch` are not part of `defaultTools`. `/tools` turns them on and stores their settings, including the search provider and Brave key, in `~/.knightcode/agent/tools.json`.
|
|
45
59
|
|
|
@@ -81,6 +95,7 @@ See [Compaction Reference](compaction.md) for trigger, summarization, and valida
|
|
|
81
95
|
| `fullscreenExitOutput` | `"transcript" \| "resume-hint"` | `"transcript"` | Output printed when fullscreen mode exits. |
|
|
82
96
|
| `fullscreenScrollbar` | `"auto" \| "always" \| "hidden"` | `"auto"` | Fullscreen transcript scrollbar behavior. |
|
|
83
97
|
| `fullscreenCopyOnSelect` | boolean | `true` | Copy selected text automatically in fullscreen mode. When disabled, selections stay highlighted and `Ctrl+X` copies the active selection. Has no effect in regular mode. |
|
|
98
|
+
| `fullscreenWheelScrollLines` | `"auto"` \| number | `"auto"` | Lines per mouse-wheel event in fullscreen mode, from 1 to 100. `"auto"` moves one line per event in local macOS terminals, which already accelerate wheel and trackpad input; elsewhere, and over SSH, it speeds up fast wheel spins to at most 6 lines per event. Alt+wheel moves five times as far. |
|
|
84
99
|
| `editorPaddingX` | number | `0` | Horizontal editor padding from 0 to 3 cells. |
|
|
85
100
|
| `outputPad` | `0 \| 1` | `1` | Horizontal transcript padding. |
|
|
86
101
|
| `autocompleteMaxVisible` | number | `5` | Visible autocomplete entries, from 3 to 20. |
|
|
@@ -142,6 +157,8 @@ Resource paths in user settings resolve from the agent directory. Paths in proje
|
|
|
142
157
|
|
|
143
158
|
Resource arrays support glob exclusions with `!pattern`, exact inclusion with `+path`, and exact exclusion with `-path`. KnightCode loads resources listed in both user-level and project settings.
|
|
144
159
|
|
|
160
|
+
The built-in extensions are named `builtin:mcp`, `builtin:llama.cpp`, `builtin:codemode`, and `builtin:tool-search` in `extensions`. They load by default; `-builtin:mcp` disables one. A `+builtin:<name>` or `-builtin:<name>` entry in project settings overrides the user setting. `knightcode config` lists them under Built-in. `--no-extensions` disables them too, and `-e builtin:<name>` loads one explicitly.
|
|
161
|
+
|
|
145
162
|
## Updates, telemetry, and warnings
|
|
146
163
|
|
|
147
164
|
| Setting | Type | Default | Description |
|
package/bin/docs/windows.md
CHANGED
|
@@ -42,6 +42,8 @@ To replace the model-facing `bash` tool with `powershell`, add this to `~/.knigh
|
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
+
`["-bash", "+powershell"]` does the same while keeping any other default tools you configured.
|
|
46
|
+
|
|
45
47
|
Restart KnightCode, then ask it to run a harmless PowerShell command. The `!` and `!!` editor commands continue to use Bash. The `powershell` tool is available only when KnightCode runs as a native Windows process.
|
|
46
48
|
|
|
47
49
|
See [Settings](settings.md#tools) for other tool combinations.
|
|
@@ -930,6 +930,21 @@
|
|
|
930
930
|
'</div>';
|
|
931
931
|
};
|
|
932
932
|
|
|
933
|
+
// Calls this tool made to other tools (for example from a codemode script), recorded without results.
|
|
934
|
+
const renderNestedCalls = () => {
|
|
935
|
+
const nested = result?.nestedCalls;
|
|
936
|
+
if (!nested || !Array.isArray(nested.calls) || nested.calls.length === 0) return '';
|
|
937
|
+
const icons = { ok: '✓', error: '✗', unfinished: '…' };
|
|
938
|
+
const lines = nested.calls.map(c => {
|
|
939
|
+
const args = c.arguments ? JSON.stringify(c.arguments) : `[arguments omitted, ${c.argumentsBytes} bytes]`;
|
|
940
|
+
const duration = c.durationMs !== undefined ? ` ${c.durationMs}ms` : '';
|
|
941
|
+
const error = c.error ? `\n ${c.error.split('\n').join('\n ')}` : '';
|
|
942
|
+
return `${icons[c.status] || '?'} ${c.name} ${args}${duration}${error}`;
|
|
943
|
+
});
|
|
944
|
+
const title = `Nested calls: ${nested.calls.length}${nested.complete ? '' : ' (incomplete record)'}`;
|
|
945
|
+
return formatExpandableOutput([title, ...lines].join('\n'), 1);
|
|
946
|
+
};
|
|
947
|
+
|
|
933
948
|
const toolDomId = `tool-call-${escapeHtml(call.id)}`;
|
|
934
949
|
let html = `<div class="tool-execution ${statusClass}" id="${toolDomId}">`;
|
|
935
950
|
const args = call.arguments || {};
|
|
@@ -1063,6 +1078,7 @@
|
|
|
1063
1078
|
}
|
|
1064
1079
|
}
|
|
1065
1080
|
|
|
1081
|
+
html += renderNestedCalls();
|
|
1066
1082
|
html += '</div>';
|
|
1067
1083
|
return html;
|
|
1068
1084
|
}
|
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: 119395055 bytes
|
|
4
|
+
sha256: d60c458eebe031960e565ec6ee7a94434ae1e7e29d1a56b64f06eda7a8333858
|
package/bin/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knightcodeai/cli",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "KnightCode — a local, BYOK terminal coding agent powered by OpenRouter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -37,17 +37,19 @@
|
|
|
37
37
|
"test": "vitest --run"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@knightcodeai/cli-linux-x64": "0.11.
|
|
41
|
-
"@knightcodeai/cli-linux-arm64": "0.11.
|
|
42
|
-
"@knightcodeai/cli-darwin-x64": "0.11.
|
|
43
|
-
"@knightcodeai/cli-darwin-arm64": "0.11.
|
|
44
|
-
"@knightcodeai/cli-win32-x64": "0.11.
|
|
40
|
+
"@knightcodeai/cli-linux-x64": "0.11.2",
|
|
41
|
+
"@knightcodeai/cli-linux-arm64": "0.11.2",
|
|
42
|
+
"@knightcodeai/cli-darwin-x64": "0.11.2",
|
|
43
|
+
"@knightcodeai/cli-darwin-arm64": "0.11.2",
|
|
44
|
+
"@knightcodeai/cli-win32-x64": "0.11.2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@agentclientprotocol/sdk": "1.4.0",
|
|
48
48
|
"@knightcode/agent": "workspace:*",
|
|
49
49
|
"@knightcode/ai": "workspace:*",
|
|
50
50
|
"@knightcode/client": "workspace:*",
|
|
51
|
+
"@knightcode/codemode": "workspace:*",
|
|
52
|
+
"@knightcode/mcp": "workspace:*",
|
|
51
53
|
"@knightcode/protocol": "workspace:*",
|
|
52
54
|
"@knightcode/remote": "workspace:*",
|
|
53
55
|
"@knightcode/tools": "workspace:*",
|
|
@@ -70,6 +72,7 @@
|
|
|
70
72
|
"marked": "18.0.11",
|
|
71
73
|
"minimatch": "10.2.6",
|
|
72
74
|
"proper-lockfile": "4.1.2",
|
|
75
|
+
"quickjs-wasi": "3.6.2",
|
|
73
76
|
"semver": "7.8.5",
|
|
74
77
|
"typebox": "1.3.27",
|
|
75
78
|
"undici": "8.10.2",
|