kward 0.81.0 → 0.83.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/Gemfile.lock +2 -2
- data/README.md +1 -1
- data/Rakefile +44 -4
- data/doc/agent-tools.md +1 -0
- data/doc/composer.md +2 -2
- data/doc/configuration.md +18 -3
- data/doc/editor.md +20 -10
- data/doc/files.md +12 -5
- data/doc/permissions.md +1 -0
- data/doc/releasing.md +79 -38
- data/doc/rpc.md +2 -2
- data/doc/sandboxing.md +5 -1
- data/doc/security.md +2 -2
- data/doc/shell.md +42 -18
- data/doc/tabs.md +3 -0
- data/doc/usage.md +3 -2
- data/kward.gemspec +1 -1
- data/lib/kward/adaptive_pty_output_sink.rb +183 -0
- data/lib/kward/agent.rb +1 -0
- data/lib/kward/auth/anthropic_oauth.rb +7 -7
- data/lib/kward/cli/git.rb +5 -1
- data/lib/kward/cli/interactive_turn.rb +101 -19
- data/lib/kward/cli/rendering.rb +14 -2
- data/lib/kward/cli/runtime_helpers.rb +252 -46
- data/lib/kward/cli/settings.rb +5 -13
- data/lib/kward/cli/slash_commands.rb +12 -1
- data/lib/kward/cli/tabs.rb +71 -9
- data/lib/kward/cli.rb +12 -0
- data/lib/kward/compaction/token_estimator.rb +12 -6
- data/lib/kward/config_files.rb +17 -0
- data/lib/kward/editor_prompt.rb +46 -0
- data/lib/kward/editor_prompt_session.rb +28 -0
- data/lib/kward/ekwsh.rb +70 -10
- data/lib/kward/image_attachments.rb +98 -15
- data/lib/kward/interactive_pty_runner.rb +25 -19
- data/lib/kward/model/client.rb +1 -17
- data/lib/kward/model/model_info.rb +3 -2
- data/lib/kward/model/payloads.rb +0 -2
- data/lib/kward/persistent_shell_session.rb +750 -0
- data/lib/kward/project_files.rb +18 -5
- data/lib/kward/prompt_interface/composer_controller.rb +3 -3
- data/lib/kward/prompt_interface/composer_renderer.rb +28 -1
- data/lib/kward/prompt_interface/editor/auto_indent.rb +3 -0
- data/lib/kward/prompt_interface/editor/controller.rb +75 -6
- data/lib/kward/prompt_interface/editor/modes/emacs.rb +2 -2
- data/lib/kward/prompt_interface/editor/modes/modern.rb +4 -0
- data/lib/kward/prompt_interface/editor/modes/vibe.rb +12 -6
- data/lib/kward/prompt_interface/editor/renderer.rb +1 -0
- data/lib/kward/prompt_interface/editor/state.rb +11 -0
- data/lib/kward/prompt_interface/editor/word_completion.rb +124 -0
- data/lib/kward/prompt_interface/file_overlay.rb +21 -7
- data/lib/kward/prompt_interface/git_prompt.rb +1 -1
- data/lib/kward/prompt_interface/key_handler.rb +30 -0
- data/lib/kward/prompt_interface/overlay_renderer.rb +1 -0
- data/lib/kward/prompt_interface/project_browser.rb +192 -8
- data/lib/kward/prompt_interface/prompt_renderer.rb +15 -6
- data/lib/kward/prompt_interface/question_prompt.rb +1 -1
- data/lib/kward/prompt_interface/runtime_state.rb +5 -1
- data/lib/kward/prompt_interface/screen.rb +40 -20
- data/lib/kward/prompt_interface/selection_prompt.rb +5 -5
- data/lib/kward/prompt_interface/transcript_renderer.rb +4 -4
- data/lib/kward/prompt_interface.rb +159 -32
- data/lib/kward/prompts/commands.rb +1 -0
- data/lib/kward/pty_output_sink.rb +45 -0
- data/lib/kward/pty_transcript_normalizer.rb +93 -0
- data/lib/kward/rpc/auth_manager.rb +1 -1
- data/lib/kward/rpc/server.rb +2 -1
- data/lib/kward/session_catalog.rb +87 -0
- data/lib/kward/session_store.rb +94 -5
- data/lib/kward/shell_prompt.rb +50 -0
- data/lib/kward/shell_prompt_session.rb +58 -0
- data/lib/kward/terminal_image_support.rb +116 -0
- data/lib/kward/terminal_keys.rb +1 -0
- data/lib/kward/terminal_sequences.rb +43 -0
- data/lib/kward/tools/prepare_shell_command.rb +28 -0
- data/lib/kward/tools/registry.rb +63 -5
- data/lib/kward/tools/replace_editor_buffer.rb +30 -0
- data/lib/kward/tools/run_shell_command.rb +24 -6
- data/lib/kward/version.rb +1 -1
- data/templates/default/layout/html/layout.erb +1 -1
- metadata +15 -4
- data/.github/workflows/ci.yml +0 -48
- data/.github/workflows/pages.yml +0 -48
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 678c9e9bb188e6c3d065dfde6b97c9ec5c31b29b178b40d69b0397b5200eb2a8
|
|
4
|
+
data.tar.gz: 3e09cb3d11ff6018ecc75e3eb31e8745e72e534dba7a4c3711a488451d353fcc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f4247a32300deff0906c95c10d7312aa6303108956596f16d9f2c6d2d4fc444b5ef377751f47dbd2157b041710d855c44a981a1a22f8a562c79203afe8b65ed
|
|
7
|
+
data.tar.gz: d93d09126d221c05d7ef0e931f46ccfaa4a84450e6eb5695dbea653d8b9de99bb27bc7fb070b323c74160477fd328f0be3cd972d544b45e3ea90ffbeb79cb087
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,62 @@ All notable changes to Kward will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.83.0] - 2026-08-28
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added `?` shell prompts for transient, context-aware assistance inside `/shell`, including shared shell-state commands and prepare-without-execute command drafts.
|
|
12
|
+
- Added `Ctrl+.` in Modern editor mode to open an in-editor prompt line for communicating with the dedicated editor agent.
|
|
13
|
+
- Added Vibe `:prompt <instruction>` support, allowing the agent to inspect and replace the active in-memory editor buffer without saving it automatically.
|
|
14
|
+
- Added current-buffer word completion to the integrated editor, with repeated Tab presses cycling nearby matches and existing smart indentation retained when no match exists.
|
|
15
|
+
- Added Claude Opus 5 to the Anthropic model picker with its 1M context window and high-reasoning metadata.
|
|
16
|
+
- Added an `i` toggle to the `/files` browser for showing Git-ignored files, which remain hidden by default.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- `/shell` now keeps one persistent local shell process per tab so shell variables, functions, aliases, and directory changes are shared by user and agent commands.
|
|
21
|
+
- Shell-agent turns use a transient per-tab context and receive only bounded, sanitized output after an explicit `?` request; ordinary shell output remains outside model context.
|
|
22
|
+
- Shell-agent transcript output is now retained as bounded, tab-local runtime state so it survives tab switches without entering session history.
|
|
23
|
+
- Vibe editor-agent turns now use an isolated, configurable model/reasoning context, remain visible with a status-line spinner, and stay out of normal chat transcripts and session history.
|
|
24
|
+
- Removed the obsolete GPT-5.6 Luna Responses Lite compatibility workaround so Luna requests retain Kward's identity and standard Codex payload.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Made persistent shell command cancellation and timeouts recover by restarting an unresponsive embedded shell, and stabilized raw-input coverage across platforms.
|
|
29
|
+
- Restored full-screen Git pagers and immediate key/Ctrl+C forwarding for interactive `/shell` commands by removing Kward's ambient `GIT_PAGER=cat` default and putting host input in raw mode during persistent-shell handoff, while keeping paging suppressed for captured and shell-agent commands.
|
|
30
|
+
- Fixed Claude subscription OAuth authorization and token-exchange requests by removing unsupported subscription scopes and the nonstandard `code` query parameter, and by forwarding the OAuth state to the token endpoint.
|
|
31
|
+
- Installed and enabled Bubblewrap during release verification so Linux worktree tests use the same sandbox setup as normal CI, added manual recovery for existing release tags, and made publication wait for and attach the canonical RubyGems artifact after trusted-publishing attestation.
|
|
32
|
+
- Fixed automatic context compaction so Codex response items are included in token estimates and long tool-call turns are checked before each model request.
|
|
33
|
+
|
|
34
|
+
## [0.82.0] - 2026-08-23
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- Added `script/release` for validated, one-command release preparation from an argument or standard input, including changelog/version updates, preflight checks, an annotated tag, and an atomic push.
|
|
39
|
+
- Added a tag-triggered GitHub Actions release workflow using RubyGems trusted publishing, published-artifact checksum verification, changelog-based GitHub Releases, and safe reruns after partial publication.
|
|
40
|
+
- Added `+` and `-` controls for resizing inline `/files` image previews within the available overlay space.
|
|
41
|
+
- Added inline read-only previews for PNG, JPEG, GIF, and WebP files opened from `/files` in terminals that support Kitty or iTerm2 image sequences, with local conversion for Kitty-compatible terminals when needed.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Excluded GitHub workflow and local release-script files from packaged gems and added explicit release metadata and package-content checks.
|
|
46
|
+
- Changed interactive PTY handoff to render conservative line/progress output above a frozen composer, with a permanent switch to exclusive full-terminal passthrough when the child emits screen-oriented or unknown controls.
|
|
47
|
+
- Kept safe, normalized shell output as explicit tab-local transient state so completed `/shell` and `!command` output can be reconstructed after tab switches without entering session history or model context.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- Made the test environment explicitly disable terminal color and made unified diff-viewer tests select that mode explicitly, keeping release preflight assertions deterministic across terminal capabilities and widths.
|
|
52
|
+
- Kept `/files` image previews bounded within a fully cleared, bordered file-list overlay above the visible composer and preserved their aspect ratio in Kitty-compatible terminals.
|
|
53
|
+
- Fixed inline image protocol detection and viewer handoff for Ghostty and other Kitty-compatible terminals by retrying inconclusive probes, honoring recognized Kitty hints, suppressing Kitty acknowledgements, and using valid, chunked graphics sequences.
|
|
54
|
+
- Kept synchronized-output updates such as Homebrew downloads in the inline PTY region instead of resetting the cursor through an unnecessary exclusive handoff.
|
|
55
|
+
- Retained the final visible state of carriage-return and horizontal-cursor progress output from commands such as `git push` and Homebrew when reconstructing the transcript after PTY handback.
|
|
56
|
+
- Cached rebuildable session-list summaries so opening `/session` no longer reparses every unchanged conversation log, while retaining automatic fallback for existing, changed, or corrupt session data.
|
|
57
|
+
- Refreshed composer status immediately after model runtime changes and `/git` returns, so selected model details and Git dirty-state color do not remain stale until another input.
|
|
58
|
+
- Kept echoed passwords, OTPs, and other child input out of transient tab state by stopping safe PTY output retention before the first forwarded input byte.
|
|
59
|
+
- Reconstructed safe transient shell output as part of the PTY ownership handback frame, avoiding an extra clear and redraw after commands such as `ls`.
|
|
60
|
+
- Preserved the active `/shell` prompt and composer when Ctrl+L clears transient shell output, and avoided a redundant preliminary redraw.
|
|
61
|
+
- Reconstructed the complete Kward screen after interactive PTY handoff, including failure paths, instead of relying on the child process cursor position.
|
|
62
|
+
|
|
7
63
|
## [0.81.0] - 2026-08-20
|
|
8
64
|
|
|
9
65
|
### Added
|
|
@@ -62,6 +118,7 @@ All notable changes to Kward will be documented in this file.
|
|
|
62
118
|
- Added Git worktree bindings for normal interactive session tabs. `/tab worktree` can move a tab into a strict linked-worktree workspace after research, preserve its transcript, warn about dirty origin changes, and keep the branch available when explicitly detached.
|
|
63
119
|
- Added the active worktree `git_commit` model tool, allowing explicitly requested agent commits through the trusted host-side Git workflow without widening the shell sandbox.
|
|
64
120
|
- Added `/tab worktree merge` for explicitly merging a clean worktree branch into the branch checked out in its original workspace, plus `/tab worktree merge abort` for conflicted merges.
|
|
121
|
+
- Added `/worktree` as a concise alias for `/tab worktree` on the active tab.
|
|
65
122
|
- Added `j`/`k` keyboard navigation to the `/files` project browser.
|
|
66
123
|
- Added `h`/`l` keyboard navigation for collapsing and expanding `/files` directories.
|
|
67
124
|
- Added `j`/`k` keyboard navigation to the `/git` changed-file overlay.
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
kward (0.
|
|
4
|
+
kward (0.83.0)
|
|
5
5
|
base64
|
|
6
6
|
nokogiri
|
|
7
7
|
tiktoken_ruby
|
|
@@ -146,7 +146,7 @@ CHECKSUMS
|
|
|
146
146
|
html-proofer (5.2.1) sha256=fdd958a7cbf9c3255fb96fe7cfc4e611f64e2706e469488a3326309ad007d2fd
|
|
147
147
|
io-event (1.16.2) sha256=9f9cb0a96ea5c3850a672606c65f27bc96d7621399ef6196acbfe2be0cd1279c
|
|
148
148
|
json (2.19.9) sha256=9b9025b7cdddafa38d316eca0b2358488e42d417045c1b90d216a9fefe46b79a
|
|
149
|
-
kward (0.
|
|
149
|
+
kward (0.83.0)
|
|
150
150
|
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
151
151
|
metrics (0.15.0) sha256=61ded5bac95118e995b1bc9ed4a5f19bc9814928a312a85b200abbdac9039072
|
|
152
152
|
minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
|
data/README.md
CHANGED
|
@@ -92,7 +92,7 @@ Extend and integrate:
|
|
|
92
92
|
- [Plugins](doc/plugins.md): trusted Ruby plugins for commands, footer UI, prompt context, transcript events, and RPC clients.
|
|
93
93
|
- [Lifecycle hooks](doc/lifecycle-hooks.md): deterministic runtime hooks for policy, approvals, automation, and command-hook integrations.
|
|
94
94
|
- [RPC protocol](doc/rpc.md): JSON-RPC backend mode for trusted local UI clients.
|
|
95
|
-
- [Releasing](doc/releasing.md):
|
|
95
|
+
- [Releasing](doc/releasing.md): prepare a version and publish it through RubyGems and GitHub Releases.
|
|
96
96
|
|
|
97
97
|
Reference guides:
|
|
98
98
|
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
1
2
|
require "fileutils"
|
|
2
3
|
require "html-proofer"
|
|
4
|
+
require "open3"
|
|
3
5
|
require "rdoc/task"
|
|
4
6
|
require "rubygems/package"
|
|
5
7
|
require "webrick"
|
|
@@ -33,6 +35,36 @@ def packaged_gem_files(gem_name)
|
|
|
33
35
|
gem.spec.files.sort
|
|
34
36
|
end
|
|
35
37
|
|
|
38
|
+
def verify_release_metadata
|
|
39
|
+
version = Kward::VERSION
|
|
40
|
+
tag = "v#{version}"
|
|
41
|
+
changelog = File.read("CHANGELOG.md")
|
|
42
|
+
abort("CHANGELOG.md is missing a [#{version}] release heading") unless changelog.match?(/^## \[#{Regexp.escape(version)}\] - \d{4}-\d{2}-\d{2}$/)
|
|
43
|
+
|
|
44
|
+
if ENV["GITHUB_REF_TYPE"] == "tag" && ENV["GITHUB_REF_NAME"] != tag
|
|
45
|
+
abort("GitHub tag #{ENV["GITHUB_REF_NAME"]} does not match gem version #{version}")
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
tag_commit, tag_status = Open3.capture2e("git", "rev-parse", "--verify", "#{tag}^{commit}")
|
|
49
|
+
return unless tag_status.success?
|
|
50
|
+
|
|
51
|
+
head_commit = `git rev-parse HEAD`.strip
|
|
52
|
+
abort("Tag #{tag} does not point at HEAD") unless tag_commit.strip == head_commit
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def verify_packaged_gem(gem_name)
|
|
56
|
+
files = packaged_gem_files(gem_name)
|
|
57
|
+
required = ["exe/kward", "lib/kward/version.rb"]
|
|
58
|
+
missing = required - files
|
|
59
|
+
abort("Packaged gem is missing: #{missing.join(", ")}") unless missing.empty?
|
|
60
|
+
|
|
61
|
+
forbidden_prefixes = [".github/", "script/", "test/", "plan/"]
|
|
62
|
+
forbidden = files.select { |file| forbidden_prefixes.any? { |prefix| file.start_with?(prefix) } }
|
|
63
|
+
abort("Packaged gem includes development files: #{forbidden.join(", ")}") unless forbidden.empty?
|
|
64
|
+
|
|
65
|
+
files
|
|
66
|
+
end
|
|
67
|
+
|
|
36
68
|
def rewrite_yard_markdown_links
|
|
37
69
|
guide_names = Dir.glob("doc/*.md").map { |path| File.basename(path, ".md") }
|
|
38
70
|
|
|
@@ -75,15 +107,23 @@ YARD::Rake::YardocTask.new do |yard|
|
|
|
75
107
|
end
|
|
76
108
|
|
|
77
109
|
namespace :release do
|
|
110
|
+
desc "Verify the version, changelog, and release tag agree"
|
|
111
|
+
task :verify do
|
|
112
|
+
verify_release_metadata
|
|
113
|
+
end
|
|
114
|
+
|
|
78
115
|
desc "Run release checks and build a local gem"
|
|
79
|
-
task preflight: [:test, "docs:check"] do
|
|
80
|
-
gem_name = "kward-#{Kward::VERSION}.gem"
|
|
116
|
+
task preflight: ["release:verify", :test, "docs:check"] do
|
|
117
|
+
gem_name = File.join("pkg", "kward-#{Kward::VERSION}.gem")
|
|
81
118
|
FileUtils.rm_f(gem_name)
|
|
82
|
-
|
|
83
|
-
puts
|
|
119
|
+
Rake::Task["build"].invoke
|
|
120
|
+
puts verify_packaged_gem(gem_name)
|
|
84
121
|
end
|
|
85
122
|
end
|
|
86
123
|
|
|
124
|
+
Rake::Task["release:source_control_push"].enhance(["release:verify"])
|
|
125
|
+
Rake::Task["release:rubygem_push"].enhance(["release:verify"])
|
|
126
|
+
|
|
87
127
|
namespace :docs do
|
|
88
128
|
desc "Serve the built YARD documentation site locally and rebuild on changes"
|
|
89
129
|
task serve: :build do
|
data/doc/agent-tools.md
CHANGED
|
@@ -15,6 +15,7 @@ Tools also enforce important boundaries:
|
|
|
15
15
|
| Category | Tools | Guide |
|
|
16
16
|
| --- | --- | --- |
|
|
17
17
|
| Workspace tools | `list_directory`, `read_file`, `context_for_task`, `context_budget_stats`, `summarize_file_structure`, `write_file`, `edit_file`, `run_shell_command` | [Workspace tools](workspace-tools.md) |
|
|
18
|
+
| Shell prompt tools | `run_shell_command`, `prepare_shell_command` (available only to the transient `?` shell assistant) | [Embedded shell](shell.md) |
|
|
18
19
|
| Web tools | `web_search`, `fetch_content`, `fetch_raw` | [Web search](web-search.md) |
|
|
19
20
|
| Code search | `code_search` | [Code search](code-search.md) |
|
|
20
21
|
| Context and interaction tools | `read_skill`, `retrieve_tool_output`, `ask_user_question` | [Context tools](context-tools.md) |
|
data/doc/composer.md
CHANGED
|
@@ -186,7 +186,7 @@ Example:
|
|
|
186
186
|
|
|
187
187
|
If the cursor is at the start of an otherwise empty draft, Backspace removes the most recently added pending attachment. Submitting the draft clears its pending attachments.
|
|
188
188
|
|
|
189
|
-
The active model must support image input. iTerm2 and Kitty-compatible terminals can render submitted images inline;
|
|
189
|
+
The active model must support image input. iTerm2 and Kitty-compatible terminals can render submitted images inline; Kward uses active Kitty capability detection when running on a real TTY and falls back to conservative terminal hints otherwise. Other terminals still show attachment badges and send the image to the model without an inline preview.
|
|
190
190
|
|
|
191
191
|
## Understand composer status
|
|
192
192
|
|
|
@@ -213,4 +213,4 @@ If rendering becomes corrupted after resize or after an external program writes
|
|
|
213
213
|
|
|
214
214
|
You can also press `Ctrl+L`; it rebuilds the durable current-tab view without deleting the conversation transcript, removing transient shell output. If a shortcut never reaches Kward, prefer its slash-command equivalent or change `composer.tab_keybindings` in `/settings`.
|
|
215
215
|
|
|
216
|
-
External commands inside `/shell` and one-shot `!command` input receive an interactive PTY by default,
|
|
216
|
+
External commands inside `/shell` and one-shot `!command` input receive an interactive PTY by default. They begin inline above a frozen composer, then switch to full-terminal passthrough if they emit screen-oriented or unknown terminal controls; full-screen programs such as Vim or `less` can therefore temporarily own the terminal. While Kward owns the shell composer, a leading `?` asks the transient shell assistant; it receives only bounded, sanitized output from the latest command. Use `capture <command>` inside `/shell` or `/capture <command>` from the normal composer for bounded, sanitized transcript output.
|
data/doc/configuration.md
CHANGED
|
@@ -184,9 +184,9 @@ aliases:
|
|
|
184
184
|
gd: "git diff --color=always"
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
`env` values are applied when shell mode starts, after Kward's conservative color defaults. Keys must look like environment variable names (`A_Z`, digits after the first character, and underscores); invalid keys are ignored. Values are converted to strings.
|
|
187
|
+
`env` values are applied when shell mode starts, after Kward's conservative color defaults. `/shell` keeps one persistent local interactive shell process per tab. Keys must look like environment variable names (`A_Z`, digits after the first character, and underscores); invalid keys are ignored. Values are converted to strings.
|
|
188
188
|
|
|
189
|
-
`aliases` expand the first word of a command once. For example, `ll lib` runs `ls -la lib`. Configured aliases are available both inside `/shell` and after the normal composer's `!` prefix, including command-name Tab completion. Built-in
|
|
189
|
+
`aliases` expand the first word of a command once. For example, `ll lib` runs `ls -la lib`. Configured aliases are available both inside `/shell` and after the normal composer's `!` prefix, including command-name Tab completion. Built-in shell commands such as `cd`, `pwd`, `export`, `unset`, `alias`, `capture`, `clear`, `pty`, and `exit` take precedence over aliases inside `/shell`. External commands receive an interactive PTY by default. Prefix a submitted line with `?` inside `/shell` to ask the transient shell assistant about the current command output or state. An alias value can begin with `capture` when its `/shell` output should use the configured timeout, output limit, and transcript sanitization. Leading-`!` alias invocations are always interactive, so Kward removes a leading `capture` or legacy `pty` mode marker from the expanded alias before execution. Run `alias` inside `ekwsh` to list configured aliases. Aliases created at runtime with that built-in belong only to the current `/shell` session and are not available to `!command` input.
|
|
190
190
|
|
|
191
191
|
## Provider and model settings
|
|
192
192
|
|
|
@@ -248,7 +248,7 @@ Defaults:
|
|
|
248
248
|
- Copilot: `gpt-5-mini`
|
|
249
249
|
- Reasoning effort: `medium`
|
|
250
250
|
|
|
251
|
-
The Anthropic model choices include `claude-fable-5`,
|
|
251
|
+
The Anthropic model choices include `claude-fable-5`, `claude-opus-5`, and `claude-sonnet-5`. Fable and Opus availability depends on the logged-in account and organization. Selecting a model without access returns an Anthropic provider error. Kward keeps Sonnet 5 as its default because it supports both Pro and Max subscriptions; select Opus 5 explicitly when it is available on the account.
|
|
252
252
|
|
|
253
253
|
The interactive `/model` picker reads cached OpenRouter models when available. Run `kward openrouter refresh` to fetch text-capable models available to the configured OpenRouter API key and cache them under `~/.kward/cache/openrouter_models.json`. Run `kward openrouter list` to inspect the cached model ids.
|
|
254
254
|
|
|
@@ -393,6 +393,21 @@ The built-in TUI file editor supports three keybinding modes. Modern is the defa
|
|
|
393
393
|
|
|
394
394
|
`mode` can be `modern`, `emacs`, or `vibe`. The old `default` value is still accepted as an alias for `modern`. You can change this from `/settings` → Interface → Editor mode; newly opened editor buffers pick up the setting immediately.
|
|
395
395
|
|
|
396
|
+
Vibe `:prompt` uses a dedicated transient editor agent. Configure its model and reasoning effort under `editor.agent` when it should differ from the active tab:
|
|
397
|
+
|
|
398
|
+
```json
|
|
399
|
+
{
|
|
400
|
+
"editor": {
|
|
401
|
+
"agent": {
|
|
402
|
+
"model": "gpt-5.5",
|
|
403
|
+
"reasoning_effort": "medium"
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
These settings use the active tab's provider. If either value is omitted, Kward falls back to the active tab's value and then the client default. Editor-agent prompts and tool activity are kept out of the normal transcript and session history; the editor remains visible with a spinner while the transient turn runs.
|
|
410
|
+
|
|
396
411
|
The integrated Git and session diff viewers support unified and side-by-side layouts:
|
|
397
412
|
|
|
398
413
|
```json
|
data/doc/editor.md
CHANGED
|
@@ -43,7 +43,7 @@ For a nested project tree, run:
|
|
|
43
43
|
/files
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
In the tree browser, use `↑`/`↓` to move, `←`/`→` to collapse or expand directories, `Enter` to toggle a directory or open a file, `Tab` or `/` to search, `@` to insert the selected file as an `@path` mention, and `Esc` to close. When you open a file from `/files`, quitting the editor returns to the browser at the same position.
|
|
46
|
+
In the tree browser, use `↑`/`↓` to move, `←`/`→` to collapse or expand directories, `Enter` to toggle a directory or open a file, `Tab` or `/` to search, `i` to show or hide Git-ignored files, `@` to insert the selected file as an `@path` mention, and `Esc` to close. When you open a file from `/files`, quitting the editor returns to the browser at the same position.
|
|
47
47
|
|
|
48
48
|
For an unsaved buffer, open a scratchpad:
|
|
49
49
|
|
|
@@ -85,21 +85,26 @@ $doc/editor.md
|
|
|
85
85
|
1. Type `$doc/editor.md` in the composer.
|
|
86
86
|
2. Pick the file from the matching results, or press `Enter` if the path is already complete.
|
|
87
87
|
3. Edit the file.
|
|
88
|
-
4.
|
|
89
|
-
5.
|
|
90
|
-
6.
|
|
88
|
+
4. In Vibe normal mode, use `:prompt <instruction>` to ask the agent to update the current in-memory buffer. In Modern mode, press `Ctrl+.` and type the instruction in the editor prompt line. For example, `write a HelloWorld class`.
|
|
89
|
+
5. The editor stays visible while the agent works; its status line shows a spinner. Review the generated buffer and save with `Ctrl+S` in Modern mode, `C-x C-s` in Emacs mode, or `:w` in Vibe mode. For an unsaved scratchpad in Vibe mode, use `:w filename`.
|
|
90
|
+
6. Quit with `Ctrl+Q`, `C-x C-c`, or `:q`.
|
|
91
|
+
7. Continue chatting with Kward.
|
|
91
92
|
|
|
92
93
|
## What the editor supports
|
|
93
94
|
|
|
94
95
|
The editor is intentionally compact, but it covers the basics you need for quick changes:
|
|
95
96
|
|
|
96
97
|
- 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
|
-
-
|
|
98
|
+
- Current-buffer word completion. After a partial word, Tab completes from words elsewhere in the active buffer; repeated Tab presses cycle nearby matches. Completion is case-sensitive and recognizes letters, numbers, and underscores. No project files or external sources are searched.
|
|
99
|
+
- Auto-indent, enabled by default. New lines inherit indentation. When word completion does not apply, 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
100
|
- Undo and redo, with up to 100 history entries per buffer.
|
|
99
101
|
- Incremental search forward and backward.
|
|
100
102
|
- Selection, copy, cut, and paste. Copy and cut also write to the terminal clipboard through OSC 52 when the terminal supports it.
|
|
101
103
|
- A line-number gutter and a status line that shows the current mode and prompts.
|
|
102
104
|
- Soft-wrap, enabled by default so long lines wrap within the editor width instead of scrolling sideways. Disable it with `editor.soft_wrap: false`.
|
|
105
|
+
- Vibe `:prompt <instruction>` and Modern `Ctrl+.` prompt lines send the complete current buffer and document metadata to a dedicated, transient editor agent. The agent can replace the in-memory buffer through an explicit editor tool; it does not save files automatically.
|
|
106
|
+
- Editor prompts and their tool activity are not added to the normal chat transcript or session history.
|
|
107
|
+
- The editor remains visible and locked for editing while the agent runs. Its status line displays progress and a spinner; `Ctrl+C` cancels the request.
|
|
103
108
|
|
|
104
109
|
## Choosing an editor mode
|
|
105
110
|
|
|
@@ -122,12 +127,16 @@ You can also configure it in `config.json`:
|
|
|
122
127
|
```json
|
|
123
128
|
{
|
|
124
129
|
"editor": {
|
|
125
|
-
"mode": "modern"
|
|
130
|
+
"mode": "modern",
|
|
131
|
+
"agent": {
|
|
132
|
+
"model": "gpt-5.5",
|
|
133
|
+
"reasoning_effort": "medium"
|
|
134
|
+
}
|
|
126
135
|
}
|
|
127
136
|
}
|
|
128
137
|
```
|
|
129
138
|
|
|
130
|
-
`mode` can be `modern`, `emacs`, or `vibe`. The old `default` value is still accepted as an alias for `modern`.
|
|
139
|
+
`mode` can be `modern`, `emacs`, or `vibe`. The optional `editor.agent.model` and `editor.agent.reasoning_effort` settings configure the dedicated Vibe editor agent. They use the active tab's provider. When either value is omitted, it falls back to the active tab's setting and then the client default. Editor-agent turns use a dedicated system prompt and are not persisted in the active tab transcript. The old `default` value is still accepted as an alias for `modern`.
|
|
131
140
|
|
|
132
141
|
To disable auto-indent or auto-close pairs:
|
|
133
142
|
|
|
@@ -156,6 +165,7 @@ Modern mode is the default and is the easiest place to start. It uses common ter
|
|
|
156
165
|
| --------------------- | ------------------------------------------------- |
|
|
157
166
|
| `Ctrl+S` | Save |
|
|
158
167
|
| `Ctrl+Q` | Quit; press again to discard unsaved changes |
|
|
168
|
+
| `Ctrl+.` | Open the editor-agent prompt line |
|
|
159
169
|
| `/` | Search forward |
|
|
160
170
|
| `?` | Search backward |
|
|
161
171
|
| `Ctrl+C` | Copy selection, or cancel search |
|
|
@@ -192,7 +202,7 @@ Modern mode is the default and is the easiest place to start. It uses common ter
|
|
|
192
202
|
| `Home` / `End` | Move to start / end of line |
|
|
193
203
|
| `PageUp` / `PageDown` | Scroll |
|
|
194
204
|
| `Enter` | Insert newline, or confirm search |
|
|
195
|
-
| `Tab` |
|
|
205
|
+
| `Tab` | Complete a buffer word, or smart-indent when no match exists |
|
|
196
206
|
| `Shift+Tab` | Move indentation back by one stop |
|
|
197
207
|
| `Backspace` | Delete before cursor |
|
|
198
208
|
| `Delete` | Delete character at cursor |
|
|
@@ -233,7 +243,7 @@ Emacs mode is for users who prefer classic Emacs-style non-modal editing. Save a
|
|
|
233
243
|
| `Home` / `End` | Move to start / end of line |
|
|
234
244
|
| `PageUp` / `PageDown` | Scroll |
|
|
235
245
|
| `Enter` | Insert newline, or confirm search |
|
|
236
|
-
| `Tab` |
|
|
246
|
+
| `Tab` | Complete a buffer word, or smart-indent when no match exists |
|
|
237
247
|
| `Shift+Tab` | Move indentation back by one stop |
|
|
238
248
|
| `Backspace` | Delete before cursor |
|
|
239
249
|
| `Delete` / `C-d` | Delete character at cursor |
|
|
@@ -370,7 +380,7 @@ Vibe insert mode also supports readline-style shortcuts for efficient editing wi
|
|
|
370
380
|
| ---------------- | ---------------------------------------- |
|
|
371
381
|
| type text | Insert characters |
|
|
372
382
|
| `Enter` | Insert newline |
|
|
373
|
-
| `Tab` |
|
|
383
|
+
| `Tab` | Complete a buffer word, or smart-indent when no match exists |
|
|
374
384
|
| `Shift+Tab` | Move indentation back by one stop |
|
|
375
385
|
| `Backspace` | Delete before cursor |
|
|
376
386
|
| `Delete` | Delete character at cursor |
|
data/doc/files.md
CHANGED
|
@@ -12,9 +12,9 @@ From an interactive Kward session, run:
|
|
|
12
12
|
/files
|
|
13
13
|
```
|
|
14
14
|
|
|
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.
|
|
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. Supported images (PNG, JPEG, GIF, and WebP) open as read-only inline previews when the terminal supports Kitty or iTerm2 image sequences.
|
|
16
16
|
|
|
17
|
-
When you quit the editor, Kward returns to the file browser at the same position so you can keep browsing nearby files.
|
|
17
|
+
When you quit the editor or close an image preview, Kward returns to the file browser at the same position so you can keep browsing nearby files.
|
|
18
18
|
|
|
19
19
|
## What appears in the browser
|
|
20
20
|
|
|
@@ -24,7 +24,7 @@ Inside a Git repository, `/files` uses Git's project view:
|
|
|
24
24
|
git ls-files --cached --others --exclude-standard
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
That means tracked files and normal untracked files appear, while ignored files stay out of the list.
|
|
27
|
+
That means tracked files and normal untracked files appear by default, while ignored files stay out of the list. Press `i` in the tree view to show or hide Git-ignored files; Kward remembers this choice for the workspace.
|
|
28
28
|
|
|
29
29
|
Outside Git, Kward scans the workspace directory and skips common noisy directories such as `.git`, `.yardoc`, `_yardoc`, `node_modules`, `rdoc`, `tmp`, and `vendor/bundle`.
|
|
30
30
|
|
|
@@ -39,7 +39,10 @@ Outside Git, Kward scans the workspace directory and skips common noisy director
|
|
|
39
39
|
| `Tab` | Start or stop search |
|
|
40
40
|
| `/` | Start search |
|
|
41
41
|
| `Backspace` | Delete the last search character |
|
|
42
|
+
| `i` | Show or hide Git-ignored files |
|
|
42
43
|
| `Esc` | Leave search; press again to close the browser |
|
|
44
|
+
| `Q` | Close an image preview |
|
|
45
|
+
| `+` / `-` | Zoom an image preview in / out |
|
|
43
46
|
| `@` | Insert the selected file as an `@path` mention |
|
|
44
47
|
|
|
45
48
|
Directories use `▸` and `▾` markers to show collapsed and expanded state. Files are shown under their containing directory with indentation. File-type icons are off by default; users with a compatible Nerd Font can enable them under Interface in `/settings`. See [Configuration](configuration.md#project-browser-icons).
|
|
@@ -88,13 +91,17 @@ See [Integrated editor](editor.md) for editor modes, save/quit keys, search, sel
|
|
|
88
91
|
|
|
89
92
|
## Remembered state
|
|
90
93
|
|
|
91
|
-
Kward remembers the expanded folders
|
|
94
|
+
Kward remembers the expanded folders, selected path, and Git-ignored file visibility for each workspace. The next time you open `/files` in the same project, it restores the browser close to where you left it.
|
|
92
95
|
|
|
93
96
|
Search itself is temporary. Closing search returns to the normal tree, and closing the browser leaves your chat session intact.
|
|
94
97
|
|
|
98
|
+
## Image previews
|
|
99
|
+
|
|
100
|
+
Image previews are read-only and replace the file-list overlay while leaving the prompt composer and tabs visible. Press `+` or `-` to make the image larger or smaller within the available overlay space. Press `Esc` or `Q` to return to `/files`. Kward probes Kitty-compatible terminals when it has a real interactive TTY, uses recognized terminal identity hints when probing is inconclusive, and retries transient detection failures. Terminals without reachable Kitty or iTerm2 inline-image support keep the selection in the browser and show a status message instead of opening binary data in the text editor. Kitty-compatible terminals use PNG data; JPEG, GIF, and WebP previews require an available local image converter.
|
|
101
|
+
|
|
95
102
|
## Notes and limitations
|
|
96
103
|
|
|
97
104
|
- `/files` is only available in the interactive prompt.
|
|
98
105
|
- It opens files inside the current workspace.
|
|
99
106
|
- It is a focused project browser, not a full file manager: it does not rename, move, copy, or delete files.
|
|
100
|
-
- Ignored Git files are
|
|
107
|
+
- Ignored Git files are hidden by default when Git can provide the file list; press `i` in the tree view to show them.
|
data/doc/permissions.md
CHANGED
|
@@ -176,6 +176,7 @@ The policy runs before Kward dispatches a model-requested tool. It does not cons
|
|
|
176
176
|
- a permitted shell command can access files, processes, credentials, and network services available to your user account;
|
|
177
177
|
- command-text rules are useful review controls, not a reliable way to enforce network destinations or all subprocess behavior;
|
|
178
178
|
- direct commands that you type yourself—`!command`, `/capture`, `/shell`, and `/pty`—are treated as your actions and are outside this first policy scope;
|
|
179
|
+
- commands run by the transient `?` shell assistant go through the normal permission and hook checks but deliberately use the user-owned `/shell` process, so the command sandbox cannot contain them;
|
|
179
180
|
- plugins, hooks, and MCP servers are trusted local extensions with their own process access.
|
|
180
181
|
|
|
181
182
|
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.
|
data/doc/releasing.md
CHANGED
|
@@ -1,74 +1,115 @@
|
|
|
1
1
|
# Releasing Kward
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Kward releases are prepared locally and published by GitHub Actions. The local command updates the version and changelog, runs every release check, creates the release commit and annotated tag, then pushes both atomically. The tag-triggered workflow publishes the gem to RubyGems.org and creates a GitHub Release with the same gem attached.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## One-time setup
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Kward publishes through [RubyGems trusted publishing](https://guides.rubygems.org/trusted-publishing/), so the repository does not need a long-lived RubyGems API key.
|
|
8
8
|
|
|
9
|
-
Before
|
|
9
|
+
Before the first automated release:
|
|
10
10
|
|
|
11
|
-
1.
|
|
12
|
-
2.
|
|
13
|
-
|
|
11
|
+
1. In the GitHub repository, create an Actions environment named `release`. Add required reviewers if releases should have a manual approval gate.
|
|
12
|
+
2. On the RubyGems.org page for the `kward` gem, add a trusted publisher with:
|
|
13
|
+
- Repository owner: `kaiwood`
|
|
14
|
+
- Repository name: `kward`
|
|
15
|
+
- Workflow filename: `release.yml`
|
|
16
|
+
- Environment: `release`
|
|
17
|
+
3. Confirm GitHub Actions can write repository contents. The release job requests only `contents: write` for the GitHub Release and `id-token: write` for RubyGems OIDC authentication.
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
bundle exec rake release:preflight
|
|
17
|
-
```
|
|
19
|
+
GitHub Packages is intentionally not used. RubyGems.org remains the canonical package registry; the built `.gem` is also attached to each GitHub Release.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
## Prepare a release
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Keep notable changes under the appropriate `Added`, `Changed`, `Fixed`, or `Removed` heading in the `[Unreleased]` section of `CHANGELOG.md`. Do not add the version heading by hand.
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
ruby -Itest test/test_cli.rb
|
|
25
|
-
```
|
|
25
|
+
Before releasing, make sure `main` is clean, pushed, and synchronized with `origin/main`. Then run:
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
```bash
|
|
28
|
+
script/release 0.82.0
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The version can also come from standard input:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
printf '0.82.0\n' | script/release
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The command fails closed unless:
|
|
38
|
+
|
|
39
|
+
- The version is a valid RubyGems version newer than `Kward::VERSION`.
|
|
40
|
+
- The working tree is clean and checked out on `main`.
|
|
41
|
+
- Local `main` exactly matches `origin/main`.
|
|
42
|
+
- The tag does not exist locally or on GitHub.
|
|
43
|
+
- RubyGems.org does not already contain the version.
|
|
44
|
+
- `[Unreleased]` contains at least one changelog entry.
|
|
45
|
+
|
|
46
|
+
If validation succeeds, it:
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
48
|
+
1. Updates `Kward::VERSION` in `lib/kward/version.rb`.
|
|
49
|
+
2. Refreshes `Gemfile.lock` with `bundle lock --local`.
|
|
50
|
+
3. Moves the unreleased changelog entries under a dated version heading.
|
|
51
|
+
4. Runs `bundle exec rake release:preflight`.
|
|
52
|
+
5. Commits the three release files as `Release v0.82.0`.
|
|
53
|
+
6. Creates an annotated `v0.82.0` tag.
|
|
54
|
+
7. Atomically pushes `main` and the tag to `origin`.
|
|
32
55
|
|
|
33
|
-
|
|
56
|
+
If preparation fails before the commit, the command restores the version, lockfile, and changelog. If tagging or pushing fails after the commit, it leaves the release commit in place and prints the failed command; inspect the repository before retrying rather than creating another release commit.
|
|
34
57
|
|
|
35
|
-
|
|
58
|
+
## What the release workflow does
|
|
36
59
|
|
|
37
|
-
|
|
38
|
-
bundle exec rake docs:build
|
|
39
|
-
bundle exec rake docs:check
|
|
40
|
-
```
|
|
60
|
+
A pushed `v*` tag starts `.github/workflows/release.yml`. The workflow:
|
|
41
61
|
|
|
42
|
-
|
|
62
|
+
1. Checks that the tag, gem version, and changelog heading agree.
|
|
63
|
+
2. Installs and enables Bubblewrap, then runs the full test suite and generated-documentation checks against Ruby 3.4 using the same Linux sandbox setup as normal CI.
|
|
64
|
+
3. Builds the gem and verifies its packaged files.
|
|
65
|
+
4. Publishes through RubyGems trusted publishing.
|
|
66
|
+
5. Downloads the canonical published gem from RubyGems.org, waiting for propagation when necessary, and verifies its checksum against the RubyGems API.
|
|
67
|
+
6. Creates `Kward VERSION` as a GitHub Release using that version's changelog section and attaches the verified RubyGems artifact.
|
|
43
68
|
|
|
44
|
-
|
|
69
|
+
The publishing job uses the protected `release` environment. If RubyGems.org already has the version after a partially completed workflow, a rerun downloads and verifies the canonical published gem before continuing. This also accommodates trusted-publishing attestations that can change the published gem bytes. For an existing GitHub Release, the workflow downloads and compares the gem, uploads it when missing, and publishes an unfinished draft. This makes normal workflow reruns safe without silently replacing mismatched artifacts.
|
|
45
70
|
|
|
46
|
-
|
|
71
|
+
If the workflow itself needs a fix after a tag has already been pushed, commit and push the fix to `main`, then recover the existing tag with the updated workflow:
|
|
47
72
|
|
|
48
|
-
|
|
73
|
+
```bash
|
|
74
|
+
gh workflow run Release --ref main -f tag=v0.82.0
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Manual recovery still checks out and verifies the tagged source before publishing. The `release` environment permits automatic version-tag runs and manual recovery runs from `main` only.
|
|
49
78
|
|
|
50
|
-
|
|
79
|
+
Follow the run from the repository's **Actions → Release** page. Installation can be checked after publication with:
|
|
51
80
|
|
|
52
81
|
```bash
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
git push && git push --tags
|
|
82
|
+
gem install kward --version 0.82.0
|
|
83
|
+
kward --version
|
|
56
84
|
```
|
|
57
85
|
|
|
58
|
-
|
|
86
|
+
## Run checks without releasing
|
|
87
|
+
|
|
88
|
+
After updating to an unreleased version, run the complete preflight directly with:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
bundle exec rake release:preflight
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This verifies release metadata, runs tests, builds and checks the generated documentation, builds `pkg/kward-VERSION.gem`, rejects development-only packaged files, and prints the final gem contents.
|
|
95
|
+
|
|
96
|
+
Individual checks remain available:
|
|
59
97
|
|
|
60
98
|
```bash
|
|
61
|
-
|
|
99
|
+
bundle exec rake test
|
|
100
|
+
bundle exec rake docs:check
|
|
101
|
+
bundle exec rake release:verify
|
|
102
|
+
bundle exec rake build
|
|
62
103
|
```
|
|
63
104
|
|
|
64
|
-
|
|
105
|
+
Use `bundle exec rake docs:serve` to preview documentation locally.
|
|
65
106
|
|
|
66
107
|
## If you need to yank a release
|
|
67
108
|
|
|
68
|
-
If a published gem has a serious problem,
|
|
109
|
+
If a published gem has a serious problem, yank it within 24 hours of pushing:
|
|
69
110
|
|
|
70
111
|
```bash
|
|
71
112
|
gem yank kward --version VERSION
|
|
72
113
|
```
|
|
73
114
|
|
|
74
|
-
Yanking removes the gem from the default install index but does not delete the version
|
|
115
|
+
Yanking removes the gem from the default install index but does not delete the version. Fix the issue, choose a new version, and run the normal release command again. Never move or reuse a published version tag.
|
data/doc/rpc.md
CHANGED
|
@@ -80,11 +80,11 @@ Read `capabilities` at runtime instead of assuming every feature is available. I
|
|
|
80
80
|
- `mcp`: local stdio MCP server support through the shared `mcpServers` config. RPC exposes MCP tools to turns and advertises discovery with `methods: ["tools/list", "mcp/status"]`, `toolMetadata: true`, and `serverStatus: true`. It does not support MCP resources, prompts, sampling, or Streamable HTTP.
|
|
81
81
|
- `startupResources`: supported startup resource listing for context, skills, prompts, and plugins.
|
|
82
82
|
- `extensionUi`: question bridge support via `ui/question` and `ui/answerQuestion`, plus plugin footer updates via `ui/footer`; other UI primitives are explicitly unsupported.
|
|
83
|
-
- `composer`: composer-only UI features. Interactive session diff totals are explicitly unsupported over RPC (`composer.sessionDiff.supported: false`) because RPC clients already receive per-tool diff results and no live composer status payload is exposed. Clipboard copy is also unsupported over RPC (`composer.copy.supported: false`) because UI clients own clipboard access.
|
|
83
|
+
- `composer`: composer-only UI features. Interactive session diff totals are explicitly unsupported over RPC (`composer.sessionDiff.supported: false`) because RPC clients already receive per-tool diff results and no live composer status payload is exposed. Clipboard copy is also unsupported over RPC (`composer.copy.supported: false`) because UI clients own clipboard access. Vibe editor prompts are unsupported over RPC (`composer.editorPrompt.supported: false`) because RPC has no live integrated editor buffer.
|
|
84
84
|
- `security`: trusted-local behavior and optional per-turn tool approval. By default, RPC turns have no workspace mutation guard or tool approval, so shell commands and file changes can run. Clients can inspect file-tool guardrails through `capabilities.events.tools.workspaceGuardrails` and `runtime/state.workspaceGuardrailsEnabled`. `security.sandbox` reports the command sandbox mode, enforcement backend, and filesystem and network capabilities; session pinning and one-time elevation are unsupported. See [Command sandboxing](sandboxing.md) for the boundary and its limits.
|
|
85
85
|
- `export`: supported transcript export formats. Currently `markdown` and `html`; default is `markdown`.
|
|
86
86
|
- `starterPack`: explicitly unsupported (`supported: false`, reason `cliOnlyInstallCommand`). Use `kward init` from the shell.
|
|
87
|
-
- `shell`: explicitly unsupported (`supported: false`, reason `interactiveTuiOnly`) because `/shell`, `!command`, `/capture`, and PTY handoff require the local TUI. Model-requested `run_shell_command` tools remain bounded, captured, and noninteractive over RPC.
|
|
87
|
+
- `shell`: explicitly unsupported (`supported: false`, reason `interactiveTuiOnly`) because `/shell`, its transient `?` shell assistant, `!command`, `/capture`, and PTY handoff require the local TUI. Model-requested `run_shell_command` tools remain bounded, captured, and noninteractive over RPC.
|
|
88
88
|
- `logging`: local redacted telemetry, its directory and enabled categories, `logging/stats` and `logging/tokenCsv`, bucketed `usageCsv` support, JSONL storage, and 10 MB rotation with manual retention. Logs contain redacted metadata only. Configuration uses the `logging` key and `KWARD_LOGGING` environment prefix.
|
|
89
89
|
|
|
90
90
|
### `shutdown`
|
data/doc/sandboxing.md
CHANGED
|
@@ -106,12 +106,16 @@ this interface.
|
|
|
106
106
|
## Boundaries and limits
|
|
107
107
|
|
|
108
108
|
The current implementation protects **model-requested command workers only**.
|
|
109
|
+
The transient `?` shell assistant is intentionally not one of those workers: its
|
|
110
|
+
`run_shell_command` calls use the active user-owned `/shell` process so shell
|
|
111
|
+
state can persist.
|
|
112
|
+
|
|
109
113
|
It does not sandbox:
|
|
110
114
|
|
|
111
115
|
- the Kward Ruby host process;
|
|
112
116
|
- model-provider, search-provider, or RPC traffic;
|
|
113
117
|
- trusted Ruby plugins;
|
|
114
|
-
- MCP servers, lifecycle hooks, `/shell`, `!command`, `/capture`, or `/pty`.
|
|
118
|
+
- MCP servers, lifecycle hooks, `/shell`, `?` shell-agent commands, `!command`, `/capture`, or `/pty`.
|
|
115
119
|
|
|
116
120
|
Sandboxed command workers receive a minimal environment: Kward preserves only
|
|
117
121
|
basic terminal, locale, and path variables, then supplies a private `HOME` and
|