@knightcodeai/cli 0.18.2 → 0.19.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/CHANGELOG.md +92 -0
- package/dist/bundle/chunks/anthropic-messages-34POCEPV.js +6 -0
- package/dist/bundle/chunks/azure-openai-responses-ZZQJJY7B.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
- package/dist/bundle/chunks/{chunk-IGNYWP4P.js → chunk-2QXUEOVY.js} +1 -1
- package/dist/bundle/chunks/{chunk-HNZSETB2.js → chunk-3QKQRXCZ.js} +4 -4
- package/dist/bundle/chunks/chunk-AA6MLWWY.js +2 -0
- package/dist/bundle/chunks/{chunk-NGWSYXD5.js → chunk-BTRAS32C.js} +2 -2
- package/dist/bundle/chunks/{chunk-LA7DDYYM.js → chunk-C62RVFZT.js} +9 -8
- package/dist/bundle/chunks/{chunk-MXIWLMNT.js → chunk-CCP7VAJU.js} +1 -1
- package/dist/bundle/chunks/{chunk-55AAX2FB.js → chunk-GPHSXYPT.js} +1 -1
- package/dist/bundle/chunks/{chunk-7CWBI3GL.js → chunk-IIS4JDFO.js} +153 -119
- package/dist/bundle/chunks/{chunk-3B66IKOZ.js → chunk-JSLSFYBX.js} +1 -1
- package/dist/bundle/chunks/{chunk-ZB5LGRB5.js → chunk-KRDGPCZM.js} +1 -1
- package/dist/bundle/chunks/chunk-OQHO44L6.js +16 -0
- package/dist/bundle/chunks/chunk-R7X2RAGR.js +30 -0
- package/dist/bundle/chunks/{chunk-R2XYMDTS.js → chunk-RZDCZFG7.js} +1 -1
- package/dist/bundle/chunks/chunk-T47GKPON.js +11 -0
- package/dist/bundle/chunks/chunk-UU4A4NV5.js +2 -0
- package/dist/bundle/chunks/{cli-66ZLURJW.js → cli-SIPOI5P3.js} +1 -1
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-QHP5M5HC.js +2 -0
- package/dist/bundle/chunks/{easter-egg-3d-DQYQIGP2.js → easter-egg-3d-BVWLABZN.js} +1 -1
- package/dist/bundle/chunks/{execute-KJDH5JWX.js → execute-6UIHV2DR.js} +9 -3
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-RFCCCXK6.js +2 -0
- package/dist/bundle/chunks/google-vertex-WN3JAZCD.js +2 -0
- package/dist/bundle/chunks/knightcode-messages-57CV36UV.js +8 -0
- package/dist/bundle/chunks/{llama-cpp-classify-HRPRKOZA.js → llama-cpp-classify-FEWC5ZIH.js} +2 -2
- package/dist/bundle/chunks/{mistral-conversations-FKYKJV7R.js → mistral-conversations-GIGX6BW6.js} +1 -1
- package/dist/bundle/chunks/openai-codex-responses-3Y7R752C.js +10 -0
- package/dist/bundle/chunks/openai-completions-HBXENZUJ.js +7 -0
- package/dist/bundle/chunks/{openai-decisions-OBTJNBTE.js → openai-decisions-MLI3SMFN.js} +1 -1
- package/dist/bundle/chunks/openai-responses-BNRA5YTD.js +4 -0
- package/dist/bundle/chunks/openrouter-images-JWVDFQJ4.js +2 -0
- package/dist/bundle/chunks/{runtime-IU2Z5WWF.js → runtime-AROIXIAV.js} +1 -1
- package/dist/bundle/chunks/typesafe-system-one-5LELZY2F.js +2 -0
- package/dist/bundle/chunks/virtual-modules-IYKQM2DL.js +2 -0
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/core/export-html/template.html +1 -0
- package/dist/core/export-html/template.js +2 -1
- package/dist/core/export-html/vendor/marked-cjk-friendly.min.js +6 -0
- package/dist/core/export-html/vendor/marked.min.js +30 -29
- package/docs/app-server.md +288 -8
- package/docs/app-server.schema.json +5414 -1636
- package/docs/codemode.md +2 -2
- package/docs/desktop.md +19 -4
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +38 -21
- package/docs/settings.md +53 -0
- package/package.json +1 -1
- package/dist/bundle/chunks/anthropic-messages-QIZAJBTA.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-7R44RRTC.js +0 -2
- package/dist/bundle/chunks/chunk-76TARFPL.js +0 -11
- package/dist/bundle/chunks/chunk-HHWP56PR.js +0 -2
- package/dist/bundle/chunks/chunk-T7XWBYOA.js +0 -11
- package/dist/bundle/chunks/chunk-XZJICKQ6.js +0 -30
- package/dist/bundle/chunks/chunk-YQ26QP2R.js +0 -2
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-LA7TF5LV.js +0 -2
- package/dist/bundle/chunks/google-generative-ai-GEBPSQBJ.js +0 -2
- package/dist/bundle/chunks/google-vertex-BRMU44TN.js +0 -2
- package/dist/bundle/chunks/knightcode-messages-3GNOTMSI.js +0 -8
- package/dist/bundle/chunks/openai-codex-responses-DAZKF6IV.js +0 -10
- package/dist/bundle/chunks/openai-completions-A6RD26ED.js +0 -7
- package/dist/bundle/chunks/openai-responses-L3QPK3MQ.js +0 -3
- package/dist/bundle/chunks/openrouter-images-ZI7LLZ4Y.js +0 -2
- package/dist/bundle/chunks/typesafe-system-one-FZHRNG67.js +0 -2
- package/dist/bundle/chunks/virtual-modules-IKIDAUHO.js +0 -2
package/docs/app-server.md
CHANGED
|
@@ -72,9 +72,10 @@ send a subscriber-only `warning` with `threadId`.
|
|
|
72
72
|
|
|
73
73
|
Threads and list summaries include `createdAt` (header creation time) and
|
|
74
74
|
optional `forkedFromId` (the parent's header ID, not a UUID inferred from its
|
|
75
|
-
filename).
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
filename). A loaded thread also carries `sessionFile`, the session file's path,
|
|
76
|
+
once it has been saved. List summaries use file modification time for
|
|
77
|
+
`updatedAt`; loaded threads use the latest entry time, falling back to the
|
|
78
|
+
header. Their `status` is one of:
|
|
78
79
|
|
|
79
80
|
- `{type: "notLoaded"}`
|
|
80
81
|
- `{type: "idle"}`
|
|
@@ -159,9 +160,12 @@ lands in a later turn. A steer cannot be taken back once accepted.
|
|
|
159
160
|
input starts a turn of its own once the thread is idle, oldest first; on an idle
|
|
160
161
|
thread it starts at once. Until it starts it is removable with
|
|
161
162
|
`turn/queue/remove`. A queued input that fails to start (no model, signed out) is
|
|
162
|
-
dropped with an `error` notification
|
|
163
|
-
`
|
|
164
|
-
|
|
163
|
+
dropped with an `error` notification carrying its `clientMessageId`, if it had
|
|
164
|
+
one. `turn/queue/updated` sends
|
|
165
|
+
`{threadId, steering: [text], followUp: [{id, text, attachments?}]}`: steers the
|
|
166
|
+
agent has not delivered yet, and the queued inputs. `text` is the user's own (not
|
|
167
|
+
a prompt composed with review comments); `attachments` counts the images and
|
|
168
|
+
review comments an input carries that its text alone does not.
|
|
165
169
|
|
|
166
170
|
`turn/interrupt` accepts optional `turnId`; a supplied stale ID returns
|
|
167
171
|
`turnMismatch`, while omitting it retains interrupt-current behavior. It drops
|
|
@@ -281,6 +285,86 @@ The most recent initiating subscriber is asked first. Disconnect or unsubscribe
|
|
|
281
285
|
cancels that attempt and migrates it to another subscriber; no subscribers means
|
|
282
286
|
cancel. `serverRequest/cancelled` withdraws an outstanding request.
|
|
283
287
|
|
|
288
|
+
## Dialogs
|
|
289
|
+
|
|
290
|
+
What KnightCode asks the user mid-turn reaches a desktop connection as a server
|
|
291
|
+
request, asked the way approvals are; the thread reports `waitingOn: ["dialog"]`
|
|
292
|
+
meanwhile.
|
|
293
|
+
|
|
294
|
+
`item/toolCall/requestUserInput` carries `ask_user`'s questions, all at once,
|
|
295
|
+
with the `itemId` of the call asking, so a client can move back and forth
|
|
296
|
+
between them before answering. Each question has an `id`, its text and its
|
|
297
|
+
options (`label`, `description`); a label ending in `(Recommended)` is the
|
|
298
|
+
recommended one. Reply `{"answers": {"<id>": {"label": "..."}}}` with the
|
|
299
|
+
chosen option's exact label and an optional `note`, or `{"other": "..."}` for
|
|
300
|
+
the user's own answer; leave out a skipped question. `{}` dismisses the
|
|
301
|
+
questions and stops the turn.
|
|
302
|
+
|
|
303
|
+
`ui/dialog` carries the rest, such as the classifier gate's confirmation of a
|
|
304
|
+
risky call and plan mode's review. `kind` says which: a select carries
|
|
305
|
+
`options`, a confirm its `message`, an input its `placeholder`, an editor its
|
|
306
|
+
`prefill`. Reply with `{"value": "..."}` for a select, input or editor,
|
|
307
|
+
`{"confirmed": true}` for a confirm, or `{}` to cancel.
|
|
308
|
+
|
|
309
|
+
Notices such as "Downloaded model" arrive as the notification `ui/notify` with
|
|
310
|
+
a `level` of `info`, `warning` or `error`. Widgets, status, header, footer
|
|
311
|
+
and custom components draw only in the terminal and do nothing here. Threads a
|
|
312
|
+
terminal-mode connection loads have no dialogs yet.
|
|
313
|
+
|
|
314
|
+
## Workspaces, diffs and git
|
|
315
|
+
|
|
316
|
+
A thread runs in a workspace: the user's checkout (`{mode: "local"}`), or a git
|
|
317
|
+
worktree of its own (`{mode: "worktree"}`), as in the Codex desktop app.
|
|
318
|
+
|
|
319
|
+
`thread/start {cwd, workspace: {mode: "worktree", baseRef?, carryLocalChanges?, environment?}}`
|
|
320
|
+
creates a worktree on a **detached `HEAD`** at `baseRef` (default:
|
|
321
|
+
the checkout's `HEAD`) under `<worktrees.root>/<4 hex digits>/<repository name>`
|
|
322
|
+
and runs the thread there, in the same subdirectory the `cwd` had. No branch is
|
|
323
|
+
created until `git/branch/create` or a handoff makes one. `carryLocalChanges`
|
|
324
|
+
brings the checkout's uncommitted changes (untracked files included, ignored
|
|
325
|
+
files not) along as uncommitted edits. Creation runs no hook, filter or user
|
|
326
|
+
code, so a failed creation leaves nothing behind. A start whose `cwd` is inside
|
|
327
|
+
a managed worktree is a new thread in that worktree.
|
|
328
|
+
|
|
329
|
+
`thread/workspace/progress {threadId, phase, output}` streams the output of an
|
|
330
|
+
environment's setup or cleanup script to the connection that asked. Every
|
|
331
|
+
`Thread` carries `workspace`; `ThreadSummary.workspaceMode` marks worktree
|
|
332
|
+
threads in listings.
|
|
333
|
+
|
|
334
|
+
Diffs come in Codex's Changes scopes: `lastTurn`, `uncommitted` (the default),
|
|
335
|
+
`unstaged`, `staged`, `committed` and `branch`. Each hunk has a content-hash id;
|
|
336
|
+
an action naming a hunk that changed since it was read answers `gitConflict`
|
|
337
|
+
with `data.reason: "diffChanged"`. Files changed while a turn ran are reported
|
|
338
|
+
by `turn/diff/updated {threadId, turnId, files}` after `turn/completed`, each
|
|
339
|
+
file as `{path, additions, deletions}`: the net line totals between the working
|
|
340
|
+
tree before and after the turn. A read-back turn carries the same list as
|
|
341
|
+
`Turn.files`. This
|
|
342
|
+
means "changed while the turn ran", not "changed by the turn": an edit another
|
|
343
|
+
local thread or an editor made meanwhile is in the list too. A worktree thread
|
|
344
|
+
is the only writer in its worktree, so its list is its own.
|
|
345
|
+
|
|
346
|
+
Review comments are drafts the client keeps. They travel with the next
|
|
347
|
+
`turn/start` or `turn/queue/add` as `comments`; the server quotes the commented
|
|
348
|
+
lines from the diff the user reviewed, and the user item shows the comments
|
|
349
|
+
next to the typed text.
|
|
350
|
+
|
|
351
|
+
**Reverting an added file deletes it**, an untracked one included. Clients
|
|
352
|
+
confirm with the user before a revert that removes files.
|
|
353
|
+
|
|
354
|
+
`thread/handoff` moves a chat and its uncommitted changes between its worktree
|
|
355
|
+
and the main checkout. The destination must be clean: "Stash or commit your
|
|
356
|
+
local changes to hand off." Archiving a thread deletes its worktree after a
|
|
357
|
+
snapshot, kept as `refs/knightcode/snapshots/<bucket>/<time>`, and
|
|
358
|
+
`thread/worktree/restore` rebuilds it. Past `worktrees.keep` worktrees, the
|
|
359
|
+
least recently used are pruned the same way. Outside a git repository, diff and
|
|
360
|
+
git methods answer `notGitRepo`.
|
|
361
|
+
|
|
362
|
+
`gitConflict` errors carry `data.reason`: `diffChanged`, `patchFailed`,
|
|
363
|
+
`concurrentChange`, `pushRejected`, `localChanges`, `operationInProgress`,
|
|
364
|
+
`branchExists`, `recoveryRequired`, `worktreeDeleted`, `worktreeMissing`,
|
|
365
|
+
`worktreeInUse` or `submodules`, with `paths`, `output` or
|
|
366
|
+
`recoveryInstructions` where they apply.
|
|
367
|
+
|
|
284
368
|
## Method reference
|
|
285
369
|
|
|
286
370
|
All methods require the handshake. Common errors are `notInitialized`,
|
|
@@ -300,12 +384,13 @@ Errors: `threadNotFound`.
|
|
|
300
384
|
|
|
301
385
|
### `config/read`
|
|
302
386
|
|
|
303
|
-
Params: optional `{cwd}`. Result: `{settings, origins, versions, errors}`.
|
|
387
|
+
Params: optional `{cwd}`. Result: `{settings, defaults, origins, versions, paths, errors}`.
|
|
304
388
|
Without cwd, only global settings are read. With cwd, trusted project settings
|
|
305
389
|
merge over global settings; untrusted project files are not read. `origins`
|
|
306
390
|
maps dotted leaf keys to `global` or `project`. `versions.global` and optional
|
|
307
391
|
`versions.project` are SHA-256 hashes of raw file contents, or `"none"` for an
|
|
308
|
-
absent or unread untrusted scope.
|
|
392
|
+
absent or unread untrusted scope. `defaults` is what an unset key means, in the
|
|
393
|
+
shape of `settings`; `paths` names the global and, with cwd, the project file. Settings, origins, versions, and parse errors
|
|
309
394
|
come from the same scope reads, not cached settings paired with fresh versions.
|
|
310
395
|
Parse errors appear as structured `source: "settings"` warnings with an
|
|
311
396
|
optional path and available one-based line/column; unaffected scopes still read.
|
|
@@ -336,6 +421,71 @@ malformed keys, and prototype-pollution segments (`__proto__`, `constructor`,
|
|
|
336
421
|
{"id":12,"method":"config/write","params":{"scope":"global","key":"theme","value":"dark","expectedVersion":"none"}}
|
|
337
422
|
```
|
|
338
423
|
|
|
424
|
+
### `tool/list`
|
|
425
|
+
|
|
426
|
+
Params: optional `{cwd}`. Result: `{tools: [{name, description, source}], defaultTools}`.
|
|
427
|
+
The tools a new thread in `cwd` would register (without cwd, a
|
|
428
|
+
project-less one), from an in-memory session like `command/list`'s; hidden tools
|
|
429
|
+
are left out, and MCP tools appear only once a thread connects. `defaultTools` is
|
|
430
|
+
the global `defaultTools` setting resolved (`+name` and `-name` applied), or the
|
|
431
|
+
built-in default `read`, `bash`, `edit`, `write`. Change it with `config/write`.
|
|
432
|
+
|
|
433
|
+
```json
|
|
434
|
+
{"id":26,"method":"tool/list","params":{}}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### `tool/settings/read` and `tool/settings/write`
|
|
438
|
+
|
|
439
|
+
The KnightCode tools `/tools` manages, stored in `tools.json` in the agent
|
|
440
|
+
directory. `tool/settings/read {}` returns
|
|
441
|
+
`{tools: [{name, enabled, settings}], classifiers: [{provider, id, name}]}`: each tool's state (its default when the
|
|
442
|
+
file does not set it) and its own settings, with values of keys ending in `Key`
|
|
443
|
+
masked to their last four characters; `classifiers` are the classifier models
|
|
444
|
+
with credentials, for the classifier gate's `model`.
|
|
445
|
+
`tool/settings/write {name, key, value}` sets one setting; `enabled` takes a boolean, other keys a string,
|
|
446
|
+
and `null` deletes the key. An unknown tool or a malformed key is
|
|
447
|
+
`invalidParams`.
|
|
448
|
+
|
|
449
|
+
```json
|
|
450
|
+
{"id":27,"method":"tool/settings/write","params":{"name":"websearch","key":"provider","value":"brave"}}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### `mcp/list`, `mcp/update`, `mcp/add` and `mcp/remove`
|
|
454
|
+
|
|
455
|
+
The servers of the global `mcp.json` and, for an explicitly trusted project, its
|
|
456
|
+
`.knightcode/mcp.json` ([MCP](mcp.md)). `mcp/list {cwd?}` returns
|
|
457
|
+
`{servers, errors, paths}`: each server's `name`, `scope`, defining file (`source`), the
|
|
458
|
+
project file that overrides it (`override`), `transport` (`stdio` or `http`),
|
|
459
|
+
`target` (command line or URL), `description`, `enabled` and `exposure`.
|
|
460
|
+
`mcp/update {cwd?, name, enabled?, exposure?}` saves the change where `/mcp`
|
|
461
|
+
would: in the project override when there is one, else in the defining file.
|
|
462
|
+
`mcp/add {scope, cwd?, name, config}` validates `config` as an `mcpServers` entry
|
|
463
|
+
and adds or replaces it (result `{replaced}`); `auth` is refused in a project
|
|
464
|
+
file. `mcp/remove {scope, cwd?, name}` returns `{removed}`. Project writes need
|
|
465
|
+
cwd and a trusted project (`invalidParams`, `data.reason: "untrusted"`).
|
|
466
|
+
Connections, sign-in and status belong to the MCP extension in each thread
|
|
467
|
+
(`/mcp`); loaded threads pick up file changes when they next load.
|
|
468
|
+
|
|
469
|
+
```json
|
|
470
|
+
{"id":28,"method":"mcp/add","params":{"scope":"global","name":"docs","config":{"url":"https://example.com/mcp"}}}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### `resource/list` and `resource/set`
|
|
474
|
+
|
|
475
|
+
Extensions, skills, prompt templates and themes as `knightcode config` lists them.
|
|
476
|
+
`resource/list {cwd?}` returns
|
|
477
|
+
`{resources: [{type, path, name, enabled, scope, origin, source}]}` for what a thread in `cwd` (or with no project) would find,
|
|
478
|
+
installing nothing. Built-in extensions are left out: they are always on, so
|
|
479
|
+
`resource/set` refuses them like any unknown path. `resource/set {cwd?, type, path, enabled}` loads or
|
|
480
|
+
skips one resource with a `+` or `-` pattern in the settings of the scope that
|
|
481
|
+
defines it: a top-level resource in that scope's `extensions`, `skills`,
|
|
482
|
+
`prompts` or `themes`, a package's in that package's filter. Project resources
|
|
483
|
+
need a trusted project; an unknown path is `invalidParams`.
|
|
484
|
+
|
|
485
|
+
```json
|
|
486
|
+
{"id":29,"method":"resource/set","params":{"type":"skills","path":"/home/u/.knightcode/agent/skills/review/SKILL.md","enabled":false}}
|
|
487
|
+
```
|
|
488
|
+
|
|
339
489
|
### `project/trust/read`
|
|
340
490
|
|
|
341
491
|
Params: `{cwd}`. Result: `{trusted, needsTrust}`. `trusted` is true, false, or
|
|
@@ -425,6 +575,136 @@ Diagnostics observe the shared server, not only this connection.
|
|
|
425
575
|
{"id":18,"method":"server/diagnostics","params":{}}
|
|
426
576
|
```
|
|
427
577
|
|
|
578
|
+
### `thread/diff/read`
|
|
579
|
+
|
|
580
|
+
Params: `{threadId, scope?, against?, commit?, context?, ignoreWhitespace?}`.
|
|
581
|
+
Result: `{scope, root, files, filesOmitted?, untrackedSkipped?, turnId?, stale?, against?}`.
|
|
582
|
+
`files` are `{path, oldPath?, status, binary, additions, deletions, tooLarge?, hunks}`,
|
|
583
|
+
their paths relative to the repository's `root` (not the thread's cwd, which can
|
|
584
|
+
be a subdirectory of it); each hunk keeps its lines with their `" "`, `"+"`, `"-"` or
|
|
585
|
+
`"\"` prefix. `committed` needs `commit`; `branch` compares with `against`,
|
|
586
|
+
else the worktree's base, the upstream or the default branch, and echoes it.
|
|
587
|
+
More than 500 untracked files are counted in `untrackedSkipped` and left out.
|
|
588
|
+
Files past the response budget come without hunks (`tooLarge`) or are only
|
|
589
|
+
counted (`filesOmitted`). A hunk id hashes the file's header (its blob ids) and
|
|
590
|
+
the hunk at the read's `context`: an action must pass the same `context` (a
|
|
591
|
+
`context: 0` id matches no action), and after an action changes a file, read it
|
|
592
|
+
again, as its other hunks' ids change too. A hunk id from an `ignoreWhitespace` read matches no
|
|
593
|
+
action. Reads take no lock and never write the user's index.
|
|
594
|
+
Errors: `threadNotFound`, `notGitRepo`; `invalidParams` for a missing `commit`
|
|
595
|
+
or no branch to compare with.
|
|
596
|
+
|
|
597
|
+
```json
|
|
598
|
+
{"id":20,"method":"thread/diff/read","params":{"threadId":"THREAD_ID","scope":"uncommitted","context":3}}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### `thread/diff/revert`
|
|
602
|
+
|
|
603
|
+
Params: `{threadId, scope?, against?, commit?, path?, hunkId?, context?, reapply?, turnId?}`.
|
|
604
|
+
With `turnId` (`lastTurn` only), a last turn other than that one answers
|
|
605
|
+
`gitConflict` `diffChanged`, so an Undo shown on one turn never reverts a newer one.
|
|
606
|
+
Result: `{paths}`. Reverse-applies one hunk, one file, or the whole scope to the
|
|
607
|
+
working tree; `lastTurn` without a path undoes the turn, and only while every
|
|
608
|
+
affected file is exactly as the turn left it. With `reapply` (`lastTurn` only,
|
|
609
|
+
no hunk), the turn's changes apply again instead, and only while every affected
|
|
610
|
+
file is exactly as the turn found it. Hunks of renamed, added, deleted,
|
|
611
|
+
binary or mode-changed files revert as whole files only. Refused while a turn
|
|
612
|
+
runs in the checkout; no turn starts and no tool runs there until it ends.
|
|
613
|
+
Errors: `turnInProgress`; `invalidParams` for `staged` and `committed` or a
|
|
614
|
+
path outside the diff; `gitConflict` with `diffChanged` or `patchFailed`.
|
|
615
|
+
|
|
616
|
+
```json
|
|
617
|
+
{"id":21,"method":"thread/diff/revert","params":{"threadId":"THREAD_ID","path":"src/a.ts","hunkId":"HUNK_ID"}}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### `thread/handoff`
|
|
621
|
+
|
|
622
|
+
Params: `{threadId, to: "local" | "worktree", branch?, environment?}`. Result:
|
|
623
|
+
`{thread, branch?, warnings}`. To the main checkout: the worktree's `HEAD`
|
|
624
|
+
becomes a branch checked out there (the worktree's own branch, else `branch`,
|
|
625
|
+
else the previous handoff's branch fast-forwarded, else
|
|
626
|
+
`<worktrees.branchPrefix><title>`), the uncommitted changes move, and the
|
|
627
|
+
worktree stays, detached and clean. Back: the worktree is detached at the main
|
|
628
|
+
checkout's `HEAD` and the changes move into it; a thread born in the main
|
|
629
|
+
checkout gets a worktree. The changes are saved under `<agentDir>/handoff/`
|
|
630
|
+
before anything moves and leave the source only after they landed. The thread
|
|
631
|
+
is reloaded where it now runs: subscribers receive `thread/replaced` with the
|
|
632
|
+
same id, and queued inputs follow it.
|
|
633
|
+
Errors: `turnInProgress`; `invalidParams` for a thread with no message yet or
|
|
634
|
+
already on that side; `gitConflict` with `localChanges`,
|
|
635
|
+
`operationInProgress`, `branchExists`, `recoveryRequired` (with `data.patch`)
|
|
636
|
+
or `worktreeDeleted`.
|
|
637
|
+
|
|
638
|
+
```json
|
|
639
|
+
{"id":22,"method":"thread/handoff","params":{"threadId":"THREAD_ID","to":"local"}}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### `thread/worktree/restore`
|
|
643
|
+
|
|
644
|
+
Params: `{threadId}`. Result: `{thread}`. Rebuilds a deleted worktree at its
|
|
645
|
+
old path from its snapshot: detached at the old `HEAD`, with the working files
|
|
646
|
+
and the staged state as they were (ignored files were not kept). Then the
|
|
647
|
+
thread loads there.
|
|
648
|
+
Errors: `threadNotFound`; `invalidParams` when the worktree is not deleted;
|
|
649
|
+
`gitConflict` with `worktreeMissing` (deleted without a snapshot: fork the chat
|
|
650
|
+
into a new worktree instead) or `submodules`.
|
|
651
|
+
|
|
652
|
+
```json
|
|
653
|
+
{"id":23,"method":"thread/worktree/restore","params":{"threadId":"THREAD_ID"}}
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### `worktree/list` and `worktree/delete`
|
|
657
|
+
|
|
658
|
+
`worktree/list {cwd?}` →
|
|
659
|
+
`{worktrees: [{path, projectCwd, head?, branch?, threadIds, lastUsedAt, deleted}]}`,
|
|
660
|
+
the managed worktrees (of `cwd`'s project
|
|
661
|
+
when given). `worktree/delete {path}` → `{snapshot?}` deletes one after its
|
|
662
|
+
snapshot. A worktree a thread is loaded in, or one holding a nested repository
|
|
663
|
+
(an initialized submodule or a repository inside it), is never deleted: archive
|
|
664
|
+
and pruning skip it, and `worktree/delete` answers `gitConflict` with
|
|
665
|
+
`worktreeInUse` or `submodules`. Only registrations in the managed layout are
|
|
666
|
+
removed; the user's own worktrees are never touched.
|
|
667
|
+
|
|
668
|
+
```json
|
|
669
|
+
{"id":24,"method":"worktree/delete","params":{"path":"/home/u/.knightcode/agent/worktrees/ab12/project"}}
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
### `environment/list` and `environment/save`
|
|
673
|
+
|
|
674
|
+
`environment/list {cwd}` → `{environments, trusted}` reads the project's
|
|
675
|
+
`.knightcode/environments.json`; `environment/save {cwd, environments}` writes
|
|
676
|
+
it (names unique, at most 50). An untrusted project's scripts never run. See
|
|
677
|
+
[Settings](settings.md#worktrees).
|
|
678
|
+
|
|
679
|
+
```json
|
|
680
|
+
{"id":25,"method":"environment/save","params":{"cwd":"/p","environments":[{"name":"node","setup":{"default":"cd \"$KNIGHTCODE_WORKTREE_PATH\" && npm ci"}}]}}
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### `git/*`
|
|
684
|
+
|
|
685
|
+
Each acts on the thread's own checkout: its worktree, or the user's checkout.
|
|
686
|
+
`git/status` → branch, upstream, ahead/behind, staged/unstaged/untracked/
|
|
687
|
+
conflicted counts and an operation in progress. `git/stage` and `git/unstage`
|
|
688
|
+
take `{threadId, path?, hunkId?, context?}`: no path is everything; paths are
|
|
689
|
+
literal. `git/commit {threadId, message?, includeUnstaged?}` stages everything
|
|
690
|
+
first unless `includeUnstaged: false`; an empty message is written by the
|
|
691
|
+
thread's model from the staged diff, outside the conversation, and the commit
|
|
692
|
+
answers `concurrentChange` when the checkout changed meanwhile. The user's
|
|
693
|
+
hooks run. `git/push` pushes the current branch with one explicit,
|
|
694
|
+
non-forcing refspec and sets the upstream the first time.
|
|
695
|
+
`git/pr/create {threadId, title?, body?, draft?}` runs `gh pr create` (`toolMissing` without
|
|
696
|
+
`gh`). `git/branches`, `git/branch/create {name}` ("Create branch here"),
|
|
697
|
+
`git/branch/switch {name}` (refused when it would overwrite local changes or an
|
|
698
|
+
ignored file the branch tracks) and `git/log {limit?}` (the commits since the
|
|
699
|
+
base, for the `committed` scope) complete the set.
|
|
700
|
+
Errors: `notGitRepo`, `invalidParams`, `authRequired`, `toolMissing`;
|
|
701
|
+
`gitConflict` with `diffChanged`, `patchFailed`, `concurrentChange`,
|
|
702
|
+
`pushRejected`, `branchExists` or `localChanges`.
|
|
703
|
+
|
|
704
|
+
```json
|
|
705
|
+
{"id":26,"method":"git/commit","params":{"threadId":"THREAD_ID","includeUnstaged":true}}
|
|
706
|
+
```
|
|
707
|
+
|
|
428
708
|
## Ownership, unloading, and shutdown
|
|
429
709
|
|
|
430
710
|
Only one process may own a persisted session file. Symlink/junction aliases share
|