@knightcodeai/cli 0.17.3 → 0.18.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.
Files changed (281) hide show
  1. package/CHANGELOG.md +1293 -0
  2. package/README.md +2 -2
  3. package/dist/bundle/chunks/anthropic-messages-A2IH2IY3.js +6 -0
  4. package/dist/bundle/chunks/anthropic.js +101 -0
  5. package/dist/bundle/chunks/azure-openai-responses-XZILQZOG.js +2 -0
  6. package/dist/bundle/chunks/bedrock-converse-stream.js +89 -0
  7. package/dist/bundle/chunks/chunk-4CRI7BMY.js +2 -0
  8. package/dist/bundle/chunks/chunk-57BPR4HF.js +2 -0
  9. package/dist/bundle/chunks/chunk-A5LJINMT.js +2 -0
  10. package/dist/bundle/chunks/chunk-AANBXVWQ.js +2 -0
  11. package/dist/bundle/chunks/chunk-ACHHEROF.js +7 -0
  12. package/dist/bundle/chunks/chunk-AFR2OW6S.js +108 -0
  13. package/dist/bundle/chunks/chunk-AHB7JV5B.js +2 -0
  14. package/dist/bundle/chunks/chunk-B2FT7RH5.js +2 -0
  15. package/dist/bundle/chunks/chunk-BRKUE2MD.js +2 -0
  16. package/dist/bundle/chunks/chunk-DKOURXGU.js +2 -0
  17. package/dist/bundle/chunks/chunk-DVFCXHT4.js +2 -0
  18. package/dist/bundle/chunks/chunk-EPYT326Y.js +30 -0
  19. package/dist/bundle/chunks/chunk-ETOMYYZC.js +2 -0
  20. package/dist/bundle/chunks/chunk-FA32X2UJ.js +7 -0
  21. package/dist/bundle/chunks/chunk-FHM6KUY3.js +44 -0
  22. package/dist/bundle/chunks/chunk-FO7CEQB3.js +11 -0
  23. package/dist/bundle/chunks/chunk-GHVXUCGU.js +130 -0
  24. package/dist/bundle/chunks/chunk-HHWP56PR.js +2 -0
  25. package/dist/bundle/chunks/chunk-HSL72VZI.js +2 -0
  26. package/dist/bundle/chunks/chunk-HUQB436V.js +2 -0
  27. package/dist/bundle/chunks/chunk-HWXGL4YB.js +2 -0
  28. package/dist/bundle/chunks/chunk-KQKUEQJA.js +6 -0
  29. package/dist/bundle/chunks/chunk-M5GCRGV6.js +1333 -0
  30. package/dist/bundle/chunks/chunk-MB4QRS7Y.js +9 -0
  31. package/dist/bundle/chunks/chunk-MXIWLMNT.js +8 -0
  32. package/dist/bundle/chunks/chunk-N6VDWLND.js +2 -0
  33. package/dist/bundle/chunks/chunk-NCIBB66G.js +2 -0
  34. package/dist/bundle/chunks/chunk-NDQ5OW6U.js +2 -0
  35. package/dist/bundle/chunks/chunk-NNCIIYD6.js +2 -0
  36. package/dist/bundle/chunks/chunk-O6JSP6YG.js +6 -0
  37. package/dist/bundle/chunks/chunk-OFST7FDG.js +2 -0
  38. package/dist/bundle/chunks/chunk-SPAUY3RD.js +12 -0
  39. package/dist/bundle/chunks/chunk-U5XE4RWR.js +2 -0
  40. package/dist/bundle/chunks/chunk-UZWP3NHW.js +2 -0
  41. package/dist/bundle/chunks/chunk-V5ANFNKF.js +11 -0
  42. package/dist/bundle/chunks/chunk-VJJ6J35N.js +20 -0
  43. package/dist/bundle/chunks/chunk-XIRAUXOE.js +58 -0
  44. package/dist/bundle/chunks/chunk-ZW7FVRHT.js +31 -0
  45. package/dist/bundle/chunks/cli-6ZTWO6GL.js +51 -0
  46. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-6E2UM7IG.js +2 -0
  47. package/dist/bundle/chunks/codemode-worker.js +478 -0
  48. package/dist/bundle/chunks/dist-DKI7Q6GY.js +13 -0
  49. package/dist/bundle/chunks/easter-egg-3d-FDCGDUF3.js +2 -0
  50. package/dist/bundle/chunks/execute-VSDU5VSN.js +499 -0
  51. package/dist/bundle/chunks/github-copilot.js +2 -0
  52. package/dist/bundle/chunks/google-generative-ai-CSWR3ORZ.js +2 -0
  53. package/dist/bundle/chunks/google-vertex-QIDRFOFB.js +2 -0
  54. package/dist/bundle/chunks/image-resize-worker.js +2 -0
  55. package/dist/bundle/chunks/jiti-loader-BXVX3Y2R.js +21 -0
  56. package/dist/bundle/chunks/jiti-static-loader-NNBCFAO5.js +2 -0
  57. package/dist/bundle/chunks/kimi-coding.js +2 -0
  58. package/dist/bundle/chunks/knightcode-messages-3GNOTMSI.js +8 -0
  59. package/dist/bundle/chunks/lib-IHWMWJDR.js +9 -0
  60. package/dist/bundle/chunks/llama-cpp-classify-HRPRKOZA.js +22 -0
  61. package/dist/bundle/chunks/meta.js +2 -0
  62. package/dist/bundle/chunks/mistral-conversations-46TK5OBA.js +5 -0
  63. package/dist/bundle/chunks/multipart-parser-VTTMF2EO.js +3 -0
  64. package/dist/bundle/chunks/node-7S3GFMOZ.js +16 -0
  65. package/dist/bundle/chunks/node-MAEICQNS.js +2 -0
  66. package/dist/bundle/chunks/openai-chatgpt.js +101 -0
  67. package/dist/bundle/chunks/openai-codex-responses-IT7VEKUU.js +10 -0
  68. package/dist/bundle/chunks/openai-codex.js +101 -0
  69. package/dist/bundle/chunks/openai-completions-LOKIW33V.js +7 -0
  70. package/dist/bundle/chunks/openai-decisions-4F3LWHMG.js +5 -0
  71. package/dist/bundle/chunks/openai-responses-OK36GJXP.js +3 -0
  72. package/dist/bundle/chunks/openrouter-images-ZI7LLZ4Y.js +2 -0
  73. package/dist/bundle/chunks/openrouter.js +101 -0
  74. package/dist/bundle/chunks/radius.js +101 -0
  75. package/dist/bundle/chunks/runtime-RMPIV5AR.js +2 -0
  76. package/dist/bundle/chunks/src-ETRMT73D.js +4 -0
  77. package/dist/bundle/chunks/typesafe-system-one-J2CJBWEH.js +2 -0
  78. package/dist/bundle/chunks/virtual-modules-EGJP3AJA.js +2 -0
  79. package/dist/bundle/chunks/xai.js +2 -0
  80. package/dist/bundle/cli-runtime.js +3 -0
  81. package/dist/bundle/cli.js +5 -0
  82. package/dist/bundle/native/darwin/prebuilds/darwin-arm64/darwin-platform.node +0 -0
  83. package/dist/bundle/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
  84. package/dist/bundle/native/linux/prebuilds/linux-arm64/linux-platform-x11.node +0 -0
  85. package/dist/bundle/native/linux/prebuilds/linux-x64/linux-platform-x11.node +0 -0
  86. package/dist/bundle/native/win32/prebuilds/win32-arm64/win32-platform.node +0 -0
  87. package/dist/bundle/native/win32/prebuilds/win32-x64/win32-platform.node +0 -0
  88. package/dist/core/export-html/template.css +1015 -0
  89. package/dist/core/export-html/template.html +55 -0
  90. package/dist/core/export-html/template.js +1929 -0
  91. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  92. package/dist/core/export-html/vendor/marked.min.js +78 -0
  93. package/dist/modes/interactive/theme/dark.json +74 -0
  94. package/dist/modes/interactive/theme/light.json +74 -0
  95. package/dist/modes/interactive/theme/system-theme.ts +579 -0
  96. package/dist/modes/interactive/theme/theme-controller.ts +253 -0
  97. package/dist/modes/interactive/theme/theme-schema.ts +145 -0
  98. package/dist/modes/interactive/theme/theme-tokens.ts +145 -0
  99. package/dist/modes/interactive/theme/theme.ts +1076 -0
  100. package/docs/app-server.md +479 -0
  101. package/docs/app-server.schema.json +8128 -0
  102. package/docs/cli-integration.md +106 -0
  103. package/docs/cli.md +393 -0
  104. package/docs/codemode.md +230 -0
  105. package/docs/compaction.md +463 -0
  106. package/docs/configuration.md +48 -0
  107. package/docs/containerization.md +143 -0
  108. package/docs/custom-provider.md +173 -0
  109. package/docs/desktop.md +73 -0
  110. package/docs/docs.json +236 -0
  111. package/docs/environment-variables.md +138 -0
  112. package/docs/extensions.md +314 -0
  113. package/docs/how-knightcode-works.md +49 -0
  114. package/docs/images/doom-extension.png +0 -0
  115. package/docs/images/interactive-mode.png +0 -0
  116. package/docs/images/tree-view.png +0 -0
  117. package/docs/index.md +39 -0
  118. package/docs/json.md +226 -0
  119. package/docs/keybindings.md +197 -0
  120. package/docs/llama-cpp.md +121 -0
  121. package/docs/mcp.md +272 -0
  122. package/docs/message-types.md +279 -0
  123. package/docs/models-configuration.md +187 -0
  124. package/docs/models.md +221 -0
  125. package/docs/nvidia-rtx-llama-cpp.md +96 -0
  126. package/docs/packages.md +129 -0
  127. package/docs/plan-mode.md +121 -0
  128. package/docs/prompt-templates.md +59 -0
  129. package/docs/providers.md +282 -0
  130. package/docs/quickstart.md +128 -0
  131. package/docs/remote.md +87 -0
  132. package/docs/rpc-commands.md +860 -0
  133. package/docs/rpc-extension-ui.md +214 -0
  134. package/docs/rpc.md +193 -0
  135. package/docs/sdk.md +197 -0
  136. package/docs/security.md +99 -0
  137. package/docs/session-format.md +358 -0
  138. package/docs/sessions.md +135 -0
  139. package/docs/settings.md +220 -0
  140. package/docs/shell-aliases.md +93 -0
  141. package/docs/skills.md +93 -0
  142. package/docs/slash-commands.md +78 -0
  143. package/docs/terminal-setup.md +242 -0
  144. package/docs/termux.md +117 -0
  145. package/docs/themes.md +140 -0
  146. package/docs/tmux.md +55 -0
  147. package/docs/tui.md +125 -0
  148. package/docs/usage.md +167 -0
  149. package/docs/virtual-models.md +114 -0
  150. package/docs/windows.md +67 -0
  151. package/examples/README.md +36 -0
  152. package/examples/extensions/README.md +214 -0
  153. package/examples/extensions/auto-commit-on-exit.ts +55 -0
  154. package/examples/extensions/bash-spawn-hook.ts +30 -0
  155. package/examples/extensions/bookmark.ts +50 -0
  156. package/examples/extensions/border-status-editor.ts +151 -0
  157. package/examples/extensions/built-in-tool-renderer.ts +225 -0
  158. package/examples/extensions/claude-rules.ts +89 -0
  159. package/examples/extensions/commands.ts +72 -0
  160. package/examples/extensions/confirm-destructive.ts +60 -0
  161. package/examples/extensions/custom-compaction.ts +118 -0
  162. package/examples/extensions/custom-footer.ts +66 -0
  163. package/examples/extensions/custom-header.ts +73 -0
  164. package/examples/extensions/custom-provider-anthropic/index.ts +617 -0
  165. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  166. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  167. package/examples/extensions/custom-provider-gitlab-duo/index.ts +399 -0
  168. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  169. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  170. package/examples/extensions/debug-provider.ts +90 -0
  171. package/examples/extensions/dirty-repo-guard.ts +56 -0
  172. package/examples/extensions/doom-overlay/README.md +46 -0
  173. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  174. package/examples/extensions/doom-overlay/doom/doomgeneric_knightcode.c +72 -0
  175. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  176. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  177. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  178. package/examples/extensions/doom-overlay/index.ts +74 -0
  179. package/examples/extensions/doom-overlay/wad-finder.ts +55 -0
  180. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  181. package/examples/extensions/dynamic-resources/dynamic.json +75 -0
  182. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  183. package/examples/extensions/dynamic-resources/index.ts +15 -0
  184. package/examples/extensions/dynamic-tools.ts +74 -0
  185. package/examples/extensions/entry-renderer.ts +41 -0
  186. package/examples/extensions/event-bus.ts +43 -0
  187. package/examples/extensions/file-trigger.ts +41 -0
  188. package/examples/extensions/git-checkpoint.ts +53 -0
  189. package/examples/extensions/git-merge-and-resolve.ts +115 -0
  190. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  191. package/examples/extensions/gondolin/index.ts +531 -0
  192. package/examples/extensions/gondolin/package-lock.json +185 -0
  193. package/examples/extensions/gondolin/package.json +19 -0
  194. package/examples/extensions/handoff.ts +190 -0
  195. package/examples/extensions/hello.ts +26 -0
  196. package/examples/extensions/hidden-thinking-label.ts +53 -0
  197. package/examples/extensions/inline-bash.ts +94 -0
  198. package/examples/extensions/input-transform-streaming.ts +39 -0
  199. package/examples/extensions/input-transform.ts +43 -0
  200. package/examples/extensions/interactive-shell.ts +196 -0
  201. package/examples/extensions/jev-router.ts +113 -0
  202. package/examples/extensions/mac-system-theme.ts +47 -0
  203. package/examples/extensions/message-renderer.ts +59 -0
  204. package/examples/extensions/minimal-mode.ts +353 -0
  205. package/examples/extensions/modal-editor.ts +85 -0
  206. package/examples/extensions/model-status.ts +31 -0
  207. package/examples/extensions/notify.ts +57 -0
  208. package/examples/extensions/overlay-qa-tests.ts +1450 -0
  209. package/examples/extensions/overlay-test.ts +153 -0
  210. package/examples/extensions/permission-gate.ts +34 -0
  211. package/examples/extensions/pirate.ts +47 -0
  212. package/examples/extensions/plan-mode/README.md +66 -0
  213. package/examples/extensions/plan-mode/index.ts +387 -0
  214. package/examples/extensions/plan-mode/utils.ts +168 -0
  215. package/examples/extensions/preset.ts +436 -0
  216. package/examples/extensions/project-trust.ts +64 -0
  217. package/examples/extensions/prompt-customizer.ts +49 -0
  218. package/examples/extensions/protected-paths.ts +30 -0
  219. package/examples/extensions/provider-payload.ts +18 -0
  220. package/examples/extensions/qna.ts +118 -0
  221. package/examples/extensions/question.ts +278 -0
  222. package/examples/extensions/questionnaire.ts +440 -0
  223. package/examples/extensions/rainbow-editor.ts +88 -0
  224. package/examples/extensions/reload-runtime.ts +37 -0
  225. package/examples/extensions/rpc-demo.ts +118 -0
  226. package/examples/extensions/sandbox/index.ts +321 -0
  227. package/examples/extensions/sandbox/package-lock.json +92 -0
  228. package/examples/extensions/sandbox/package.json +19 -0
  229. package/examples/extensions/send-user-message.ts +97 -0
  230. package/examples/extensions/session-name.ts +27 -0
  231. package/examples/extensions/shutdown-command.ts +63 -0
  232. package/examples/extensions/snake.ts +343 -0
  233. package/examples/extensions/space-invaders.ts +560 -0
  234. package/examples/extensions/ssh.ts +220 -0
  235. package/examples/extensions/status-line.ts +32 -0
  236. package/examples/extensions/structured-output.ts +65 -0
  237. package/examples/extensions/subagent/README.md +177 -0
  238. package/examples/extensions/subagent/agents/planner.md +37 -0
  239. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  240. package/examples/extensions/subagent/agents/scout.md +50 -0
  241. package/examples/extensions/subagent/agents/worker.md +24 -0
  242. package/examples/extensions/subagent/agents.ts +157 -0
  243. package/examples/extensions/subagent/index.ts +1010 -0
  244. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  245. package/examples/extensions/subagent/prompts/implement.md +10 -0
  246. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  247. package/examples/extensions/summarize.ts +199 -0
  248. package/examples/extensions/system-prompt-header.ts +17 -0
  249. package/examples/extensions/tic-tac-toe.ts +1004 -0
  250. package/examples/extensions/timed-confirm.ts +70 -0
  251. package/examples/extensions/titlebar-spinner.ts +58 -0
  252. package/examples/extensions/todo.ts +294 -0
  253. package/examples/extensions/tool-override.ts +144 -0
  254. package/examples/extensions/tools.ts +146 -0
  255. package/examples/extensions/trigger-compact.ts +50 -0
  256. package/examples/extensions/truncated-tool.ts +195 -0
  257. package/examples/extensions/widget-placement.ts +9 -0
  258. package/examples/extensions/with-deps/index.ts +32 -0
  259. package/examples/extensions/with-deps/package-lock.json +31 -0
  260. package/examples/extensions/with-deps/package.json +22 -0
  261. package/examples/extensions/working-indicator.ts +121 -0
  262. package/examples/extensions/working-message-test.ts +25 -0
  263. package/examples/rpc-client.ts +35 -0
  264. package/examples/rpc-extension-ui.ts +661 -0
  265. package/examples/sdk/01-minimal.ts +26 -0
  266. package/examples/sdk/02-custom-model.ts +49 -0
  267. package/examples/sdk/03-custom-prompt.ts +70 -0
  268. package/examples/sdk/04-skills.ts +55 -0
  269. package/examples/sdk/05-tools.ts +48 -0
  270. package/examples/sdk/06-extensions.ts +94 -0
  271. package/examples/sdk/07-context-files.ts +42 -0
  272. package/examples/sdk/08-prompt-templates.ts +51 -0
  273. package/examples/sdk/09-api-keys-and-oauth.ts +34 -0
  274. package/examples/sdk/10-settings.ts +53 -0
  275. package/examples/sdk/11-sessions.ts +52 -0
  276. package/examples/sdk/12-full-control.ts +74 -0
  277. package/examples/sdk/13-session-runtime.ts +67 -0
  278. package/examples/sdk/14-codemode-mcp.ts +61 -0
  279. package/examples/sdk/README.md +141 -0
  280. package/package.json +15 -15
  281. package/bin/knightcode +0 -62
@@ -0,0 +1,99 @@
1
+ # Run KnightCode safely
2
+
3
+ Treat model-generated commands and code as untrusted. KnightCode can read, change, and execute files with the permissions of the account that started it, and it does not ask for approval before every tool call. Extensions, package installers, language servers, and other child processes run with those same permissions unless an operating-system or virtualization boundary restricts them.
4
+
5
+ Files, comments, instructions, command output, and model responses can steer the model through prompt injection. Project trust controls which project resources load at startup, but it does not make that content or the resulting actions safe.
6
+
7
+ Safety comes from limiting the files, credentials, processes, and network services KnightCode can access and affect if a generated action is wrong or hostile. Watching the transcript, using project trust, and reviewing changes do not create a security boundary.
8
+
9
+ ## Choose how to run KnightCode
10
+
11
+ Different ways of running KnightCode place different limits on what generated commands can access:
12
+
13
+ | How KnightCode runs | What remains protected |
14
+ |---|---|
15
+ | Directly, with the permissions of its operating-system user | Anything that user cannot access. A dedicated user account can narrow those permissions, but KnightCode still shares the operating system and network with other users. |
16
+ | Entirely inside a container, virtual machine, or sandbox | Host files and processes that you do not expose to the environment. Credentials and network services remain accessible if you make them available inside it. This is usually the strongest practical option. |
17
+ | Outside the isolated environment, with only its built-in tools running inside | Host resources are protected from actions performed through those tools. KnightCode itself and other extensions remain outside the boundary, so this is a narrower form of isolation. |
18
+
19
+ The working folder controls resource discovery and the default location for tools, but it does not prevent commands from accessing other paths available to the KnightCode process.
20
+
21
+ Whichever option you choose, only provide the files and services required for the task. Keep credentials outside the environment where possible, or use narrowly scoped, short-lived credentials. Restrict network access when commands do not need it.
22
+
23
+ For setup instructions and the limitations of each isolation method, see [Run KnightCode in an isolated environment](containerization.md).
24
+
25
+ <a id="project-trust"></a>
26
+
27
+ ## Understand project trust
28
+
29
+ Project trust controls whether KnightCode loads most settings and resources supplied by a working folder. It prevents a folder from silently loading executable extensions before you approve it.
30
+
31
+ Project trust is not a complete startup boundary. KnightCode reads the project `sessionDir` setting while selecting or creating a session, before it resolves project trust. Declining trust prevents the remaining project settings and protected resources from loading, but it cannot undo that initial session-directory lookup.
32
+
33
+ Project trust does not limit what tool calls can access or affect. After KnightCode starts, enabled tools still use the operating-system permissions of the KnightCode process. Instructions and other content in the folder can also influence the model.
34
+
35
+ ### Resources protected by project trust
36
+
37
+ KnightCode requires a project-trust decision when it finds any of these resources from the current working directory:
38
+
39
+ - `.knightcode/settings.json`
40
+ - `.knightcode/mcp.json`
41
+ - `.knightcode/extensions`, `.knightcode/skills`, `.knightcode/prompts`, or `.knightcode/themes`
42
+ - `.knightcode/SYSTEM.md` or `.knightcode/APPEND_SYSTEM.md`
43
+ - project `.agents/skills` in the current directory or an ancestor directory
44
+
45
+ A bare `.knightcode` directory does not require project trust.
46
+
47
+ Granting project trust allows KnightCode to load:
48
+
49
+ - project settings
50
+ - project MCP servers from `.knightcode/mcp.json`
51
+ - extensions, skills, prompt templates, themes, and system-prompt files under `.knightcode`
52
+ - missing packages configured through project settings
53
+ - project-local and project-package extensions
54
+
55
+ Declining project trust skips those protected resources, except for the initial `sessionDir` lookup described above.
56
+
57
+ Context files such as `AGENTS.override.md`, `AGENTS.md`, and `CLAUDE.md` load regardless of project trust unless you disable context loading. Treat instructions in a folder as untrusted input even when you decline project trust.
58
+
59
+ ### How KnightCode chooses a trust decision
60
+
61
+ A command-line `--approve` or `--no-approve` override applies first. When protected resources exist and there is no command-line override:
62
+
63
+ 1. User-level and command-line extensions can handle the `project_trust` event. The first extension that returns yes or no owns the decision.
64
+ 2. If no extension decides, KnightCode looks for a saved decision for the current directory or one of its parents. The closest decision applies.
65
+ 3. If no saved decision applies, KnightCode follows the global `defaultProjectTrust` setting, whose default is `"ask"`.
66
+
67
+ Saved decisions use canonical directory paths and live in:
68
+
69
+ ```text
70
+ ~/.knightcode/agent/trust.json
71
+ ```
72
+
73
+ Use `/trust` to save a decision for future KnightCode processes.
74
+
75
+ ### Project trust without an interactive prompt
76
+
77
+ Print, JSON, and RPC modes cannot show the built-in trust prompt. If no command-line override, extension, or saved decision applies:
78
+
79
+ - `defaultProjectTrust: "always"` loads protected project resources.
80
+ - `defaultProjectTrust: "ask"` or `"never"` skips them.
81
+
82
+ Use `--approve` or `--no-approve` when an automated run needs an explicit one-time decision.
83
+
84
+ ## Reduce impact and improve recovery
85
+
86
+ These practices do not replace isolation, but they reduce exposure or make recovery easier:
87
+
88
+ - Give KnightCode access only to files and services required for the task.
89
+ - Use snapshots, backups, or version control before substantial changes.
90
+ - Review extensions and packages before loading them. Extensions execute inside the KnightCode process.
91
+ - Prefer narrowly scoped, short-lived credentials.
92
+ - Review diffs and generated output before applying results to another system.
93
+ - Review sessions before exporting or sharing them. They can contain prompts, tool arguments, command output, file contents, and credentials exposed during the conversation.
94
+
95
+ ## Report a security issue
96
+
97
+ Follow the repository [Security Policy](https://github.com/KnightCodeAI/knightcode/blob/main/SECURITY.md). Do not open a public issue for a security-sensitive report.
98
+
99
+ Expected local-agent behavior, prompt injection from untrusted content, lack of a built-in sandbox, and behavior from user-installed extensions or skills are generally outside the security boundary unless the report demonstrates a privilege-boundary bypass or access that the local user did not already have.
@@ -0,0 +1,358 @@
1
+ # Session File Format
2
+
3
+ Sessions are stored as JSONL (JSON Lines) files. Each line is a JSON object with a `type` field. Session entries form a tree structure via `id`/`parentId` fields, enabling in-place branching without creating new files.
4
+
5
+ For programmatic creation, persistence, and tree navigation, see the [`SessionManager` API](sdk.md#sessionmanager-api).
6
+
7
+
8
+ ## File Location
9
+
10
+ ```
11
+ ~/.knightcode/agent/sessions/--<path>--/<timestamp>_<session-id>.jsonl
12
+ ```
13
+
14
+ By default, `<session-id>` is a UUID. Callers can supply a custom ID through the SDK or `--session-id`. For `<path>`, KnightCode removes the leading path separator and replaces `/`, `\\`, and `:` with `-`.
15
+
16
+ ## Deleting Sessions
17
+
18
+ Sessions can be removed by deleting their `.jsonl` files under `~/.knightcode/agent/sessions/`.
19
+
20
+ KnightCode also supports deleting sessions interactively from `/resume` (select a session and press `Ctrl+D`, then confirm). When available, knightcode uses the `trash` CLI to avoid permanent deletion.
21
+
22
+ ## Session Version
23
+
24
+ Sessions have a version field in the header:
25
+
26
+ - **Version 1**: Linear entry sequence (legacy, auto-migrated on load)
27
+ - **Version 2**: Tree structure with `id`/`parentId` linking
28
+ - **Version 3**: Renamed `hookMessage` role to `custom` (extensions unification)
29
+
30
+ Existing sessions are automatically migrated to the current version (v3) when
31
+ opened by an owning manager. Read-only discovery, history, export, and fork-source
32
+ reads do not rewrite or migrate the source file. See [ownership](sessions.md#session-ownership).
33
+
34
+ ## Source Files
35
+
36
+ Source on GitHub ([knightcode](https://github.com/KnightCodeAI/knightcode)):
37
+ - [`packages/cli/src/core/session-manager.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/core/session-manager.ts) - Session entry types and SessionManager
38
+ - [Message Types](message-types.md) - Shared message and content-block reference
39
+ - [`packages/cli/src/core/messages.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/cli/src/core/messages.ts) - Extended message types
40
+ - [`packages/ai/src/types.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/ai/src/types.ts) - Base message and content-block types
41
+ - [`packages/agent/src/types.ts`](https://github.com/KnightCodeAI/knightcode/blob/main/packages/agent/src/types.ts) - Extensible `AgentMessage` union
42
+
43
+ For TypeScript definitions in your project, inspect `node_modules/@knightcodeai/cli/dist/` and `node_modules/@knightcode/ai/dist/`.
44
+
45
+ ## Messages
46
+
47
+ A `message` entry stores an [`AgentMessage`](message-types.md). Message content blocks, roles, usage, and message timestamps are defined in [Message Types](message-types.md).
48
+
49
+ Session entry timestamps are ISO 8601 strings. The nested message timestamp is a Unix timestamp in milliseconds.
50
+
51
+ ## Entry Base
52
+
53
+ All entries (except `SessionHeader`) extend `SessionEntryBase`:
54
+
55
+ ```typescript
56
+ interface SessionEntryBase {
57
+ type: string;
58
+ id: string; // Usually an 8-char hex ID; may fall back to a full UUID
59
+ parentId: string | null; // Parent entry ID (null for a root entry)
60
+ timestamp: string; // ISO timestamp
61
+ }
62
+ ```
63
+
64
+ ## Entry Types
65
+
66
+ ### SessionHeader
67
+
68
+ First line of the file. Metadata only, not part of the tree (no `id`/`parentId`).
69
+
70
+ ```json
71
+ {"type":"session","version":3,"id":"uuid","timestamp":"2024-12-03T14:00:00.000Z","cwd":"/path/to/project"}
72
+ ```
73
+
74
+ For sessions with a parent (created via `/fork`, `/clone`, or `newSession({ parentSession })`):
75
+
76
+ ```json
77
+ {"type":"session","version":3,"id":"uuid","timestamp":"2024-12-03T14:00:00.000Z","cwd":"/path/to/project","parentSession":"/path/to/original/session.jsonl"}
78
+ ```
79
+
80
+ ### SessionMessageEntry
81
+
82
+ A message in the conversation. The `message` field contains an `AgentMessage`. System messages carry the prompt and tool loadout: the first request of a session persists one with every prompt section and tool declaration, and later changes persist as system messages that patch `sections` by name (`null` removes one) and list `toolsAdded`/`toolsRemoved`. Replaying them in order yields the current prompt and tools; there is no separate prompt state entry.
83
+
84
+ ```json
85
+ {"type":"message","id":"a0b1c2d3","parentId":null,"timestamp":"2024-12-03T14:00:00.000Z","message":{"role":"system","content":"","sections":{"preamble":"You are an expert coding assistant...","tools":"<tools>\n- read: ...\n</tools>","cwd":"/project"},"toolsAdded":[{"name":"read","description":"...","parameters":{}}],"timestamp":1733234400000}}
86
+ {"type":"message","id":"d4e5f6g7","parentId":"c3d4e5f6","timestamp":"2024-12-03T14:04:00.000Z","message":{"role":"system","content":"","sections":{"skills":"<skills>...</skills>"},"toolsRemoved":[{"name":"write"}],"timestamp":1733234640000}}
87
+ ```
88
+
89
+ Sessions created before system messages existed have no leading system message; the first request declares the current prompt as a later system message, which replays the same way.
90
+
91
+ ```json
92
+ {"type":"message","id":"a1b2c3d4","parentId":"prev1234","timestamp":"2024-12-03T14:00:01.000Z","message":{"role":"user","content":"Hello","timestamp":1733234401000}}
93
+ {"type":"message","id":"b2c3d4e5","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:00:02.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}],"api":"anthropic-messages","provider":"anthropic","model":"claude-sonnet-4-5","usage":{...},"stopReason":"stop","timestamp":1733234402000}}
94
+ {"type":"message","id":"c3d4e5f6","parentId":"b2c3d4e5","timestamp":"2024-12-03T14:00:03.000Z","message":{"role":"toolResult","toolCallId":"call_123","toolName":"bash","content":[{"type":"text","text":"output"}],"isError":false,"timestamp":1733234403000}}
95
+ ```
96
+
97
+ Assistant messages name the model that produced them. Newer messages also record `thinkingLevel`, the KnightCode thinking level requested for that response.
98
+
99
+ Assistant `durationMs`, when present, measures the reply from its numeric
100
+ `timestamp`; the app server derives final text/reasoning completion times from
101
+ these fields.
102
+
103
+ ### ModelChangeEntry
104
+
105
+ Emitted when the user switches models mid-session. The latest entry is the selected model, which may be a [virtual model](virtual-models.md); assistant messages then name the physical model that answered.
106
+
107
+ ```json
108
+ {"type":"model_change","id":"d4e5f6g7","parentId":"c3d4e5f6","timestamp":"2024-12-03T14:05:00.000Z","provider":"openai","modelId":"gpt-4o"}
109
+ ```
110
+
111
+ ### ThinkingLevelChangeEntry
112
+
113
+ Emitted when the user changes the thinking/reasoning level.
114
+
115
+ ```json
116
+ {"type":"thinking_level_change","id":"e5f6g7h8","parentId":"d4e5f6g7","timestamp":"2024-12-03T14:06:00.000Z","thinkingLevel":"high"}
117
+ ```
118
+
119
+ ### UsageEntry
120
+
121
+ Records model-attributed usage that is not an assistant message and does not participate in LLM context. `kind` is an arbitrary string identifying the operation; for example, cache warming uses `"cache_warm"`.
122
+
123
+ ```json
124
+ {"type":"usage","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:08:00.000Z","kind":"cache_warm","provider":"anthropic","model":"claude-sonnet-4-5","usage":{"input":0,"output":0,"cacheRead":50000,"cacheWrite":0,"totalTokens":50000,"cost":{"input":0,"output":0,"cacheRead":0.015,"cacheWrite":0,"total":0.015}}}
125
+ ```
126
+
127
+ Usage entries contribute to session token and cost totals. KnightCode hides them from the conversation tree. Consumers should treat unknown `kind` values as normal usage rather than rejecting them.
128
+
129
+ ### CompactionEntry
130
+
131
+ Created when context is compacted. Stores a summary of earlier messages and a complete system prompt/tool checkpoint.
132
+
133
+ ```json
134
+ {"type":"compaction","id":"f6g7h8i9","parentId":"e5f6g7h8","timestamp":"2024-12-03T14:10:00.000Z","summary":"User discussed X, Y, Z...","firstKeptEntryId":"c3d4e5f6","tokensBefore":50000,"systemMessage":{"role":"system","content":"You are a coding assistant.","toolsAdded":[],"timestamp":1733235000000}}
135
+ ```
136
+
137
+ `firstKeptEntryId` is required. It identifies the first entry retained from before the compaction entry. When rebuilding context, KnightCode replaces older summarized entries with the compaction summary and keeps the range beginning at this entry. A retain-none compaction stores its own ID in this field, so no preceding entries are retained.
138
+
139
+ Optional fields:
140
+ - `systemMessage`: The replayed prompt sections and tool declarations at the compaction boundary; it becomes the leading system message of the compacted context, and system messages among the kept entries are dropped in its favor. It is absent on older session entries.
141
+ - `usage`: LLM usage from generating the summary; included in session token and cost totals
142
+ - `details`: Implementation-specific data (e.g., `{ readFiles: string[], modifiedFiles: string[] }` for default, or custom data for extensions)
143
+ - `fromHook`: `true` if generated by an extension, `false`/`undefined` if knightcode-generated (legacy field name)
144
+
145
+ ### ContextEditEntry
146
+
147
+ Append-only edit of one earlier context-producing entry. It changes only future model context; the target entry and its metadata remain unchanged in raw history, UI, exports, and session accounting.
148
+
149
+ ```json
150
+ {"type":"context_edit","id":"g6h7i8j9","parentId":"f6g7h8i9","timestamp":"2024-12-03T14:11:00.000Z","targetId":"c3d4e5f6","replacement":null}
151
+ ```
152
+
153
+ Targets may be user, assistant, tool-result, or custom-message entries. `replacement: null` omits the target from model context. A non-null `replacement` replaces only the target message content. String replacements for assistant and tool-result entries are normalized to one text block because those roles require content arrays. If several edits target the same entry, the latest edit on the active branch wins. Edits are branch-relative: navigating to a point before the edit reveals the target's original contribution again.
154
+
155
+ ### BranchSummaryEntry
156
+
157
+ Created when switching branches via `/tree` with an LLM generated summary of the left branch up to the common ancestor. Captures context from the abandoned path.
158
+
159
+ ```json
160
+ {"type":"branch_summary","id":"g7h8i9j0","parentId":"a1b2c3d4","timestamp":"2024-12-03T14:15:00.000Z","fromId":"f6g7h8i9","summary":"Branch explored approach A..."}
161
+ ```
162
+
163
+ `parentId` is the entry from which the new branch continues. `fromId` is the previous leaf whose abandoned path was summarized.
164
+
165
+ Optional fields:
166
+ - `usage`: LLM usage from generating the summary; included in session token and cost totals
167
+ - `details`: File tracking data (`{ readFiles: string[], modifiedFiles: string[] }`) for default, or custom data for extensions
168
+ - `fromHook`: `true` if generated by an extension, `false`/`undefined` if knightcode-generated (legacy field name)
169
+
170
+ ### CustomEntry
171
+
172
+ Extension state persistence. Does NOT participate in LLM context.
173
+
174
+ ```json
175
+ {"type":"custom","id":"h8i9j0k1","parentId":"g7h8i9j0","timestamp":"2024-12-03T14:20:00.000Z","customType":"my-extension","data":{"count":42}}
176
+ ```
177
+
178
+ Use `customType` to identify your extension's entries on reload. Interactive mode can render custom entries via `knightcode.registerEntryRenderer(customType, renderer)`, but they still do not participate in LLM context.
179
+
180
+ KnightCode stores [virtual model](virtual-models.md) router state as custom entries with `customType` `knightcode.virtual-model-state` and `data` `{ provider, modelId, state }`.
181
+
182
+ #### Turn boundaries
183
+
184
+ The built-in turn-marker extension writes `knightcode.turn` at the first
185
+ `agent_start` of a run and `knightcode.turnEnd` at `agent_settled`:
186
+
187
+ ```json
188
+ {"type":"custom","id":"turn1234","parentId":"prev1234","timestamp":"2026-10-11T14:00:00.000Z","customType":"knightcode.turn"}
189
+ {"type":"custom","id":"end12345","parentId":"reply123","timestamp":"2026-10-11T14:00:05.000Z","customType":"knightcode.turnEnd","data":{"status":"completed"}}
190
+ ```
191
+
192
+ End status is `completed`, `interrupted`, or `failed`, with optional
193
+ `error: {message, kind}`. Kinds are `auth`, `rateLimit`, `contextOverflow`,
194
+ `network`, `provider`, and `other`, classified from the error text. For example:
195
+
196
+ ```json
197
+ {"type":"custom","id":"end54321","parentId":"reply123","timestamp":"2026-10-11T14:00:05.000Z","customType":"knightcode.turnEnd","data":{"status":"failed","error":{"message":"Too many requests","kind":"rateLimit"}}}
198
+ ```
199
+
200
+ An end entry whose `error` is a plain string reads as
201
+ `{message: <string>, kind: "other"}`. The marker/end-entry timestamps define the app server's final turn
202
+ `startedAt`/`completedAt` in Unix milliseconds.
203
+
204
+ The marker's entry ID is the [app-server](app-server.md) turn ID. Retries,
205
+ automatic recovery, and steering before settlement share one boundary. A later independent prompt starts another turn. A marker without a
206
+ valid end entry reads as `interrupted`, including after a crash.
207
+
208
+ Item IDs are deterministic ordinals within the turn, such as
209
+ `turn1234:user:0`, except tool calls, which retain their original call IDs.
210
+ Assistant text/thinking ordinals follow finalized content order; nested calls
211
+ are live-only. Unmarked legacy history is grouped by user-message boundaries
212
+ and uses those entry IDs as turn IDs. Turn markers are custom entries, not a new
213
+ session-file version, and never enter model context.
214
+
215
+ App-server approval modes use `customType: "knightcode.approvalMode"` with `data`
216
+ of `ask`, `autoEdit`, or `fullAccess`. The latest value on the branch wins;
217
+ malformed stored data restores as `ask` rather than widening access.
218
+
219
+ #### Plan mode snapshots
220
+
221
+ The built-in [plan mode](plan-mode.md) writes full snapshots with
222
+ `customType: "plan-mode"`:
223
+
224
+ ```json
225
+ {"type":"custom","id":"plan1234","parentId":"prev1234","timestamp":"2024-12-03T14:20:00.000Z","customType":"plan-mode","data":{"mode":"off","draft":{"revision":2,"markdown":"# Changes\n..."},"approved":2}}
226
+ ```
227
+
228
+ `mode` is `off` or `planning`; `draft` and `approved` are optional. An approved
229
+ revision must equal the draft revision and exist only while off. The latest
230
+ snapshot on the selected branch wins, including entries omitted from model
231
+ context by compaction. Exit and approval retain the draft; entry and submission
232
+ clear approval. Malformed state refuses restoration rather than dropping the
233
+ restrictions. No session version change is needed.
234
+
235
+ ### CustomMessageEntry
236
+
237
+ Extension-injected messages that DO participate in LLM context.
238
+
239
+ ```json
240
+ {"type":"custom_message","id":"i9j0k1l2","parentId":"h8i9j0k1","timestamp":"2024-12-03T14:25:00.000Z","customType":"my-extension","content":"Injected context...","display":true}
241
+ ```
242
+
243
+ Fields:
244
+ - `content`: String or `(TextContent | ImageContent)[]` (same as UserMessage)
245
+ - `display`: `true` = show in TUI with distinct styling, `false` = hidden
246
+ - `details`: Optional extension-specific metadata (not sent to LLM)
247
+
248
+ Plan-mode messages use `customType: "plan-mode"`, `display: false`, and
249
+ `details.kind` of `instructions`, `reminder`, `exit`, or `recovery`. Recovery
250
+ also stores `id` (the compaction entry ID), `revision` when present, and `status`
251
+ (`planning` or `approved`). Its content is frozen when appended, so later
252
+ revisions cannot change earlier request content.
253
+
254
+ ### LabelEntry
255
+
256
+ User-defined bookmark/marker on an entry.
257
+
258
+ ```json
259
+ {"type":"label","id":"j0k1l2m3","parentId":"i9j0k1l2","timestamp":"2024-12-03T14:30:00.000Z","targetId":"a1b2c3d4","label":"checkpoint-1"}
260
+ ```
261
+
262
+ Set `label` to `undefined` to clear a label.
263
+
264
+ ### SessionInfoEntry
265
+
266
+ Session metadata (e.g., user-defined display name). Set via `/name`, `--name` / `-n`, or `knightcode.setSessionName()` in extensions.
267
+
268
+ ```json
269
+ {"type":"session_info","id":"k1l2m3n4","parentId":"j0k1l2m3","timestamp":"2024-12-03T14:35:00.000Z","name":"Refactor auth module"}
270
+ ```
271
+
272
+ The session name is displayed in the session selector (`/resume`) instead of the first message when set.
273
+
274
+ ## Tree Structure
275
+
276
+ Entries normally form one tree, but navigation APIs can create multiple roots:
277
+ - A root entry has `parentId: null`; the first entry is initially the root
278
+ - Each non-root entry points to its parent via `parentId`
279
+ - Branching creates new children from an earlier entry
280
+ - The "leaf" is the current position in the tree
281
+ - Calling `resetLeaf()` or `branchWithSummary(null, ...)` allows a later entry to become another root
282
+
283
+ ```
284
+ [user msg] ─── [assistant] ─── [user msg] ─── [assistant] ─┬─ [user msg] ← current leaf
285
+ │
286
+ └─ [branch_summary] ─── [user msg] ← alternate branch
287
+ ```
288
+
289
+ ## Context Building
290
+
291
+ `buildContextEntries()` walks from the current leaf to the root, producing the active entry list while honoring compaction:
292
+
293
+ 1. Collects all entries on the path
294
+ 2. If one or more `CompactionEntry` values are on the path, uses the latest one:
295
+ - Includes the compaction entry first
296
+ - Includes non-system entries from `firstKeptEntryId` up to, but not including, the compaction entry
297
+ - Includes entries after the compaction entry
298
+ 3. Preserves non-message entries in the selected range so interactive mode can render them
299
+
300
+ `buildSessionProjection()` then applies the latest `context_edit` for each selected target. It returns the model-visible messages together with their source entries. Omitted targets produce no message; replacements retain the source entry's role and metadata while changing only content. The raw selected entries are not modified.
301
+
302
+ `buildSessionContext()` builds on that projection to produce the message list for the LLM:
303
+
304
+ 1. Extracts current model and thinking level settings from the full path
305
+ 2. Converts selected entries to messages:
306
+ - `message` -> stored `AgentMessage`
307
+ - `compaction` -> complete system checkpoint followed by `compactionSummary`
308
+ - `branch_summary` -> `branchSummary`
309
+ - `custom_message` -> `CustomMessage`
310
+ - `context_edit` -> no context message of its own
311
+ - `usage` and `custom` -> no context message
312
+
313
+ The compaction summary replaces entries before `firstKeptEntryId`. Pre-compaction system messages are folded into the complete checkpoint rather than replayed from the retained range. Retained non-system entries and all entries after the compaction remain available to the LLM.
314
+
315
+ ## Parsing Example
316
+
317
+ ```typescript
318
+ import { readFileSync } from "fs";
319
+
320
+ const lines = readFileSync("session.jsonl", "utf8").trim().split("\n");
321
+
322
+ for (const line of lines) {
323
+ const entry = JSON.parse(line);
324
+
325
+ switch (entry.type) {
326
+ case "session":
327
+ console.log(`Session v${entry.version ?? 1}: ${entry.id}`);
328
+ break;
329
+ case "message":
330
+ console.log(`[${entry.id}] ${entry.message.role}: ${JSON.stringify(entry.message.content)}`);
331
+ break;
332
+ case "compaction":
333
+ console.log(`[${entry.id}] Compaction: ${entry.tokensBefore} tokens summarized`);
334
+ break;
335
+ case "branch_summary":
336
+ console.log(`[${entry.id}] Branch from ${entry.fromId}`);
337
+ break;
338
+ case "usage":
339
+ console.log(`[${entry.id}] Usage (${entry.kind}): ${entry.usage.totalTokens} tokens`);
340
+ break;
341
+ case "custom":
342
+ console.log(`[${entry.id}] Custom (${entry.customType}): ${JSON.stringify(entry.data)}`);
343
+ break;
344
+ case "custom_message":
345
+ console.log(`[${entry.id}] Extension message (${entry.customType}): ${entry.content}`);
346
+ break;
347
+ case "label":
348
+ console.log(`[${entry.id}] Label "${entry.label}" on ${entry.targetId}`);
349
+ break;
350
+ case "model_change":
351
+ console.log(`[${entry.id}] Model: ${entry.provider}/${entry.modelId}`);
352
+ break;
353
+ case "thinking_level_change":
354
+ console.log(`[${entry.id}] Thinking: ${entry.thinkingLevel}`);
355
+ break;
356
+ }
357
+ }
358
+ ```
@@ -0,0 +1,135 @@
1
+ # Sessions and Context
2
+
3
+ KnightCode saves a conversation as a session. The active branch of that session supplies conversation history for the next model request. Use session commands to continue work, explore another branch, or reduce the amount of history sent to the model.
4
+
5
+ ## Continue or switch sessions
6
+
7
+ KnightCode saves sessions automatically unless you start it with `--no-session`.
8
+
9
+ ```bash
10
+ knightcode --continue
11
+ knightcode --resume
12
+ ```
13
+
14
+ `--continue` opens the most recent session for the current working directory. `--resume` opens the session picker. In interactive mode, `/resume` opens the same picker and `/new` starts a new session.
15
+
16
+ Use `/name` or `--name` to assign a recognizable session name. Run `/session` to verify the current session file, ID, message count, token usage, and cost.
17
+
18
+ The session picker lets you search, rename, and delete sessions. It can also show paths, change sorting, and limit results to named sessions. See [Keybindings](keybindings.md#sessions) for its shortcuts.
19
+
20
+ ## Choose how to branch
21
+
22
+ KnightCode stores entries as a tree, so returning to an earlier point does not erase the branch you leave.
23
+
24
+ | Action | Result | Use it when |
25
+ |---|---|---|
26
+ | `/tree` | Moves within the current session file | Related alternatives should stay together |
27
+ | `/fork` | Creates a new session from an earlier user message | The alternative should become separate work |
28
+ | `/clone` | Copies the active branch into a new session | You want a separate copy of the current state |
29
+ | `/undo` | Returns to an earlier user message on the current branch, optionally restoring files | You want to take back the last turns |
30
+
31
+ In `/tree`, select a user message to put its text back in the editor. Edit and submit it to create another branch. Selecting an assistant response or another entry continues after that entry with an empty editor.
32
+
33
+ <p align="center"><img src="images/tree-view.png" alt="The /tree view showing a session with two branches, user messages, assistant replies, and tool calls" width="750"></p>
34
+
35
+ Selecting a point while the model is responding cancels that response. Navigation cannot proceed while compaction or another tree navigation is still running; wait for it to finish and retry.
36
+
37
+ When you leave a branch, KnightCode can summarize it and attach that summary to the branch you enter. This preserves relevant work from the abandoned path without including every message from it.
38
+
39
+ For the persisted tree and entry types, see [Session Format](session-format.md).
40
+
41
+ ## Undoing with `/undo`
42
+
43
+ `/undo` is the quick form of `/tree` for the common case: pick a user message on the current
44
+ branch and go back to it. It lists only user messages, newest at the bottom, with the time
45
+ and how many files an undo to that point would restore. Enter goes back; the turns after the
46
+ chosen message are left as an abandoned branch (still reachable through `/tree`) and the
47
+ message text returns to the editor for editing and resubmitting. `/undo` never summarizes the
48
+ branch it leaves.
49
+
50
+ ### File Restore
51
+
52
+ Before `edit` or `write` changes a file, KnightCode copies the original into
53
+ `~/.knightcode/agent/file-history/<session id>/`, once per file per user turn. When you go
54
+ back past a turn that changed files, through `/undo`, `/tree`, or double-Escape, you are asked:
55
+
56
+ - **Conversation only**: files stay as they are.
57
+ - **Conversation and N files**: every file the abandoned turns touched is put back to its
58
+ content from before those turns; files they created are deleted.
59
+
60
+ Escape at that prompt cancels the navigation entirely.
61
+
62
+ Limits:
63
+
64
+ - Changes made by shell commands (`bash`, `powershell`) are not tracked. The prompt says so
65
+ when a shell command ran in the abandoned turns.
66
+ - Edits made by subagents or outside KnightCode are not tracked either; a tracked file is
67
+ restored to its backup regardless of who changed it afterwards.
68
+ - If you go back without restoring files and later go back further, only the edits on the
69
+ branch you are on are restored.
70
+ - Jumping sideways to another branch with `/tree` restores to the fork point; edits on the
71
+ target branch are not re-applied.
72
+
73
+ Backups older than 30 days are removed at startup. Set `KNIGHTCODE_DISABLE_FILE_CHECKPOINTS=1`
74
+ to turn file tracking off; `/undo` then rewinds the conversation only.
75
+
76
+ ## Manage conversation context
77
+
78
+ The model receives the active branch, not every branch in the session file. KnightCode combines that history with the system prompt, discovered context files, available tools, and loaded skill descriptions. [How KnightCode Works](how-knightcode-works.md#context) describes how those inputs are assembled.
79
+
80
+ The footer shows current context usage. When the active context approaches the model's limit, KnightCode normally compacts older history automatically. Compaction adds a summary and keeps recent messages. It does not delete the original session entries.
81
+
82
+ Run `/compact` to compact manually. You can add instructions when the summary should preserve a particular topic or decision. Configure automatic compaction and retained history through [Settings](settings.md#compaction).
83
+
84
+ Compaction can fail if the provider is unavailable or cannot accept the summarization request. Correct the provider problem and run `/compact` again. Disabling automatic compaction does not disable the manual command.
85
+
86
+ See [Compaction Reference](compaction.md) for thresholds, retained boundaries, branch-summary behavior, and extension hooks.
87
+
88
+ ## Control session storage
89
+
90
+ By default, KnightCode stores sessions under `~/.knightcode/agent/sessions/`, grouped by working directory. Use `--session-dir`, `KNIGHTCODE_CODING_AGENT_SESSION_DIR`, or the `sessionDir` setting to choose another location. The CLI option has highest precedence.
91
+
92
+ Use `--no-session` for an ephemeral run. An ephemeral session cannot be resumed after KnightCode exits.
93
+
94
+ Use `--session` when you already know the session path or ID. Use `--fork` to create a new session from an existing session before interactive mode starts.
95
+
96
+ ## Session ownership
97
+
98
+ Only one KnightCode process may write a persisted session at a time. Opening a
99
+ session locks its canonical file path and canonical parent directory binding.
100
+ Symlink and Windows junction aliases identify the same file; hard-linked
101
+ transcripts are refused because distinct names could bypass ownership. Managers
102
+ inside one process share counted ownership; the final `close()` releases it.
103
+
104
+ If another terminal or the [app server](app-server.md) owns the session, terminal
105
+ startup and `/resume` offer to continue in a fork. Accepting reads the source
106
+ without changing it and creates an independently owned transcript. Declining
107
+ keeps the current interactive session. Non-interactive invocations fail rather
108
+ than waiting for input.
109
+
110
+ Locks are refreshed while live. After a crashed or stalled owner's lock expires,
111
+ another process can take it. The old owner detects this before writes, refuses
112
+ mutations, and never removes the new owner's lock. Read-only listings, exports,
113
+ history reads, and fork-source reads need no ownership and never repair or migrate
114
+ the source. Repairs and migrations happen only when an owner opens it.
115
+
116
+ Closing a persisted manager is final: it remains readable but cannot write again.
117
+ Reopen through a new `SessionManager.open()` after closing or disposing its
118
+ session. See the [SDK ownership example](sdk.md#session-ownership).
119
+
120
+ App-server archive/unarchive operations own both source and destination until
121
+ publication and lookup updates finish. They refuse collisions, publish without
122
+ replacement, and report recovery paths if a move cannot finish; they do not
123
+ silently overwrite another transcript.
124
+
125
+ ## Export or share a session
126
+
127
+ Use `/export` to write the current session as HTML or JSONL. Use `/share` to upload it and get a viewer link. By default, KnightCode uses a Radius artifact when Radius authentication is configured; otherwise, it uses a private GitHub gist. Set [`sessionShareDestination`](settings.md#sessions-and-context) to `gist` or `radius` to force one destination.
128
+
129
+ Review exported or shared sessions first. They can contain prompts, model responses, tool arguments, command output, file contents, and extension messages.
130
+
131
+ ## Report a bug
132
+
133
+ Run `/bug [description]` to prepare a private report for the KnightCode maintainers. You can include the session transcript, omit it, or ask the current model to summarize the problem. Review any transcript or generated summary because it can contain sensitive conversation data.
134
+
135
+ The report includes environment and provider configuration without credential values, plus recorded error diagnostics. Upload it to the maintainers through `remote.knightcode.dev` or export the same report as a zip to inspect and share yourself. Uploads do not require a login and are always anonymous. If an upload fails, KnightCode offers to export the zip.