kward 0.80.1 → 0.82.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 +62 -0
- data/Gemfile.lock +2 -2
- data/README.md +2 -2
- data/Rakefile +44 -4
- data/doc/composer.md +6 -9
- data/doc/configuration.md +13 -3
- data/doc/files.md +8 -2
- data/doc/permissions.md +1 -1
- data/doc/releasing.md +71 -38
- data/doc/rpc.md +2 -1
- data/doc/sandboxing.md +4 -4
- data/doc/security.md +6 -9
- data/doc/shell.md +161 -196
- data/doc/skills.md +17 -5
- data/doc/tabs.md +1 -1
- data/doc/usage.md +6 -5
- data/kward.gemspec +1 -1
- data/lib/kward/adaptive_pty_output_sink.rb +183 -0
- data/lib/kward/ansi.rb +9 -1
- data/lib/kward/cli/commands.rb +7 -0
- data/lib/kward/cli/git.rb +5 -1
- data/lib/kward/cli/interactive_turn.rb +1 -1
- data/lib/kward/cli/plugins.rb +1 -1
- data/lib/kward/cli/project_skills.rb +99 -0
- data/lib/kward/cli/project_skills_commands.rb +87 -0
- data/lib/kward/cli/prompt_interface.rb +18 -4
- data/lib/kward/cli/rendering.rb +41 -3
- data/lib/kward/cli/runtime_helpers.rb +222 -21
- data/lib/kward/cli/sessions.rb +6 -4
- data/lib/kward/cli/settings.rb +5 -13
- data/lib/kward/cli/slash_commands.rb +6 -0
- data/lib/kward/cli/tabs.rb +62 -5
- data/lib/kward/cli.rb +21 -1
- data/lib/kward/config_files.rb +9 -4
- data/lib/kward/conversation.rb +8 -5
- data/lib/kward/ekwsh.rb +37 -16
- data/lib/kward/image_attachments.rb +98 -15
- data/lib/kward/interactive_pty_runner.rb +102 -30
- data/lib/kward/prompt_interface/composer_controller.rb +15 -3
- data/lib/kward/prompt_interface/composer_renderer.rb +27 -0
- data/lib/kward/prompt_interface/editor/controller.rb +10 -6
- data/lib/kward/prompt_interface/editor/modes/emacs.rb +2 -2
- data/lib/kward/prompt_interface/editor/modes/vibe.rb +2 -2
- data/lib/kward/prompt_interface/git_prompt.rb +1 -1
- data/lib/kward/prompt_interface/key_handler.rb +100 -43
- data/lib/kward/prompt_interface/overlay_renderer.rb +13 -0
- data/lib/kward/prompt_interface/project_browser.rb +162 -3
- 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/screen.rb +40 -15
- 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 +167 -44
- data/lib/kward/prompts/commands.rb +2 -0
- data/lib/kward/prompts.rb +6 -6
- data/lib/kward/pty_output_sink.rb +45 -0
- data/lib/kward/pty_transcript_normalizer.rb +93 -0
- data/lib/kward/rpc/server.rb +1 -0
- data/lib/kward/session_catalog.rb +87 -0
- data/lib/kward/session_store.rb +97 -7
- data/lib/kward/skills/registry.rb +52 -2
- data/lib/kward/skills/trust_coordinator.rb +45 -0
- data/lib/kward/skills/trust_store.rb +107 -0
- data/lib/kward/terminal_image_support.rb +116 -0
- data/lib/kward/terminal_sequences.rb +43 -0
- data/lib/kward/version.rb +1 -1
- metadata +11 -4
- data/.github/workflows/ci.yml +0 -48
- data/.github/workflows/pages.yml +0 -48
data/doc/shell.md
CHANGED
|
@@ -1,246 +1,263 @@
|
|
|
1
1
|
# Embedded shell
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Kward lets you run your own shell commands without leaving the interactive TUI. Choose the workflow that matches what you are doing:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **For one quick command, use `!command`.** It runs from the active workspace and returns you to the normal composer when it finishes.
|
|
6
|
+
- **For a longer stretch of shell work, use `/shell`.** It keeps its directory, environment, aliases, and history between commands.
|
|
7
|
+
- **For bounded output in the transcript view, use `/capture <command>`.** Inside `/shell`, use `capture <command>` for the same kind of readable output while keeping the shell's current state.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Ordinary `!command` input and external commands inside `/shell` receive an interactive PTY. Pagers, Vim, SSH, REPLs, password prompts, and other interactive tools therefore work without a `pty` prefix.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
- running focused tests,
|
|
11
|
-
- inspecting files with command-line tools,
|
|
12
|
-
- using project aliases,
|
|
13
|
-
- keeping command output visible beside the current Kward session.
|
|
11
|
+
## Run a one-off command
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
Prefix a command with `!` in the normal composer:
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
```text
|
|
16
|
+
!git status --short
|
|
17
|
+
!bundle exec ruby -Itest test/test_cli.rb
|
|
18
|
+
!less README.md
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The command runs from the active workspace root and begins in an inline PTY region above a frozen composer. Line-oriented output, single-line carriage-return progress, and synchronized-output update brackets scroll the transcript area naturally while keyboard input belongs to the child process. If the child emits alternate-screen, clear-screen, absolute cursor, or unknown terminal controls, Kward conservatively hides the composer and switches permanently to full-terminal passthrough for the rest of that command. Pagers and full-screen applications therefore retain the complete terminal without relying on a command-name allowlist.
|
|
22
|
+
|
|
23
|
+
When an inline command exits without reading input, safe output is mirrored into the transient transcript view so a repaint cannot hide it. Carriage-return and horizontal-cursor progress redraws are reduced to their final visible lines, while an unterminated synchronized-output update is closed before Kward redraws. If the child reads input, Kward retains only output captured before the first forwarded input byte; this prevents echoed passwords, OTPs, or other input from entering tab state. Shell output is never added to the AI conversation or sent to the model.
|
|
24
|
+
|
|
25
|
+
Shell output can leave transient text in the transcript area. **After the command finishes, press Ctrl+L to redraw the durable conversation and clear that transient `!command` output.** While an interactive command is still running, the composer remains frozen and keyboard input—including Ctrl+L and Kward's tab shortcuts—belongs to the child process.
|
|
26
|
+
|
|
27
|
+
Configured `ekwsh.yml` aliases also work after `!`:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
aliases:
|
|
31
|
+
glog: "git log --decorate --stat --graph"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
!glog
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
An alias that resolves to `kward edit <filename>` opens Kward's integrated editor in the current session instead of starting a nested Kward process:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
aliases:
|
|
42
|
+
vibe: "kward edit"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
!vibe filename.txt
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Press Tab after `!` to complete configured aliases, executables from `PATH`, and paths from the active workspace:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
!git sta<Tab>
|
|
53
|
+
!cat lib/kwa<Tab>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The completion overlay lists matching commands and paths. Press Tab repeatedly to cycle through the listed candidates.
|
|
57
|
+
|
|
58
|
+
## Work in shell mode
|
|
18
59
|
|
|
19
|
-
|
|
60
|
+
Enter the embedded shell when you expect to run several commands:
|
|
20
61
|
|
|
21
62
|
```text
|
|
22
63
|
/shell
|
|
23
64
|
```
|
|
24
65
|
|
|
25
|
-
The
|
|
66
|
+
The prompt changes to show the shell's current directory:
|
|
26
67
|
|
|
27
68
|
```text
|
|
28
69
|
Shell ~/code/project $
|
|
29
70
|
```
|
|
30
71
|
|
|
31
|
-
|
|
72
|
+
The directory and exported environment persist between commands:
|
|
32
73
|
|
|
33
74
|
```sh
|
|
34
|
-
|
|
35
|
-
bundle exec ruby -Itest test/test_ekwsh.rb
|
|
36
|
-
cd lib/kward
|
|
75
|
+
cd test
|
|
37
76
|
pwd
|
|
77
|
+
export RAILS_ENV=test
|
|
78
|
+
bundle exec ruby -Itest test_example.rb
|
|
79
|
+
unset RAILS_ENV
|
|
38
80
|
```
|
|
39
81
|
|
|
40
|
-
|
|
82
|
+
Simple assignment-only commands persist too:
|
|
41
83
|
|
|
42
84
|
```sh
|
|
43
|
-
|
|
85
|
+
FOO=bar
|
|
86
|
+
printf '%s\n' "$FOO"
|
|
44
87
|
```
|
|
45
88
|
|
|
46
|
-
or
|
|
89
|
+
Leave shell mode with `exit`, `logout`, or Ctrl+D on an empty prompt.
|
|
47
90
|
|
|
48
|
-
|
|
91
|
+
`cd` changes only the embedded shell's directory. It does not change Kward's workspace root or the directory used by the model's other tools.
|
|
49
92
|
|
|
50
|
-
|
|
93
|
+
## Interactive and captured commands
|
|
51
94
|
|
|
52
|
-
|
|
95
|
+
External commands inside `/shell` are interactive by default:
|
|
53
96
|
|
|
54
97
|
```sh
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
unset FOO
|
|
98
|
+
git log
|
|
99
|
+
vim README.md
|
|
100
|
+
ruby
|
|
101
|
+
ssh example.com
|
|
60
102
|
```
|
|
61
103
|
|
|
62
|
-
|
|
104
|
+
Kward gives each command the terminal, forwards keyboard input, and restores the shell prompt when the command exits. It prints the submitted command but no PTY start message or exit-status summary. The line-oriented Git commands `git fetch`, `git ls-remote`, `git push`, `git remote`, and `git status` keep the shell prompt visible as a frozen display. Safe, line-oriented output from commands that did not read keyboard input is kept in the transient transcript view; full-screen and genuinely interactive output stays terminal-owned.
|
|
63
105
|
|
|
64
|
-
|
|
106
|
+
Use `capture` inside `/shell` when you want ordinary, readable output in Kward's transcript area instead of direct terminal control:
|
|
65
107
|
|
|
66
|
-
|
|
108
|
+
```sh
|
|
109
|
+
capture git status --short
|
|
110
|
+
capture bundle exec ruby -Itest test/test_ekwsh.rb
|
|
111
|
+
```
|
|
67
112
|
|
|
68
|
-
|
|
113
|
+
An `ekwsh` `capture` command:
|
|
69
114
|
|
|
70
|
-
|
|
115
|
+
- does not receive keyboard input,
|
|
116
|
+
- uses the timeout and output-size limit from `ekwsh.yml`,
|
|
117
|
+
- preserves safe color and styling,
|
|
118
|
+
- strips controls that could corrupt Kward's TUI,
|
|
119
|
+
- can be cancelled with Ctrl+C.
|
|
71
120
|
|
|
72
|
-
|
|
73
|
-
| --- | --- |
|
|
74
|
-
| `cd [dir]` | Change the embedded shell directory. Supports `cd`, `cd -`, and normal relative paths. |
|
|
75
|
-
| `pwd` | Print the embedded shell directory. |
|
|
76
|
-
| `export KEY[=value]` | Set or mark an environment variable for later commands. `export` and `export -p` list variables. |
|
|
77
|
-
| `unset KEY` | Remove an environment variable from later commands. |
|
|
78
|
-
| `alias [name]` | List configured aliases, show specific configured aliases, or set `alias name=value`. |
|
|
79
|
-
| `unalias name` / `unalias -a` | Remove configured aliases. |
|
|
80
|
-
| `clear` | Clear Kward's visible transcript. |
|
|
81
|
-
| `exit` / `logout` | Leave shell mode. |
|
|
121
|
+
From the normal composer, `/capture` provides a bounded, noninteractive one-shot command using the active workspace root:
|
|
82
122
|
|
|
83
|
-
|
|
123
|
+
```text
|
|
124
|
+
/capture git status --short
|
|
125
|
+
```
|
|
84
126
|
|
|
85
|
-
|
|
127
|
+
It captures stdout and stderr in the transcript view, but does not inherit `/shell` state or its configured runtime limits.
|
|
86
128
|
|
|
87
|
-
|
|
129
|
+
Interactive commands are not automatically timed out or output-limited. Ctrl+C is forwarded to the child.
|
|
88
130
|
|
|
89
|
-
|
|
131
|
+
The older `/pty <command>` slash command and `pty <command>` shell built-in remain available for compatibility, but ordinary interactive commands no longer need them.
|
|
90
132
|
|
|
91
|
-
|
|
133
|
+
## Shell state, history, and tabs
|
|
92
134
|
|
|
93
|
-
|
|
135
|
+
Each Kward tab owns its `/shell` state. Switching away and back restores that tab's:
|
|
136
|
+
|
|
137
|
+
- current shell directory,
|
|
94
138
|
- exported environment,
|
|
95
|
-
-
|
|
96
|
-
-
|
|
139
|
+
- runtime aliases,
|
|
140
|
+
- shell prompt and transcript view.
|
|
97
141
|
|
|
98
|
-
|
|
142
|
+
Shell commands use a separate, workspace-scoped history rather than the normal chat-prompt history. Configure its size with `history_limit` in `ekwsh.yml`.
|
|
99
143
|
|
|
100
|
-
|
|
144
|
+
Kward's tab shortcuts work at the shell prompt and while a captured command is running. During an interactive command, the child owns every key; exit or interrupt it before switching Kward tabs.
|
|
101
145
|
|
|
102
|
-
|
|
146
|
+
## Completion
|
|
103
147
|
|
|
104
|
-
|
|
148
|
+
Press Tab in `/shell` to complete:
|
|
105
149
|
|
|
106
|
-
- built-in
|
|
107
|
-
- configured aliases,
|
|
108
|
-
-
|
|
109
|
-
-
|
|
150
|
+
- built-in names,
|
|
151
|
+
- configured and runtime aliases,
|
|
152
|
+
- executables from `PATH`,
|
|
153
|
+
- files and directories from the shell's current directory.
|
|
110
154
|
|
|
111
155
|
Examples:
|
|
112
156
|
|
|
113
157
|
```sh
|
|
114
158
|
pw<Tab> # pwd
|
|
115
|
-
ll<Tab> # configured alias
|
|
116
|
-
cat lib/kw<Tab> # path
|
|
117
|
-
cd doc<Tab> #
|
|
159
|
+
ll<Tab> # configured alias
|
|
160
|
+
cat lib/kw<Tab> # path
|
|
161
|
+
cd doc<Tab> # directories only for cd
|
|
118
162
|
```
|
|
119
163
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
Paths with spaces are shell-escaped:
|
|
164
|
+
Paths with spaces are escaped:
|
|
123
165
|
|
|
124
166
|
```sh
|
|
125
167
|
cat my<Tab>
|
|
126
168
|
# => cat my\ file.txt
|
|
127
169
|
```
|
|
128
170
|
|
|
129
|
-
Quoted
|
|
171
|
+
Quoted paths stay quoted:
|
|
130
172
|
|
|
131
173
|
```sh
|
|
132
174
|
cat "my<Tab>
|
|
133
175
|
# => cat "my file.txt
|
|
134
176
|
```
|
|
135
177
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
## Colors and ANSI output
|
|
139
|
-
|
|
140
|
-
`ekwsh` preserves safe ANSI SGR color/style sequences in command output, such as:
|
|
141
|
-
|
|
142
|
-
- colors,
|
|
143
|
-
- bold,
|
|
144
|
-
- dim,
|
|
145
|
-
- italic,
|
|
146
|
-
- underline,
|
|
147
|
-
- 256-color and truecolor SGR sequences.
|
|
148
|
-
|
|
149
|
-
It strips terminal-control sequences that could corrupt Kward's TUI, such as cursor movement, clear-screen controls, OSC title changes, and alternate-screen controls.
|
|
150
|
-
|
|
151
|
-
When rbenv is available, `ekwsh` also prepends the rbenv shims and bin directories to PATH and sets `RBENV_ROOT` when it was missing. This lets commands such as `ruby`, `bundle`, and `./exe/kward` use the same Ruby selected by rbenv without requiring `rbenv init` support in `ekwsh`.
|
|
178
|
+
When several candidates match, repeated Tab presses cycle through them and wrap back to the first. Candidate lists stay in the composer instead of being printed in the transcript. The executable cache refreshes when `PATH` changes through assignment, `export`, or `unset`.
|
|
152
179
|
|
|
153
|
-
|
|
180
|
+
## Built-ins
|
|
154
181
|
|
|
155
|
-
|
|
156
|
-
CLICOLOR=1
|
|
157
|
-
COLORTERM=truecolor
|
|
158
|
-
TERM=xterm-256color # only when TERM is missing or dumb
|
|
159
|
-
```
|
|
182
|
+
`ekwsh` handles a small set of commands itself so their state can persist:
|
|
160
183
|
|
|
161
|
-
|
|
184
|
+
| Built-in | What it does |
|
|
185
|
+
| --- | --- |
|
|
186
|
+
| `cd [dir]` | Change the shell directory. Supports `cd`, `cd -`, and relative paths. |
|
|
187
|
+
| `pwd` | Print the shell directory. |
|
|
188
|
+
| `export KEY[=value]` | Set an environment variable. `export` and `export -p` list variables. |
|
|
189
|
+
| `unset KEY` | Remove an environment variable. |
|
|
190
|
+
| `alias [name]` | List, inspect, or create aliases. |
|
|
191
|
+
| `unalias name` / `unalias -a` | Remove aliases. |
|
|
192
|
+
| `capture <command>` | Run with bounded, sanitized transcript output. |
|
|
193
|
+
| `pty <command>` | Compatibility spelling for interactive terminal handoff. |
|
|
194
|
+
| `clear` | Clear the visible transcript. |
|
|
195
|
+
| `exit` / `logout` | Leave shell mode. |
|
|
162
196
|
|
|
163
|
-
|
|
164
|
-
git diff --color=always
|
|
165
|
-
grep --color=always TODO lib/**/*.rb
|
|
166
|
-
```
|
|
197
|
+
Built-ins take precedence over aliases and executables.
|
|
167
198
|
|
|
168
|
-
##
|
|
199
|
+
## Configure ekwsh
|
|
169
200
|
|
|
170
|
-
|
|
201
|
+
Global shell configuration lives at:
|
|
171
202
|
|
|
172
203
|
```text
|
|
173
204
|
~/.kward/ekwsh.yml
|
|
174
205
|
```
|
|
175
206
|
|
|
176
|
-
|
|
207
|
+
When `KWARD_CONFIG_PATH` selects another main config file, Kward reads `ekwsh.yml` from the same directory.
|
|
177
208
|
|
|
178
|
-
|
|
209
|
+
A practical configuration might look like this:
|
|
179
210
|
|
|
180
211
|
```yaml
|
|
181
212
|
shell: /bin/sh
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
213
|
+
timeout_seconds: 300
|
|
214
|
+
max_output_bytes: 1048576
|
|
215
|
+
history_limit: 1000
|
|
185
216
|
|
|
186
217
|
env:
|
|
187
218
|
FORCE_COLOR: "1"
|
|
188
|
-
|
|
219
|
+
BUNDLE_WITHOUT: "production"
|
|
189
220
|
RAILS_ENV: "test"
|
|
190
221
|
|
|
191
222
|
aliases:
|
|
192
223
|
ll: "ls -la"
|
|
193
224
|
gs: "git status --short"
|
|
194
225
|
gd: "git diff --color=always"
|
|
226
|
+
glog: "git log --decorate --stat --graph"
|
|
195
227
|
be: "bundle exec"
|
|
196
228
|
t: "bundle exec ruby -Itest"
|
|
197
229
|
```
|
|
198
230
|
|
|
199
|
-
###
|
|
200
|
-
|
|
201
|
-
`ekwsh` accepts these top-level runtime settings:
|
|
231
|
+
### Settings
|
|
202
232
|
|
|
203
233
|
| Setting | Default | What it does |
|
|
204
234
|
| --- | --- | --- |
|
|
205
|
-
| `shell` | `/bin/sh` |
|
|
206
|
-
| `timeout_seconds` | `300` | Maximum runtime for one command. |
|
|
207
|
-
| `max_output_bytes` | `1048576` | Maximum
|
|
208
|
-
| `history_limit` | `1000` | Maximum
|
|
235
|
+
| `shell` | `/bin/sh` | POSIX-compatible shell used with `-c`. It must be an absolute executable path. |
|
|
236
|
+
| `timeout_seconds` | `300` | Maximum runtime for one captured command. |
|
|
237
|
+
| `max_output_bytes` | `1048576` | Maximum output retained for one captured command. |
|
|
238
|
+
| `history_limit` | `1000` | Maximum shell-history entries per workspace. |
|
|
209
239
|
|
|
210
|
-
|
|
240
|
+
Invalid or relative `shell` paths fall back to `/bin/sh`. These timeout and output limits apply only to `capture` inside `/shell`, not interactive commands or the separate `/capture` slash command.
|
|
211
241
|
|
|
212
|
-
### Environment
|
|
242
|
+
### Environment
|
|
213
243
|
|
|
214
|
-
`env` values are applied when shell
|
|
244
|
+
Configured `env` values are applied when `/shell` starts. Keys must be valid environment-variable names; nil values and invalid keys are ignored, and other values are converted to strings.
|
|
215
245
|
|
|
216
|
-
|
|
246
|
+
Kward also supplies conservative terminal defaults:
|
|
217
247
|
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
Invalid keys are ignored. Values are converted to strings. Nil values are ignored.
|
|
223
|
-
|
|
224
|
-
Configured env is useful for local preferences such as:
|
|
225
|
-
|
|
226
|
-
```yaml
|
|
227
|
-
env:
|
|
228
|
-
FORCE_COLOR: "1"
|
|
229
|
-
BUNDLE_WITHOUT: "production"
|
|
230
|
-
RAILS_ENV: "test"
|
|
248
|
+
```sh
|
|
249
|
+
CLICOLOR=1
|
|
250
|
+
COLORTERM=truecolor
|
|
251
|
+
TERM=xterm-256color # only when TERM is missing or dumb
|
|
231
252
|
```
|
|
232
253
|
|
|
233
|
-
|
|
254
|
+
It does not force color. Set `FORCE_COLOR`, `CLICOLOR_FORCE`, or a command-specific option such as `--color=always` when needed.
|
|
234
255
|
|
|
235
|
-
|
|
236
|
-
export FORCE_COLOR=1
|
|
237
|
-
```
|
|
256
|
+
When rbenv is available, Kward adds its shims and bin directories to `PATH` and supplies `RBENV_ROOT` if it was missing. This lets `ruby`, `bundle`, and `./exe/kward` use the selected Ruby without sourcing shell startup files.
|
|
238
257
|
|
|
239
258
|
### Aliases
|
|
240
259
|
|
|
241
|
-
Aliases
|
|
242
|
-
|
|
243
|
-
With this config:
|
|
260
|
+
Aliases replace the first command word once and append any remaining arguments:
|
|
244
261
|
|
|
245
262
|
```yaml
|
|
246
263
|
aliases:
|
|
@@ -248,8 +265,6 @@ aliases:
|
|
|
248
265
|
t: "bundle exec ruby -Itest"
|
|
249
266
|
```
|
|
250
267
|
|
|
251
|
-
these commands run as:
|
|
252
|
-
|
|
253
268
|
```sh
|
|
254
269
|
ll lib
|
|
255
270
|
# runs: ls -la lib
|
|
@@ -258,75 +273,25 @@ t test/test_ekwsh.rb
|
|
|
258
273
|
# runs: bundle exec ruby -Itest test/test_ekwsh.rb
|
|
259
274
|
```
|
|
260
275
|
|
|
261
|
-
Aliases are
|
|
262
|
-
|
|
263
|
-
- only the first word is expanded,
|
|
264
|
-
- aliases do not recursively expand,
|
|
265
|
-
- built-ins win over alias names,
|
|
266
|
-
- aliases are not shell functions,
|
|
267
|
-
- aliases are global for now.
|
|
268
|
-
|
|
269
|
-
List configured aliases inside `ekwsh`:
|
|
270
|
-
|
|
271
|
-
```sh
|
|
272
|
-
alias
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
Show specific aliases:
|
|
276
|
-
|
|
277
|
-
```sh
|
|
278
|
-
alias ll gs
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
Aliases also appear in command-name Tab completion.
|
|
282
|
-
|
|
283
|
-
## Interactive PTY passthrough
|
|
284
|
-
|
|
285
|
-
Use `/pty <command>` for commands that need to own the terminal temporarily, such as pagers:
|
|
286
|
-
|
|
287
|
-
```text
|
|
288
|
-
/pty git log
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Inside `/shell`, use the `pty` built-in so the command inherits the embedded shell's current directory and environment:
|
|
292
|
-
|
|
293
|
-
```sh
|
|
294
|
-
pty git log
|
|
295
|
-
pty vim README.md
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
Kward runs the command in a PTY, forwards your keyboard input to the process, and streams the process output directly to the terminal. This lets tools such as `less` receive keys like Space, `/`, `n`, and `q` normally. When the command exits, Kward restores its prompt and records only a short session summary in the transcript instead of raw full-screen terminal control output.
|
|
299
|
-
|
|
300
|
-
`/pty` and shell `pty` are explicit on purpose. Normal `/shell` commands remain captured and transcript-friendly; `pty` is for commands where the child process should temporarily own the terminal.
|
|
276
|
+
Configured aliases work inside `/shell` and after `!`. Aliases created with the `alias` built-in belong only to the current `/shell` session and are not shared with one-shot `!command` input.
|
|
301
277
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
Kward has two ways to run local commands yourself:
|
|
305
|
-
|
|
306
|
-
```text
|
|
307
|
-
!git status --short
|
|
308
|
-
```
|
|
278
|
+
For compatibility with older configs, Kward removes a leading `pty` or `capture` mode marker when a configured alias is invoked through `!`, because `!command` is always interactive.
|
|
309
279
|
|
|
310
|
-
|
|
280
|
+
Aliases are intentionally simple: they do not expand recursively and are not shell functions. Use `alias` to list them, `alias name=value` to create a runtime alias, and `unalias` to remove one.
|
|
311
281
|
|
|
312
|
-
|
|
313
|
-
/shell
|
|
314
|
-
```
|
|
282
|
+
## Terminal output and safety
|
|
315
283
|
|
|
316
|
-
|
|
284
|
+
Interactive commands write directly to your terminal so full-screen tools can work. When a command does not read keyboard input and emits only line-oriented text plus safe color sequences, Kward mirrors that output into the transient transcript view after the command exits. Other interactive output is not sanitized and may contain terminal control sequences, so run only commands you trust with terminal access.
|
|
317
285
|
|
|
318
|
-
|
|
286
|
+
Commands run with `capture` inside `/shell` preserve safe ANSI color and style sequences while removing cursor movement, clear-screen controls, title changes, alternate-screen controls, and similar sequences that could damage the TUI transcript.
|
|
319
287
|
|
|
320
288
|
## Limitations
|
|
321
289
|
|
|
322
|
-
`ekwsh` is
|
|
323
|
-
|
|
324
|
-
Current limitations:
|
|
325
|
-
|
|
326
|
-
- no job control,
|
|
327
|
-
- no persistent shell functions,
|
|
328
|
-
- no shell startup file sourcing,
|
|
329
|
-
- no native readline from your login shell,
|
|
330
|
-
- normal `/shell` command output is transcript-sanitized rather than treated as a full terminal UI.
|
|
290
|
+
`ekwsh` manages shell-like state, but it is not a persistent login shell or terminal emulator:
|
|
331
291
|
|
|
332
|
-
|
|
292
|
+
- each external command runs separately through the configured shell,
|
|
293
|
+
- there is no job control; a stopped child is terminated rather than leaving the terminal stranded,
|
|
294
|
+
- shell functions do not persist and shell startup files are not sourced,
|
|
295
|
+
- there is no login-shell readline integration,
|
|
296
|
+
- full-screen terminal state is not retained after an interactive command exits,
|
|
297
|
+
- safe line-oriented output may remain in the transient TUI transcript, but full-screen terminal state is not retained and no shell output becomes part of the AI conversation.
|
data/doc/skills.md
CHANGED
|
@@ -70,19 +70,31 @@ Project-level skills live in the current workspace:
|
|
|
70
70
|
|
|
71
71
|
The `.agents/skills` paths are the cross-client Agent Skills convention. Use them when you want skills to work across compatible agents.
|
|
72
72
|
|
|
73
|
-
Project skills
|
|
73
|
+
Project skills require an explicit trust decision because repository-provided instructions may be untrusted. In the interactive TUI, Kward asks when it finds a new or changed project skill:
|
|
74
74
|
|
|
75
75
|
```text
|
|
76
|
-
/
|
|
76
|
+
Allow / Deny / Review
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
`Review` displays the bounded `SKILL.md` contents and lists referenced resources without executing them. Trust decisions are scoped to the current workspace and skill snapshot. A changed skill or newly added skill requires another decision. Use `/new` after changing trust for the active agent to rebuild.
|
|
80
|
+
|
|
81
|
+
You can inspect or manage the current workspace from the TUI:
|
|
80
82
|
|
|
81
83
|
```text
|
|
82
|
-
|
|
84
|
+
/skills status
|
|
85
|
+
/skills trust
|
|
86
|
+
/skills untrust
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For non-interactive use, inspect or manage trust explicitly:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
kward --working-directory /path/to/project skills status
|
|
93
|
+
kward --working-directory /path/to/project skills review
|
|
94
|
+
kward --working-directory /path/to/project skills trust
|
|
83
95
|
```
|
|
84
96
|
|
|
85
|
-
|
|
97
|
+
Trust records are stored in `~/.kward/trusted_project_skills.json`. The legacy global setting remains available:
|
|
86
98
|
|
|
87
99
|
```json
|
|
88
100
|
{
|
data/doc/tabs.md
CHANGED
|
@@ -61,7 +61,7 @@ Inspect, merge, or remove the binding explicitly:
|
|
|
61
61
|
|
|
62
62
|
Removal refuses a dirty worktree and keeps its branch. A worktree that is missing or no longer points at the recorded branch is restored as unavailable rather than silently falling back to the original workspace.
|
|
63
63
|
|
|
64
|
-
Worktree tabs are available for normal session tabs, not plugin-owned tabs. Kward's file tools, `@`/`$` completion, `/files` browser, integrated editor, and model-requested shell workers use the active worktree root. Model operations retain strict workspace guardrails. The
|
|
64
|
+
Worktree tabs are available for normal session tabs, not plugin-owned tabs. Kward's file tools, `@`/`$` completion, `/files` browser, integrated editor, and model-requested shell workers use the active worktree root. Model operations retain strict workspace guardrails. The user-directed `/shell`, `!command`, `/capture`, and `/pty` features remain host-process operations and are not contained by the model command sandbox; use them only when that is intentional. Generic shell Git writes remain protected. When explicitly asked to commit, the agent can use the active tab's narrow `git_commit` tool; use the interactive `/git` flow when you want to review and commit changes yourself.
|
|
65
65
|
|
|
66
66
|
## Common workflow
|
|
67
67
|
|
data/doc/usage.md
CHANGED
|
@@ -66,7 +66,7 @@ Inside interactive mode, ask Kward to run a command:
|
|
|
66
66
|
Run the focused test for the CLI status command.
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
Or run
|
|
69
|
+
Or run an interactive PTY command yourself from the composer by prefixing it with `!`. Aliases configured in `ekwsh.yml` are expanded here too:
|
|
70
70
|
|
|
71
71
|
```text
|
|
72
72
|
!git status --short
|
|
@@ -78,7 +78,7 @@ For several commands, enter the embedded Kward shell:
|
|
|
78
78
|
/shell
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
`/shell` opens `ekwsh`, a Kward-native command mode that
|
|
81
|
+
`/shell` opens `ekwsh`, a Kward-native command mode that preserves state such as the current directory, environment variables, and aliases between commands. External commands receive an interactive PTY by default, so `git log`, `less`, Vim, SSH, and REPLs work without a prefix. Use `capture <command>` inside `/shell` or `/capture <command>` from the normal composer for bounded, transcript-friendly output. See [Embedded shell](shell.md) for built-ins, completion, configuration, ANSI handling, PTY passthrough, and limitations.
|
|
82
82
|
|
|
83
83
|
## Shell commands
|
|
84
84
|
|
|
@@ -123,8 +123,9 @@ Slash commands run local actions in the current session. Most do not send a prom
|
|
|
123
123
|
| `/git` | review uncommitted changes, stage files, and commit. |
|
|
124
124
|
| `/diff` | open the file changes recorded in the current session. |
|
|
125
125
|
| `/files` | browse project files in a nested tree and open them in the editor. |
|
|
126
|
-
| `/shell` | run workspace commands
|
|
127
|
-
| `/
|
|
126
|
+
| `/shell` | run stateful workspace commands with interactive PTY support. |
|
|
127
|
+
| `/capture <command>` | run a bounded one-shot command and retain its output in the transcript. |
|
|
128
|
+
| `/pty <command>` | explicitly hand the terminal to an interactive command; retained for compatibility with existing workflows. |
|
|
128
129
|
| `/settings` | configure models, accounts, memory, interface, tools, context, personalization, and logging. |
|
|
129
130
|
| `/status` | see session, model, and context status. |
|
|
130
131
|
| `/new` | start a fresh session in the current tab. |
|
|
@@ -168,7 +169,7 @@ Prompt templates, configured skills, and plugins can add more slash commands. Th
|
|
|
168
169
|
|
|
169
170
|
## Prompt history
|
|
170
171
|
|
|
171
|
-
The [Interactive composer](composer.md) guide covers multiline editing, slash and file completion, reasoning
|
|
172
|
+
The [Interactive composer](composer.md) guide covers multiline editing, slash and file completion, reasoning selection, busy input, cancellation, attachments, and terminal compatibility.
|
|
172
173
|
|
|
173
174
|
In interactive mode, Kward keeps prompt history per workspace under `~/.kward/history/`. Press Up/Down to recall previous prompts across restarts.
|
|
174
175
|
|
data/kward.gemspec
CHANGED
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
|
|
21
21
|
spec.files = Dir.chdir(__dir__) do
|
|
22
22
|
`git ls-files -z`.split("\x0").reject do |file|
|
|
23
|
-
file.start_with?(".ruby-lsp/", "test/", "plan/") || [".gitignore", "AGENTS.md"].include?(file)
|
|
23
|
+
file.start_with?(".github/", ".ruby-lsp/", "script/", "test/", "plan/") || [".gitignore", "AGENTS.md"].include?(file)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
spec.bindir = "exe"
|