kward 0.78.0 → 0.80.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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +13 -2
  3. data/.github/workflows/pages.yml +1 -1
  4. data/CHANGELOG.md +82 -1
  5. data/Gemfile.lock +2 -2
  6. data/README.md +33 -38
  7. data/doc/agent-tools.md +10 -11
  8. data/doc/api.md +3 -3
  9. data/doc/authentication.md +79 -110
  10. data/doc/code-search.md +1 -1
  11. data/doc/composer.md +1 -1
  12. data/doc/configuration.md +136 -27
  13. data/doc/context-budgeting.md +6 -6
  14. data/doc/context-tools.md +2 -2
  15. data/doc/editor.md +7 -7
  16. data/doc/extensibility.md +9 -29
  17. data/doc/files.md +6 -6
  18. data/doc/getting-started.md +3 -3
  19. data/doc/git.md +8 -2
  20. data/doc/lifecycle-hooks.md +5 -4
  21. data/doc/local-models.md +130 -0
  22. data/doc/mcp.md +5 -5
  23. data/doc/permissions.md +15 -5
  24. data/doc/plugins.md +39 -4
  25. data/doc/prompt-templates.md +105 -0
  26. data/doc/providers.md +140 -0
  27. data/doc/releasing.md +11 -3
  28. data/doc/rpc.md +65 -31
  29. data/doc/sandboxing.md +142 -0
  30. data/doc/security.md +31 -10
  31. data/doc/session-management.md +2 -4
  32. data/doc/skills.md +10 -0
  33. data/doc/tabs.md +37 -0
  34. data/doc/telegram.md +138 -0
  35. data/doc/transports.md +209 -0
  36. data/doc/usage.md +11 -3
  37. data/doc/web-search.md +3 -3
  38. data/doc/workspace-tools.md +4 -4
  39. data/examples/plugins/stardate_footer.rb +10 -0
  40. data/examples/plugins/telegram/plugin.rb +39 -0
  41. data/examples/plugins/telegram/telegram_api.rb +136 -0
  42. data/examples/plugins/telegram/telegram_transport.rb +304 -0
  43. data/kward.gemspec +1 -1
  44. data/lib/kward/ansi.rb +1 -0
  45. data/lib/kward/auth/api_key_store.rb +99 -0
  46. data/lib/kward/cli/auth_commands.rb +72 -13
  47. data/lib/kward/cli/commands.rb +7 -0
  48. data/lib/kward/cli/doctor.rb +21 -0
  49. data/lib/kward/cli/git.rb +31 -8
  50. data/lib/kward/cli/plugins.rb +1 -0
  51. data/lib/kward/cli/prompt_interface.rb +7 -0
  52. data/lib/kward/cli/rendering.rb +6 -2
  53. data/lib/kward/cli/runtime_helpers.rb +4 -2
  54. data/lib/kward/cli/sessions.rb +1 -1
  55. data/lib/kward/cli/settings.rb +162 -36
  56. data/lib/kward/cli/slash_commands.rb +109 -1
  57. data/lib/kward/cli/tabs.rb +102 -37
  58. data/lib/kward/cli/transports.rb +67 -0
  59. data/lib/kward/cli/worktrees.rb +360 -0
  60. data/lib/kward/cli.rb +22 -1
  61. data/lib/kward/config_files.rb +106 -4
  62. data/lib/kward/conversation.rb +27 -8
  63. data/lib/kward/git_worktree_manager.rb +291 -0
  64. data/lib/kward/local_command_runner.rb +2 -2
  65. data/lib/kward/model/azure_openai_config.rb +54 -0
  66. data/lib/kward/model/catalog.rb +113 -0
  67. data/lib/kward/model/client.rb +364 -23
  68. data/lib/kward/model/model_info.rb +60 -1
  69. data/lib/kward/model/payloads.rb +64 -4
  70. data/lib/kward/model/provider_catalog.rb +114 -0
  71. data/lib/kward/model/sources.rb +70 -0
  72. data/lib/kward/model/stream_parser.rb +141 -39
  73. data/lib/kward/pan/index.html.erb +50 -0
  74. data/lib/kward/pan/server.rb +49 -2
  75. data/lib/kward/permissions/policy.rb +18 -4
  76. data/lib/kward/plugin_chat_runtime.rb +374 -0
  77. data/lib/kward/plugin_registry.rb +81 -8
  78. data/lib/kward/private_file.rb +9 -3
  79. data/lib/kward/prompt_interface/approval_prompt.rb +2 -0
  80. data/lib/kward/prompt_interface/composer_renderer.rb +1 -5
  81. data/lib/kward/prompt_interface/editor/auto_indent.rb +46 -0
  82. data/lib/kward/prompt_interface/editor/buffer.rb +18 -4
  83. data/lib/kward/prompt_interface/editor/controller.rb +43 -10
  84. data/lib/kward/prompt_interface/editor/modes/vibe.rb +2 -2
  85. data/lib/kward/prompt_interface/editor/renderer.rb +8 -8
  86. data/lib/kward/prompt_interface/editor/state.rb +3 -9
  87. data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +184 -9
  88. data/lib/kward/prompt_interface/file_overlay.rb +2 -2
  89. data/lib/kward/prompt_interface/git_prompt.rb +7 -3
  90. data/lib/kward/prompt_interface/interactive/controller.rb +4 -4
  91. data/lib/kward/prompt_interface/interactive/renderer.rb +4 -1
  92. data/lib/kward/prompt_interface/interactive/state.rb +2 -2
  93. data/lib/kward/prompt_interface/project_browser.rb +25 -6
  94. data/lib/kward/prompt_interface/runtime_state.rb +22 -6
  95. data/lib/kward/prompt_interface/screen.rb +3 -0
  96. data/lib/kward/prompt_interface/selection_prompt.rb +7 -1
  97. data/lib/kward/prompt_interface/transcript_buffer.rb +24 -2
  98. data/lib/kward/prompt_interface.rb +71 -12
  99. data/lib/kward/prompts/commands.rb +3 -1
  100. data/lib/kward/prompts.rb +22 -10
  101. data/lib/kward/rpc/auth_manager.rb +112 -152
  102. data/lib/kward/rpc/config_manager.rb +46 -6
  103. data/lib/kward/rpc/plugin_chat_manager.rb +56 -194
  104. data/lib/kward/rpc/prompt_bridge.rb +8 -4
  105. data/lib/kward/rpc/redactor.rb +1 -1
  106. data/lib/kward/rpc/server.rb +102 -14
  107. data/lib/kward/rpc/session_manager.rb +151 -38
  108. data/lib/kward/sandbox/capabilities.rb +39 -0
  109. data/lib/kward/sandbox/command_runner.rb +28 -0
  110. data/lib/kward/sandbox/environment.rb +24 -0
  111. data/lib/kward/sandbox/linux_bubblewrap_runner.rb +71 -0
  112. data/lib/kward/sandbox/macos_seatbelt_runner.rb +96 -0
  113. data/lib/kward/sandbox/passthrough_runner.rb +13 -0
  114. data/lib/kward/sandbox/policy.rb +74 -0
  115. data/lib/kward/sandbox/runner_factory.rb +55 -0
  116. data/lib/kward/sandbox/unavailable_runner.rb +21 -0
  117. data/lib/kward/sandbox.rb +9 -0
  118. data/lib/kward/session_store.rb +110 -24
  119. data/lib/kward/skills/capture.rb +144 -0
  120. data/lib/kward/tab_driver.rb +6 -3
  121. data/lib/kward/tools/git_commit.rb +39 -0
  122. data/lib/kward/tools/registry.rb +26 -6
  123. data/lib/kward/tools/tool_call.rb +1 -0
  124. data/lib/kward/transport/gateway.rb +253 -0
  125. data/lib/kward/transport/host.rb +343 -0
  126. data/lib/kward/transport/manager.rb +179 -0
  127. data/lib/kward/transport/plugin_chat_gateway.rb +186 -0
  128. data/lib/kward/transport/runtime.rb +41 -0
  129. data/lib/kward/transport/store.rb +101 -0
  130. data/lib/kward/transport.rb +204 -0
  131. data/lib/kward/version.rb +1 -1
  132. data/lib/kward/workspace.rb +18 -3
  133. data/lib/kward/workspace_factory.rb +34 -0
  134. data/templates/default/fulldoc/html/js/kward.js +3 -0
  135. data/templates/default/kward_navigation.rb +8 -1
  136. data/templates/default/layout/html/setup.rb +5 -0
  137. metadata +41 -2
data/doc/editor.md CHANGED
@@ -1,4 +1,8 @@
1
- # Integrated Editor
1
+ # Integrated editor
2
+
3
+ Kward includes a terminal editor with three modes: Modern, Emacs, and Vibe. It opens inside the chat composer, so you can jump into a file, make a change, save it, and return to the conversation without switching tools.
4
+
5
+ The editor opens only files inside the current workspace, which keeps edits tied to the project where you started Kward.
2
6
 
3
7
  <quote>
4
8
  Three Modes for the Elven-kings under the sky,<br>
@@ -10,10 +14,6 @@ One Kward to bring them all and in the transcript bind them<br>
10
14
  In the Land of Ruby where the agents lie.<br>
11
15
  </quote>
12
16
 
13
- Kward includes a terminal editor with 3 editing modes to choose from: Modern, Emacs and Vibe. It opens inside the chat composer, so you can jump into a file, make a change, save it, and return to the conversation without switching tools.
14
-
15
- The editor is scoped to the current workspace. It only opens files inside that directory, which helps keep edits tied to the project you started Kward in.
16
-
17
17
  ## Quick start
18
18
 
19
19
  Open a file directly from your shell:
@@ -93,8 +93,8 @@ $doc/editor.md
93
93
 
94
94
  The editor is intentionally compact, but it covers the basics you need for quick changes:
95
95
 
96
- - Syntax highlighting for common languages, including Ruby, Crystal, Elixir, Julia, JavaScript, TypeScript, JSON, Markdown, YAML, Shell, Makefile, HTML, CSS, SCSS, Python, Go, Rust, Java, C#, C, C++, Swift, Kotlin, Lua, and SQL. Unknown file types render as plain text.
97
- - Auto-indent, enabled by default. New lines inherit indentation, Tab jumps to the expected indentation or the next indentation stop, Shift+Tab moves indentation back, obvious closing tokens are re-indented, and Backspace in leading whitespace removes one indentation unit when possible. For Ruby, Crystal, Elixir, Julia, Lua, Makefiles, and shell scripts, Enter after a block opener inserts the matching closing keyword; Ctrl+Enter also works from the middle of the line in terminals that report modified Enter keys.
96
+ - Syntax highlighting for common languages, including Ruby, ERB templates, Crystal, Elixir, Julia, JavaScript, TypeScript, JSON, Markdown, YAML, Shell, Makefile, HTML, CSS, SCSS, Python, Go, Rust, Java, C#, C, C++, Swift, Kotlin, Lua, and SQL. ERB highlights template HTML outside ERB tags and Ruby inside `<% ... %>` tags. Unknown file types render as plain text.
97
+ - Auto-indent, enabled by default. New lines inherit indentation, Tab jumps to the expected indentation or the next indentation stop, Shift+Tab moves indentation back, obvious closing tokens are re-indented, and Backspace in leading whitespace removes one indentation unit when possible. ERB recognizes common inline Ruby control tags and HTML opening tags when calculating the next indentation. For Ruby, Crystal, Elixir, Julia, Lua, Makefiles, and shell scripts, Enter after a block opener inserts the matching closing keyword; Ctrl+Enter also works from the middle of the line in terminals that report modified Enter keys.
98
98
  - Undo and redo, with up to 100 history entries per buffer.
99
99
  - Incremental search forward and backward.
100
100
  - Selection, copy, cut, and paste. Copy and cut also write to the terminal clipboard through OSC 52 when the terminal supports it.
data/doc/extensibility.md CHANGED
@@ -14,6 +14,7 @@ Start simple. Most users only need `PRINCIPLES.md`, workspace `AGENTS.md`, and m
14
14
  | Task-specific reusable instructions | skills |
15
15
  | Different tone or role | [personas](personas.md) |
16
16
  | Local Ruby behavior or integrations | plugins |
17
+ | External messaging or event integration | transport plugins |
17
18
  | Deterministic runtime policy or automation | lifecycle hooks |
18
19
 
19
20
  Install the starter pack for a useful starting point:
@@ -43,6 +44,8 @@ If `KWARD_CONFIG_PATH` is set, `PRINCIPLES.md` lives beside that config file.
43
44
 
44
45
  If `PRINCIPLES.md` is absent, Kward also reads `~/.kward/AGENTS.md` (or the equivalent beside a custom config path) as a legacy alias. New setups should use `PRINCIPLES.md`. See [Configuration](configuration.md) for details.
45
46
 
47
+ For a small local model, set `system_prompt.include_principles` to `false` to keep Kward's normal prompt without global principles. Set `system_prompt.file` only when you want the file to replace the entire assembled system prompt; replacement mode also omits personas, skills, memory, plugins, and workspace guidance. See [Local models](local-models.md) for a complete setup.
48
+
46
49
  ## Project instructions: `AGENTS.md`
47
50
 
48
51
  Put repository-specific rules in the workspace root:
@@ -66,35 +69,9 @@ By default, Kward adds a compact instruction telling the model that `AGENTS.md`
66
69
 
67
70
  ## Prompt templates
68
71
 
69
- Use prompt templates when you repeatedly type the same kind of request.
70
-
71
- Create:
72
-
73
- ```text
74
- ~/.kward/prompts/review.md
75
- ```
76
-
77
- Example:
78
-
79
- ```markdown
80
- ---
81
- description: Review a change for correctness.
82
- argument-hint: <focus>
83
- ---
84
-
85
- Review the current diff for correctness, tests, and maintainability.
86
- Focus on: $ARGUMENTS
87
- ```
88
-
89
- Then run inside Kward:
90
-
91
- ```text
92
- /review auth edge cases
93
- ```
72
+ Use prompt templates when you repeatedly type the same kind of request. Each Markdown file in `~/.kward/prompts/` becomes a slash command; its filename is the command name and `$ARGUMENTS` expands the text after the command.
94
73
 
95
- The `description` frontmatter field appears in the slash command list and completion overlay so you can find the template by purpose. `argument-hint` is shown as a usage hint. The `$ARGUMENTS` placeholder in the body is replaced with whatever you type after the command.
96
-
97
- Prompt templates are best for reusable text. They do not run local code.
74
+ See [Prompt templates](prompt-templates.md) to create one, understand naming and reload behavior, and learn about the `/plan`, `/investigate`, `/research`, and `/codebase-review` templates installed by `kward init`.
98
75
 
99
76
  ## Skills
100
77
 
@@ -112,12 +89,15 @@ Hooks are deterministic automation and policy. They are not model instructions.
112
89
 
113
90
  Use plugins when text instructions are not enough and you need Ruby code to run locally.
114
91
 
115
- Plugins can add slash commands, prompt context, footer UI, transcript observers, and RPC-visible commands.
92
+ Plugins can add slash commands, prompt context, footer UI, transcript observers, RPC-visible commands, and external transports. Transport plugins can connect external conversations to normal Kward sessions or explicitly transport-capable plugin chats; they remain distinct from plugin-owned tabs.
93
+
94
+ Use `kward transport list` and `kward transport status` to inspect registered transports. Run a foreground transport with `kward transport run NAME`.
116
95
 
117
96
  Plugin files live in:
118
97
 
119
98
  ```text
120
99
  ~/.kward/plugins/*.rb
100
+ ~/.kward/plugins/*/plugin.rb
121
101
  ```
122
102
 
123
103
  Plugins are trusted local Ruby code. Install only plugins you trust. See [Plugins](plugins.md).
data/doc/files.md CHANGED
@@ -12,7 +12,7 @@ From an interactive Kward session, run:
12
12
  /files
13
13
  ```
14
14
 
15
- Kward opens the project file browser. Use the arrow keys to move through the tree, then press `Enter` on a file to open it in the integrated editor.
15
+ Kward opens the project file browser. Use the arrow keys or `j`/`k` to move through the tree, then press `Enter` on a file to open it in the integrated editor.
16
16
 
17
17
  When you quit the editor, Kward returns to the file browser at the same position so you can keep browsing nearby files.
18
18
 
@@ -32,10 +32,10 @@ Outside Git, Kward scans the workspace directory and skips common noisy director
32
32
 
33
33
  | Key | Action |
34
34
  | --- | ------ |
35
- | `↑` / `↓` | Move the selection |
35
+ | `↑` / `↓` or `j` / `k` | Move the selection down / up |
36
36
  | `Enter` | Open a file, or toggle a directory |
37
- | `←` | Collapse the selected directory, or jump to its parent |
38
- | `→` | Expand the selected directory |
37
+ | `←` or `h` | Collapse the selected directory, or jump to its parent |
38
+ | `→` or `l` | Expand the selected directory |
39
39
  | `Tab` | Start or stop search |
40
40
  | `/` | Start search |
41
41
  | `Backspace` | Delete the last search character |
@@ -55,7 +55,7 @@ For example:
55
55
  /agent
56
56
  ```
57
57
 
58
- Use `↑` and `↓` to choose a result, then press `Enter` to open it. Press `Esc` to return to the tree view.
58
+ Use `↑` / `↓` or `j` / `k` to choose a result, then press `Enter` to open it. Press `Esc` to return to the tree view.
59
59
 
60
60
  ## Mention a file in chat
61
61
 
@@ -84,7 +84,7 @@ A typical workflow:
84
84
  5. Save and quit.
85
85
  6. Continue browsing files, or press `Esc` to return to chat.
86
86
 
87
- See [Integrated Editor](editor.md) for editor modes, save/quit keys, search, selection, and configuration.
87
+ See [Integrated editor](editor.md) for editor modes, save/quit keys, search, selection, and configuration.
88
88
 
89
89
  ## Remembered state
90
90
 
@@ -6,7 +6,7 @@ This page gets you from install to a first useful chat.
6
6
 
7
7
  ## Requirements
8
8
 
9
- - Ruby 3.2 or newer.
9
+ - Ruby 3.4 or newer.
10
10
  - Credentials for one model provider. The easiest setup is `kward login` or `/login` inside Kward.
11
11
  - Bundler only if you run Kward from a source checkout.
12
12
 
@@ -57,7 +57,7 @@ Or from inside an interactive session:
57
57
  /login
58
58
  ```
59
59
 
60
- Kward supports OpenAI/ChatGPT, Anthropic Claude Pro/Max, OpenRouter, and experimental Copilot credentials. See [Authentication](authentication.md) when you need a specific provider.
60
+ Kward supports subscription login, direct native APIs, OpenAI-compatible API-key providers, Copilot, OpenRouter, and local model servers. See [Model providers](providers.md) to choose one, then [Authentication](authentication.md) for its login flow.
61
61
 
62
62
  Confirm your credentials are saved:
63
63
 
@@ -65,7 +65,7 @@ Confirm your credentials are saved:
65
65
  kward auth status
66
66
  ```
67
67
 
68
- If your provider offers multiple models, choose one inside Kward with `/model`.
68
+ Choose a model inside Kward with `/model`. The picker can refresh provider catalogs, switch providers, show all returned entries, or accept a manual model/deployment ID.
69
69
 
70
70
  ## Start an interactive chat
71
71
 
data/doc/git.md CHANGED
@@ -30,7 +30,7 @@ Use the overlay to review and shape the commit:
30
30
 
31
31
  | Key | Action |
32
32
  | --- | --- |
33
- | `↑` / `↓` | Move between changed files. |
33
+ | `↑` / `↓` or `j` / `k` | Move between changed files. |
34
34
  | `Enter` | Open the selected file in the diff viewer. |
35
35
  | `s` | Stage or unstage the selected file. |
36
36
  | `Tab` | Switch to commit-message entry. |
@@ -61,7 +61,7 @@ Useful keys in the diff viewer:
61
61
 
62
62
  After you close the viewer, Kward returns to the Git overlay with the file list refreshed.
63
63
 
64
- The diff viewer is read-only. It is meant for checking what changed, not editing. If you spot something you want to fix, close the viewer, return to chat, and ask Kward to make the change or open the file with the built-in editor using `$path/to/file`. See [Integrated Editor](editor.md) for editor workflows and keybindings.
64
+ The diff viewer is read-only. It is meant for checking what changed, not editing. If you spot something you want to fix, close the viewer, return to chat, and ask Kward to make the change or open the file with the built-in editor using `$path/to/file`. See [Integrated editor](editor.md) for editor workflows and keybindings.
65
65
 
66
66
  ## Example workflow
67
67
 
@@ -107,6 +107,12 @@ This is just a lightweight status hint. Use `/git` when you want to review or co
107
107
 
108
108
  If the working tree is clean when you run `/git`, the overlay shows `No uncommitted changes.` and there is nothing to stage or commit.
109
109
 
110
+ ## Agent commits in worktree tabs
111
+
112
+ When an active worktree tab receives an explicit request to commit, the agent can use the model-facing `git_commit` tool. It runs Git in the trusted host process so linked-worktree metadata can be updated without granting arbitrary shell commands write access to shared `.git` metadata.
113
+
114
+ The tool requires a commit message and can receive an optional list of workspace-relative paths. If paths are omitted, all current changes in the active worktree are included. Generic `run_shell_command` Git commands remain sandboxed and cannot replace this operation. It is exposed only for active interactive worktree tabs; RPC sessions do not currently support worktree bindings.
115
+
110
116
  ## Notes and limitations
111
117
 
112
118
  - `/git` is available in the interactive terminal UI, not in one-shot prompts or the RPC backend.
@@ -1,8 +1,8 @@
1
1
  # Lifecycle hooks
2
2
 
3
- Lifecycle hooks are deterministic runtime callbacks around Kward's agent workflow. Use them when something must happen because of an event, not because the model remembered an instruction.
3
+ Lifecycle hooks let you run a rule or action whenever something happens in Kward—for example, before a command runs, after a turn finishes, or when a tool needs approval. Use a hook when the action must happen reliably rather than depending on the model to remember an instruction.
4
4
 
5
- Hooks can observe events and return structured decisions to allow, deny, ask for approval, modify supported payloads, warn, retry, or defer. They are currently exposed through trusted Ruby plugins and through command hooks configured in `config.json`.
5
+ A hook can observe an event, allow or deny an operation, ask for approval, adjust supported data, or trigger follow-up work. You can add hooks through trusted Ruby plugins or configure command hooks in `config.json`.
6
6
 
7
7
  Hooks run as local code with your user permissions. Do not install hooks you do not trust, and do not put secrets in hook output.
8
8
 
@@ -34,7 +34,8 @@ When multiple hooks match one event, they run by ascending `order`. A `deny` sto
34
34
 
35
35
  ## Ruby plugin hooks
36
36
 
37
- Register hooks from trusted plugin files in `~/.kward/plugins/*.rb`:
37
+ Register hooks from trusted plugin files in `~/.kward/plugins/*.rb` or a
38
+ package entrypoint at `~/.kward/plugins/*/plugin.rb`:
38
39
 
39
40
  ```ruby
40
41
  Kward.plugin do |plugin|
@@ -363,7 +364,7 @@ Unknown selector keys match same-named payload fields.
363
364
 
364
365
  ## Security notes
365
366
 
366
- - Plugin hooks are trusted Ruby code loaded only from `~/.kward/plugins/*.rb`.
367
+ - Plugin hooks are trusted Ruby code loaded only from `~/.kward/plugins/*.rb` or package entrypoints at `~/.kward/plugins/*/plugin.rb`.
367
368
  - Command hooks run local commands with your user permissions.
368
369
  - Workspace hook files are loaded only after `/hooks trust`, and trust is invalidated when `.kward/hooks.json` changes.
369
370
  - Hook payloads are intentionally bounded and metadata-oriented; avoid logging raw event JSON if your hook receives prompt or command data.
@@ -0,0 +1,130 @@
1
+ # Local models
2
+
3
+ If you already run Ollama, LM Studio, or llama.cpp, Kward can use it as a local model provider. This can be useful for offline work, tighter control over model selection, or a smaller prompt tuned for a local coding model. The server must provide OpenAI-compatible Chat Completions.
4
+
5
+ Kward connects to an already-running server; it does not install a runtime, download or load models, or choose GPU settings. For a comparison with hosted providers, see [Model providers](providers.md#Choosing_between_similar_providers).
6
+
7
+ ## Choose and start a runtime
8
+
9
+ Use one of these local servers:
10
+
11
+ | Runtime | Default Kward base URL |
12
+ | --- | --- |
13
+ | Ollama | `http://127.0.0.1:11434/v1` |
14
+ | LM Studio | `http://127.0.0.1:1234/v1` |
15
+ | llama.cpp `llama-server` | `http://127.0.0.1:8080/v1` |
16
+
17
+ Start the server and load a chat model before starting Kward. Then confirm that it reports models:
18
+
19
+ ```bash
20
+ curl http://127.0.0.1:11434/v1/models
21
+ ```
22
+
23
+ Use the equivalent configured port for LM Studio or llama.cpp.
24
+
25
+ ## Configure Kward
26
+
27
+ Add a Local provider configuration to `~/.kward/config.json`:
28
+
29
+ ```json
30
+ {
31
+ "provider": "local",
32
+ "local_backend": "ollama",
33
+ "local_model": "qwen2.5-coder:7b",
34
+ "local_context_window": 32768
35
+ }
36
+ ```
37
+
38
+ `local_backend` supplies a default endpoint for `ollama`, `lm_studio`, or `llama_cpp`. Set `local_base_url` when the server uses another host, port, path, Docker address, reverse proxy, or TLS endpoint:
39
+
40
+ ```json
41
+ {
42
+ "provider": "local",
43
+ "local_base_url": "http://127.0.0.1:1234/v1",
44
+ "local_model": "loaded-model-id",
45
+ "local_context_window": 32768
46
+ }
47
+ ```
48
+
49
+ Set `local_context_window` to the context length actually configured for the loaded model. Kward cannot reliably infer it from a local model name. The value lets Kward report meaningful context usage and make safe auto-compaction decisions.
50
+
51
+ If your local proxy requires a token, set `local_api_key` or `KWARD_LOCAL_API_KEY`. Kward sends it as a bearer token only for Local requests.
52
+
53
+ You can also choose **Local** from `/settings` → **Model & Reasoning** → **Provider**, then select a model with `/model`.
54
+
55
+ ## Use a minimal replacement prompt
56
+
57
+ Smaller models often work better with a short, direct prompt. Create a file beside your Kward config, for example `~/.kward/prompts/local-minimal.md`:
58
+
59
+ ```markdown
60
+ You are a coding assistant.
61
+ Use the provided tools when needed.
62
+ Inspect relevant files before changing them.
63
+ Make only requested changes and report what changed.
64
+ ```
65
+
66
+ Configure it as Kward's replacement system prompt:
67
+
68
+ ```json
69
+ {
70
+ "system_prompt": {
71
+ "file": "prompts/local-minimal.md",
72
+ "include_principles": false
73
+ }
74
+ }
75
+ ```
76
+
77
+ This file is the entire system prompt. Kward does not add its built-in instructions, `PRINCIPLES.md`, memory context, personas, plugin context, skills, or workspace `AGENTS.md` guidance in replacement mode.
78
+
79
+ If you want Kward's normal prompt but do not want global principles sent on every turn, omit the `file` and disable only principles:
80
+
81
+ ```json
82
+ {
83
+ "system_prompt": {
84
+ "include_principles": false
85
+ }
86
+ }
87
+ ```
88
+
89
+ Check the exact result before relying on it:
90
+
91
+ ```bash
92
+ kward sysprompt
93
+ kward sysprompt --raw
94
+ ```
95
+
96
+ Do not put secrets in a replacement prompt. Its contents are sent to the model and may be stored as a session prompt snapshot.
97
+
98
+ ## Verify tool calling
99
+
100
+ A coding agent needs more than ordinary chat: the model must request tools with valid arguments and use their results. Start with a safe read-only task:
101
+
102
+ ```text
103
+ Read README.md and summarize the project's test command. Do not modify files.
104
+ ```
105
+
106
+ Choose a model trained for tool or function calling. If it responds with prose instead of tool calls, use a tool-capable model or make the replacement prompt's tool guidance more explicit.
107
+
108
+ ## Security and limits
109
+
110
+ The default endpoints use loopback addresses. If you configure another host, Kward can send prompts, workspace-derived content, attachments, and tool results over that connection. Use TLS and authentication for any endpoint outside your machine or trusted private network.
111
+
112
+ Local model support uses the OpenAI-compatible Chat Completions interface, including streaming text and function/tool calls. Kward does not promise reasoning controls or image support for arbitrary local models.
113
+
114
+ ## Troubleshooting
115
+
116
+ **No models appear in `/model`**
117
+
118
+ Confirm the server is running, a model is loaded, and `GET /v1/models` succeeds. You can still set `local_model` manually when discovery is unavailable.
119
+
120
+ **The model stops early or Kward compacts too soon**
121
+
122
+ Check `local_context_window`. It must match the server's loaded-model context setting, not just the model's advertised training context.
123
+
124
+ **Tool calls are malformed or missing**
125
+
126
+ Use a tool-trained model and a compatible chat template. Test with a read-only task before allowing writes or shell commands.
127
+
128
+ **The server is slow**
129
+
130
+ Reduce the model size, reduce context length, verify GPU acceleration in the local runtime, or raise `stream_idle_timeout_seconds` if the server has long silent intervals.
data/doc/mcp.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # MCP servers
2
2
 
3
- Kward can connect to local [Model Context Protocol](https://modelcontextprotocol.io/) servers and expose their tools to the model alongside Kward's built-in workspace tools.
3
+ Kward can connect to local [Model Context Protocol](https://modelcontextprotocol.io/) servers and use their tools alongside its built-in workspace tools.
4
4
 
5
- This is useful when another app ships an MCP server for something Kward should be able to inspect or control. For example, Safari Technology Preview includes a Safari MCP server that lets agents inspect pages, console output, network activity, screenshots, and other browser state.
5
+ Use MCP when another app exposes something you want Kward to inspect or control. For example, Safari Technology Preview includes an MCP server for inspecting pages, console output, network activity, screenshots, and other browser state.
6
6
 
7
7
  ## Configure a local MCP server
8
8
 
@@ -66,7 +66,7 @@ Example with an environment variable and custom timeout:
66
66
 
67
67
  ## Notes and limitations
68
68
 
69
- - Kward currently supports local stdio MCP servers.
70
- - Kward currently exposes MCP tools. MCP resources, prompts, sampling, and Streamable HTTP are not implemented yet.
71
- - MCP tool results are returned to the model as text. Structured content is included as JSON. Image, audio, and resource results are summarized as placeholders for now.
69
+ - Kward supports local stdio MCP servers and exposes their tools to the model.
70
+ - It does not support MCP resources, prompts, sampling, or Streamable HTTP.
71
+ - MCP tool results are returned to the model as text. Structured content is included as JSON. Image, audio, and resource results are summarized as placeholders.
72
72
  - MCP servers can expose sensitive local application state. Only configure servers you trust, especially browser automation servers that can read page content or screenshots.
data/doc/permissions.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Permissions
2
2
 
3
- Kward's permission policy lets you put a human decision between a model-requested tool call and its side effect. It is useful when you want the agent to inspect a project freely, but want to confirm edits, commands, web requests, or MCP calls as they arise.
3
+ Turn on permissions when you want Kward to ask before it edits files, runs commands, accesses the web, or calls an MCP tool. In the usual `ask` mode, read-only work continues normally while you decide which side effects to allow.
4
4
 
5
- Permissions are **off by default**. Enabling them does not sandbox Kward or its subprocesses: an allowed shell command still runs with your operating-system user permissions.
5
+ Permissions are **off by default**. They are not an operating-system sandbox: an allowed shell command still runs with your operating-system user permissions unless you separately enable [command sandboxing](sandboxing.md) for model-requested shell commands.
6
6
 
7
7
  ## Start with approval mode
8
8
 
@@ -24,7 +24,16 @@ In `ask` mode, Kward allows ordinary read-only tools and asks before the agent:
24
24
  - searches or fetches content on the web,
25
25
  - calls an MCP tool.
26
26
 
27
- When approval is required in the interactive CLI, Kward opens a modal overlay. It shows the complete tool arguments, so an approval for `read_skill` includes the requested skill name and relative path, and an approval for a write includes its path and content. Choose **Allow once** to run that one call, **Allow this tool for this session** to allow later calls to the same tool in the current Kward session, or **Deny** to stop it. Pressing `Esc`, cancelling the overlay, or losing the approval bridge denies the call.
27
+ When Kward needs approval in the interactive CLI, it shows the complete tool arguments in an overlay. For example, a write request includes the file path and content.
28
+
29
+ Choose:
30
+
31
+ - **Allow once** to run this call.
32
+ - **Allow this tool for this session** to allow later calls to the same tool in the current session.
33
+ - **Deny** to stop the call.
34
+ - **Type something** to stop the call and tell Kward what to do instead.
35
+
36
+ Pressing `Esc`, closing the overlay, or losing the frontend connection denies the call.
28
37
 
29
38
  ### Steer the agent with `Type something`
30
39
 
@@ -91,7 +100,7 @@ With this configuration, the agent may edit `lib/` and `test/` without asking. A
91
100
 
92
101
  `write_scopes` narrows the policy's default workspace-write behavior; it does not broaden Kward's built-in workspace boundary. File tools still stay inside the active workspace by default, and existing files must still be read before Kward can edit them. See [Workspace tools](workspace-tools.md) for those guardrails.
93
102
 
94
- An empty `write_scopes` array permits no default workspace writes. Omit `write_scopes` if you want the `workspace-write` mode to cover the normal workspace file-tool boundary.
103
+ An empty `write_scopes` array permits no default workspace writes. Omit `write_scopes` if you want the `workspace-write` mode to cover the normal workspace file-tool boundary. The active worktree `git_commit` tool is treated as a mutating tool: it asks for approval in the default `ask` mode and is denied by read-only or deny-by-default modes unless explicitly allowed.
95
104
 
96
105
  ## Rules and precedence
97
106
 
@@ -169,11 +178,12 @@ The policy runs before Kward dispatches a model-requested tool. It does not cons
169
178
  - direct commands that you type yourself—`!command`, `/shell`, and `/pty`—are treated as your actions and are outside this first policy scope;
170
179
  - plugins, hooks, and MCP servers are trusted local extensions with their own process access.
171
180
 
172
- For sensitive work, use a restricted operating-system account, container, virtual machine, or disposable checkout. A future OS-enforced sandbox may provide stronger filesystem and network isolation; it is not part of the current permissions feature.
181
+ For sensitive work, use a restricted operating-system account, container, virtual machine, or disposable checkout. [Command sandboxing](sandboxing.md) is a separate, opt-in operating-system boundary for model-requested `run_shell_command` workers. It can add filesystem and child-network restrictions, but does not cover Kward's host process, extensions, or direct interactive commands.
173
182
 
174
183
  ## Related guides
175
184
 
176
185
  - [Security and trust](security.md): trust boundaries, extensions, and safe work in unfamiliar repositories.
177
186
  - [Configuration](configuration.md#Permissions): the complete configuration reference.
187
+ - [Command sandboxing](sandboxing.md): configure the separate OS boundary for model-requested shell commands.
178
188
  - [Lifecycle hooks](lifecycle-hooks.md): add trusted local policy or automation around Kward events.
179
189
  - [RPC protocol](rpc.md#Tool_approval_bridge): implement the approval bridge in an RPC client.
data/doc/plugins.md CHANGED
@@ -21,16 +21,21 @@ Plugins run inside the Kward process with your user permissions. Install only pl
21
21
  | Repository rules | `AGENTS.md` |
22
22
  | Local Ruby code or integration | plugin |
23
23
 
24
- See [Extensibility](extensibility.md) for the full overview of Kward's extension points and prompt assembly order.
24
+ See [Extensibility](extensibility.md) for the full overview of Kward's extension points and prompt assembly order. See [Transports](transports.md) for external messaging and event integrations.
25
25
 
26
26
  ## Where plugins live
27
27
 
28
- Kward loads top-level Ruby files from:
28
+ Kward loads trusted Ruby plugin entrypoints from:
29
29
 
30
30
  ```text
31
31
  ~/.kward/plugins/*.rb
32
+ ~/.kward/plugins/*/plugin.rb
32
33
  ```
33
34
 
35
+ For a larger plugin, use a directory with `plugin.rb` as its entry point. Kward
36
+ loads only that file automatically, so use `require_relative` there to load any
37
+ sibling files.
38
+
34
39
  Plugins are not loaded from the current workspace or a custom `KWARD_CONFIG_PATH` directory. This prevents a project checkout from silently adding executable Ruby code to Kward.
35
40
 
36
41
  ## A first plugin
@@ -58,7 +63,7 @@ Start Kward and run:
58
63
  /hello World
59
64
  ```
60
65
 
61
- When developing plugins, use `/reload` inside Kward to reload all plugin files without restarting. This picks up changes to existing plugins and registers new ones, then rebuilds the system message.
66
+ When developing plugins or prompt templates, use `/reload` inside Kward to reload configured prompt files and all plugin files without restarting. This picks up prompt edits, changes to existing plugins, and new plugin registrations, then refreshes slash-command completion and rebuilds the system message.
62
67
 
63
68
  ## Add a slash command
64
69
 
@@ -111,7 +116,7 @@ Kward.plugin do |plugin|
111
116
  end
112
117
  ```
113
118
 
114
- Only one footer is active. If multiple plugins register footers, the later one replaces the earlier one and Kward prints a warning.
119
+ Only one footer is active. If multiple plugins register footers, the later one replaces the earlier one and Kward prints a warning. Kward evaluates the active footer at most once per second and reuses its last value between refreshes.
115
120
 
116
121
  ## Add an interactive command
117
122
 
@@ -132,6 +137,7 @@ Kward.plugin do |plugin|
132
137
  x = (x + 1) % ui.width
133
138
  key = ui.poll_key
134
139
  return :exit if key == :ctrl_c || key == "q"
140
+ ui.render
135
141
  end
136
142
  end
137
143
  end
@@ -162,6 +168,8 @@ Keys are returned as symbols (`:left`, `:right`, `:up`, `:down`, `:return`,
162
168
  without a named mapping. Ctrl+C always exits the loop immediately.
163
169
 
164
170
  The tick callback runs at the configured frame rate (1–120 fps, default 30).
171
+ Calls to `put` and `clear_frame` stage canvas changes; call `render` after the
172
+ frame is complete to publish it. Kward skips ticks that do not publish a frame.
165
173
  Returning `:exit` from the tick callback ends the loop, same as calling
166
174
  `ui.exit`.
167
175
 
@@ -219,6 +227,7 @@ The observer context exposes the plugin tab's `messages` through
219
227
  - `messages` — renderable transcript messages;
220
228
  - `submit(input, display_input:, cancellation:, steering:)` — a turn method
221
229
  that returns the final response and yields stream events;
230
+ - optionally `submit(..., context:)` — trusted actor context for transport turns;
222
231
  - `descriptor` — the durable tab descriptor;
223
232
  - `supports_steering?` and `assistant_label`.
224
233
 
@@ -234,6 +243,32 @@ plugin.tab_type "example", id: "com.example.chat", rpc: true do |host, descripto
234
243
  end
235
244
  ```
236
245
 
246
+ Set `transport: true` separately when an external transport may target the
247
+ plugin chat. Do not use `rpc: true` as an implicit external-access permission:
248
+
249
+ ```ruby
250
+ plugin.tab_type "example", id: "com.example.chat", rpc: true, transport: true do |host, descriptor|
251
+ ExampleChat.new(client: host.client, descriptor: descriptor)
252
+ end
253
+ ```
254
+
255
+ Set `local: false` for a transport-only plugin chat. It remains available to
256
+ transports when `transport: true`, but `/tab open` and local tab restoration do
257
+ not expose it:
258
+
259
+ ```ruby
260
+ plugin.tab_type "telegram", id: "com.example.telegram", local: false, transport: true do |host, descriptor|
261
+ ExampleChat.new(client: host.client, descriptor: descriptor)
262
+ end
263
+ ```
264
+
265
+ Transport-created plugin chats receive a descriptor containing a stable scoped
266
+ key, transport identity, external conversation, and actor metadata. Use the
267
+ scope to select separate transcript and memory roots. The driver may accept a
268
+ `context:` keyword on `submit` to receive the authenticated actor for each
269
+ turn; access decisions must still be enforced by the transport and plugin code,
270
+ not by model instructions.
271
+
237
272
  RPC clients discover opted-in types through `initialize.capabilities.pluginChats`, open a chat with `pluginChats/open`, and must explicitly subscribe before receiving live `pluginChat/event` notifications. See [RPC](rpc.md) for the protocol. Plugin tabs remain CLI-only unless they opt in.
238
273
 
239
274
  ## Observe transcript events
@@ -0,0 +1,105 @@
1
+ # Prompt templates
2
+
3
+ Prompt templates turn a repeated request into a slash command. Keep one when you regularly ask Kward to plan before coding, investigate without changing files, or review a particular part of a project in the same way.
4
+
5
+ Templates are reusable **user prompts**, not always-on instructions. Kward expands the selected template when you run its slash command, then sends the expanded text as your request.
6
+
7
+ Use [skills](skills.md) for task guidance the model can load when relevant, `PRINCIPLES.md` for preferences that apply broadly, and `AGENTS.md` for repository rules.
8
+
9
+ ## Create a template
10
+
11
+ By default, put one Markdown file per command in:
12
+
13
+ ```text
14
+ ~/.kward/prompts/
15
+ ```
16
+
17
+ For example, create `~/.kward/prompts/review.md`:
18
+
19
+ ```markdown
20
+ ---
21
+ description: Review a change for correctness.
22
+ argument-hint: <focus>
23
+ ---
24
+
25
+ Review the current diff for correctness, tests, and maintainability.
26
+ Focus on: $ARGUMENTS
27
+ Do not edit files; report findings first.
28
+ ```
29
+
30
+ Restart Kward, or use `/reload` in an already-running session. The filename becomes the command name:
31
+
32
+ ```text
33
+ /review authentication edge cases
34
+ ```
35
+
36
+ Kward expands `$ARGUMENTS` everywhere it appears in the body with the text after `/review`. In this example, the model receives `Focus on: authentication edge cases`. If the template does not contain `$ARGUMENTS`, supplied arguments are not added automatically.
37
+
38
+ The `description` and `argument-hint` frontmatter fields are optional, but useful: Kward shows them in slash-command completion. The rest of the file is the prompt body. Add as much Markdown structure and instruction text as the workflow needs.
39
+
40
+ ## Naming and discovery
41
+
42
+ Kward reads `*.md` files directly inside the prompts directory, in filename order. It ignores subdirectories. A filename must produce a command containing only letters, numbers, `_`, and `-`, and must begin with a letter or number:
43
+
44
+ ```text
45
+ ~/.kward/prompts/
46
+ ├── review.md # /review
47
+ ├── release-check.md # /release-check
48
+ └── api_v2.md # /api_v2
49
+ ```
50
+
51
+ A template cannot replace a built-in slash command such as `/settings`, `/skill`, or `/reload`; Kward warns and skips it. It also warns and skips files with invalid Markdown frontmatter or command names.
52
+
53
+ `~/.kward/prompts` is the default. When `KWARD_CONFIG_PATH` points to another config file, templates live in the `prompts/` directory beside that file instead. See [Configuration](configuration.md#Config_directory).
54
+
55
+ ## Starter templates from `kward init`
56
+
57
+ After installing Kward, run:
58
+
59
+ ```bash
60
+ kward init
61
+ ```
62
+
63
+ The starter pack downloads template files into `~/.kward/prompts/` without overwriting files that already exist. It currently installs these four commands:
64
+
65
+ | Command | Use it for | What it asks Kward to do |
66
+ | --- | --- | --- |
67
+ | `/plan <task-or-change>` | Agree on an approach before coding | Clarify important requirements, produce a concise plan, and wait for confirmation before implementation. |
68
+ | `/investigate <bug-or-behavior>` | Diagnose a bug or surprising result | Gather evidence, identify the root cause or strongest hypothesis, suggest the smallest safe fix, and make no edits. |
69
+ | `/research <question-or-topic>` | Answer a question that needs current or external evidence | Prefer primary sources, separate facts from recommendations, cite sources and caveats, and make no changes. |
70
+ | `/codebase-review [scope-or-focus]` | Assess a repository or area for practical cleanup | Report concrete maintainability, correctness, duplication, ownership, testing, and hot-path findings without refactoring. |
71
+
72
+ For example:
73
+
74
+ ```text
75
+ /plan Add rate limiting to the public API
76
+ /investigate The session picker occasionally shows the wrong title
77
+ /research Which OAuth scopes does this provider require?
78
+ /codebase-review lib/kward/model
79
+ ```
80
+
81
+ The starter templates deliberately favor report- or plan-first workflows. They do not make Kward edit files until you follow up with an explicit implementation request. Edit the installed files to fit your own process, or add new files alongside them.
82
+
83
+ `kward init` also installs a base `PRINCIPLES.md` and starter skills. It needs network access to fetch the versioned [starter pack](https://github.com/kaiwood/kward-starter-pack) and leaves existing destination files untouched.
84
+
85
+ ## Practical patterns
86
+
87
+ Keep templates specific enough to set a workflow, but short enough that the request remains easy to adapt. For example, a release-check prompt might take a version as an argument:
88
+
89
+ ```markdown
90
+ ---
91
+ description: Prepare release notes and verification for a version.
92
+ argument-hint: <version>
93
+ ---
94
+
95
+ Prepare the release checklist for version $ARGUMENTS.
96
+ Inspect the changelog and version files. Do not publish or tag a release.
97
+ ```
98
+
99
+ Then run:
100
+
101
+ ```text
102
+ /release-check 1.4.0
103
+ ```
104
+
105
+ Templates only expand text; they do not execute local code, grant permissions, or bypass Kward's tool and workspace safeguards.