kward 0.71.0 → 0.73.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/.github/workflows/ci.yml +30 -0
- data/CHANGELOG.md +93 -0
- data/Gemfile.lock +2 -2
- data/README.md +4 -0
- data/doc/agent-tools.md +15 -6
- data/doc/authentication.md +22 -1
- data/doc/code-search.md +42 -2
- data/doc/configuration.md +106 -3
- data/doc/context-budgeting.md +136 -0
- data/doc/context-tools.md +16 -3
- data/doc/editor.md +415 -0
- data/doc/extensibility.md +16 -7
- data/doc/files.md +100 -0
- data/doc/getting-started.md +25 -18
- data/doc/git.md +123 -0
- data/doc/memory.md +24 -4
- data/doc/personas.md +34 -5
- data/doc/plugins.md +72 -1
- data/doc/releasing.md +37 -9
- data/doc/rpc.md +75 -5
- data/doc/session-management.md +35 -1
- data/doc/shell.md +332 -0
- data/doc/tabs.md +122 -0
- data/doc/troubleshooting.md +77 -1
- data/doc/usage.md +79 -7
- data/doc/web-search.md +12 -4
- data/doc/workspace-tools.md +51 -12
- data/examples/plugins/space_invaders.rb +377 -0
- data/lib/kward/agent.rb +1 -1
- data/lib/kward/ansi.rb +62 -23
- data/lib/kward/cli/commands.rb +33 -2
- data/lib/kward/cli/git.rb +150 -0
- data/lib/kward/cli/interactive_turn.rb +73 -9
- data/lib/kward/cli/plugins.rb +54 -4
- data/lib/kward/cli/prompt_interface.rb +32 -1
- data/lib/kward/cli/rendering.rb +4 -1
- data/lib/kward/cli/runtime_helpers.rb +268 -4
- data/lib/kward/cli/sessions.rb +2 -2
- data/lib/kward/cli/settings.rb +217 -9
- data/lib/kward/cli/slash_commands.rb +628 -2
- data/lib/kward/cli/tabs.rb +725 -0
- data/lib/kward/cli/tool_summaries.rb +6 -0
- data/lib/kward/cli.rb +150 -26
- data/lib/kward/clipboard.rb +2 -3
- data/lib/kward/compactor.rb +7 -19
- data/lib/kward/config_files.rb +145 -1
- data/lib/kward/context_budget_meter.rb +44 -0
- data/lib/kward/conversation.rb +12 -4
- data/lib/kward/editor_mode.rb +25 -0
- data/lib/kward/ekwsh.rb +559 -0
- data/lib/kward/image_attachments.rb +3 -1
- data/lib/kward/interactive_pty_runner.rb +151 -0
- data/lib/kward/local_command_runner.rb +155 -0
- data/lib/kward/local_pty_command_runner.rb +171 -0
- data/lib/kward/model/context_usage.rb +2 -2
- data/lib/kward/model/payloads.rb +2 -5
- data/lib/kward/plugin_registry.rb +61 -0
- data/lib/kward/project_files.rb +52 -0
- data/lib/kward/prompt_history.rb +84 -0
- data/lib/kward/prompt_interface/composer_controller.rb +69 -1
- data/lib/kward/prompt_interface/composer_renderer.rb +109 -13
- data/lib/kward/prompt_interface/composer_state.rb +96 -27
- data/lib/kward/prompt_interface/editor/auto_close_pairs.rb +123 -0
- data/lib/kward/prompt_interface/editor/auto_indent.rb +510 -0
- data/lib/kward/prompt_interface/editor/buffer.rb +109 -0
- data/lib/kward/prompt_interface/editor/controller.rb +1218 -0
- data/lib/kward/prompt_interface/editor/endwise.rb +321 -0
- data/lib/kward/prompt_interface/editor/file_marker.rb +40 -0
- data/lib/kward/prompt_interface/editor/indent_navigation.rb +61 -0
- data/lib/kward/prompt_interface/editor/kill_ring.rb +78 -0
- data/lib/kward/prompt_interface/editor/modes/emacs.rb +259 -0
- data/lib/kward/prompt_interface/editor/modes/modern.rb +354 -0
- data/lib/kward/prompt_interface/editor/modes/vibe.rb +1812 -0
- data/lib/kward/prompt_interface/editor/modes/vibe_insert_readline.rb +166 -0
- data/lib/kward/prompt_interface/editor/renderer.rb +244 -0
- data/lib/kward/prompt_interface/editor/search.rb +76 -0
- data/lib/kward/prompt_interface/editor/selections.rb +120 -0
- data/lib/kward/prompt_interface/editor/state.rb +1271 -0
- data/lib/kward/prompt_interface/editor/status_text.rb +23 -0
- data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +422 -0
- data/lib/kward/prompt_interface/editor/undo_history.rb +46 -0
- data/lib/kward/prompt_interface/editor/vibe_state.rb +44 -0
- data/lib/kward/prompt_interface/file_overlay.rb +211 -0
- data/lib/kward/prompt_interface/git_prompt.rb +288 -0
- data/lib/kward/prompt_interface/interactive/controller.rb +186 -0
- data/lib/kward/prompt_interface/interactive/renderer.rb +71 -0
- data/lib/kward/prompt_interface/interactive/state.rb +62 -0
- data/lib/kward/prompt_interface/key_handler.rb +451 -57
- data/lib/kward/prompt_interface/overlay_renderer.rb +21 -2
- data/lib/kward/prompt_interface/project_browser.rb +524 -0
- data/lib/kward/prompt_interface/question_prompt.rb +99 -56
- data/lib/kward/prompt_interface/runtime_state.rb +43 -0
- data/lib/kward/prompt_interface/screen.rb +19 -3
- data/lib/kward/prompt_interface/selection_prompt.rb +10 -19
- data/lib/kward/prompt_interface/slash_overlay.rb +2 -0
- data/lib/kward/prompt_interface/stream_state.rb +7 -0
- data/lib/kward/prompt_interface/transcript_buffer.rb +6 -0
- data/lib/kward/prompt_interface.rb +366 -222
- data/lib/kward/prompts/commands.rb +9 -0
- data/lib/kward/prompts.rb +2 -0
- data/lib/kward/rpc/memory_methods.rb +83 -0
- data/lib/kward/rpc/server.rb +169 -83
- data/lib/kward/rpc/session_manager.rb +45 -121
- data/lib/kward/rpc/session_tree_rows.rb +9 -115
- data/lib/kward/rpc/tool_event_normalizer.rb +1 -1
- data/lib/kward/rpc/tool_metadata.rb +11 -0
- data/lib/kward/rpc/transcript_normalizer.rb +4 -39
- data/lib/kward/scratchpad_runner.rb +56 -0
- data/lib/kward/session_diff.rb +20 -3
- data/lib/kward/session_naming.rb +11 -0
- data/lib/kward/session_store.rb +44 -0
- data/lib/kward/session_tree_nodes.rb +136 -0
- data/lib/kward/session_tree_renderer.rb +9 -131
- data/lib/kward/tab_store.rb +47 -0
- data/lib/kward/terminal_keys.rb +84 -0
- data/lib/kward/terminal_sequences.rb +42 -0
- data/lib/kward/text_boundary.rb +25 -0
- data/lib/kward/tools/context_budget_stats.rb +54 -0
- data/lib/kward/tools/context_for_task.rb +204 -0
- data/lib/kward/tools/read_file.rb +8 -4
- data/lib/kward/tools/registry.rb +62 -16
- data/lib/kward/tools/tool_call.rb +10 -0
- data/lib/kward/version.rb +1 -1
- data/lib/kward/workers/git_guard.rb +93 -0
- data/lib/kward/workers/job.rb +99 -0
- data/lib/kward/workers/live_view.rb +49 -0
- data/lib/kward/workers/manager.rb +288 -0
- data/lib/kward/workers/queue_runner.rb +166 -0
- data/lib/kward/workers/queue_store.rb +112 -0
- data/lib/kward/workers/store.rb +72 -0
- data/lib/kward/workers/tool_policy.rb +23 -0
- data/lib/kward/workers/worker.rb +82 -0
- data/lib/kward/workers/write_lock.rb +38 -0
- data/lib/kward/workers.rb +10 -0
- data/lib/kward/workspace.rb +125 -87
- data/templates/default/fulldoc/html/css/kward.css +140 -36
- data/templates/default/fulldoc/html/images/kward_screen_1.png +0 -0
- data/templates/default/fulldoc/html/setup.rb +1 -0
- data/templates/default/kward_navigation.rb +12 -1
- data/templates/default/layout/html/layout.erb +23 -34
- data/templates/default/layout/html/setup.rb +6 -0
- metadata +67 -1
data/doc/getting-started.md
CHANGED
|
@@ -18,13 +18,21 @@ Install the gem:
|
|
|
18
18
|
gem install kward
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Optionally install the starter pack:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
kward init
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
The starter pack adds default prompts and a base `PRINCIPLES.md` under `~/.kward`. It does not overwrite existing files.
|
|
27
|
+
The starter pack adds default prompts and a base `PRINCIPLES.md` under `~/.kward`. It does not overwrite existing files. It is safe to skip if you prefer to create your own instructions. It requires network access because it fetches the pack from GitHub.
|
|
28
|
+
|
|
29
|
+
Verify your setup:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
kward doctor
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This checks your config, auth, writable directories, and workspace. Run `kward help` to see all available commands and examples.
|
|
28
36
|
|
|
29
37
|
If you are working from a checkout instead:
|
|
30
38
|
|
|
@@ -49,6 +57,14 @@ Or from inside an interactive session:
|
|
|
49
57
|
|
|
50
58
|
Kward supports OpenAI/ChatGPT, Anthropic Claude Pro/Max, OpenRouter, and experimental Copilot credentials. See [Authentication](authentication.md) when you need a specific provider.
|
|
51
59
|
|
|
60
|
+
Confirm your credentials are saved:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
kward auth status
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If your provider offers multiple models, choose one inside Kward with `/model`.
|
|
67
|
+
|
|
52
68
|
## Start an interactive chat
|
|
53
69
|
|
|
54
70
|
Run Kward from the project you want it to work on:
|
|
@@ -58,6 +74,12 @@ cd ~/code/my-project
|
|
|
58
74
|
kward
|
|
59
75
|
```
|
|
60
76
|
|
|
77
|
+
Or point Kward at a project without leaving your shell:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
kward --working-directory ~/code/my-project
|
|
81
|
+
```
|
|
82
|
+
|
|
61
83
|
Ask something concrete:
|
|
62
84
|
|
|
63
85
|
```text
|
|
@@ -88,7 +110,7 @@ git diff | kward "Review this diff for bugs"
|
|
|
88
110
|
|
|
89
111
|
One-shot prompts do not use Kward memory.
|
|
90
112
|
|
|
91
|
-
## Useful
|
|
113
|
+
## Useful interactive commands
|
|
92
114
|
|
|
93
115
|
Inside interactive Kward:
|
|
94
116
|
|
|
@@ -97,27 +119,12 @@ Inside interactive Kward:
|
|
|
97
119
|
/model choose a model
|
|
98
120
|
/status show session and context status
|
|
99
121
|
/sessions open the saved sessions picker
|
|
100
|
-
/resume alias for /sessions
|
|
101
122
|
/rewind revisit an earlier prompt
|
|
102
123
|
/export notes.md export the transcript
|
|
103
124
|
/compact summarize older context when a chat gets long
|
|
104
125
|
/exit leave Kward
|
|
105
126
|
```
|
|
106
127
|
|
|
107
|
-
## Run from source
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
ruby lib/main.rb login
|
|
111
|
-
ruby lib/main.rb
|
|
112
|
-
ruby lib/main.rb "Explain this project"
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
You can also run:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
exe/kward
|
|
119
|
-
```
|
|
120
|
-
|
|
121
128
|
## Next steps
|
|
122
129
|
|
|
123
130
|
- Read [Usage](usage.md) for day-to-day workflows.
|
data/doc/git.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Git
|
|
2
|
+
|
|
3
|
+
Kward has a small interactive Git workflow built into the terminal UI. It lets you review the current working tree, inspect per-file diffs, stage or unstage files, write a commit message, and create a commit without leaving the chat.
|
|
4
|
+
|
|
5
|
+
Use it when you have just finished a change with Kward and want one last pass before committing. It is intentionally focused: it is not a full Git client, just the common review-and-commit loop.
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
From an interactive Kward session inside a Git repository, run:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
/git
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Kward opens a Git overlay showing the same short status style you would see from:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git status --short --untracked-files=normal
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
M lib/kward/cli.rb
|
|
25
|
+
A doc/git.md
|
|
26
|
+
?? tmp/example.txt
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use the overlay to review and shape the commit:
|
|
30
|
+
|
|
31
|
+
| Key | Action |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `↑` / `↓` | Move between changed files. |
|
|
34
|
+
| `Enter` | Open the selected file in the diff viewer. |
|
|
35
|
+
| `s` | Stage or unstage the selected file. |
|
|
36
|
+
| `Tab` | Switch to commit-message entry. |
|
|
37
|
+
| `Esc` | Cancel and return to chat. |
|
|
38
|
+
|
|
39
|
+
When you press `Tab`, the prompt changes from `Git>` to `Commit>`. Type the commit message and press `Enter` to commit. Press `Tab` again to return to the file list without losing the draft message.
|
|
40
|
+
|
|
41
|
+
Use `Shift+Enter` to insert a newline if you need a multi-line commit message.
|
|
42
|
+
|
|
43
|
+
## Review changes with the diff viewer
|
|
44
|
+
|
|
45
|
+
Highlight a file in the `/git` overlay and press `Enter`.
|
|
46
|
+
|
|
47
|
+
Kward opens a read-only diff viewer in the composer area. It shows classic Git diff output with added and removed lines colorized when terminal color is enabled.
|
|
48
|
+
|
|
49
|
+
Useful keys in the diff viewer:
|
|
50
|
+
|
|
51
|
+
| Key | Action |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `↑` / `↓` | Move through the diff one line at a time. |
|
|
54
|
+
| `Page Up` / `Page Down` | Scroll by a page. |
|
|
55
|
+
| `Home` / `End` | Move within the current line. |
|
|
56
|
+
| `/` or `Ctrl+F` | Search within the diff. |
|
|
57
|
+
| `Ctrl+C` / `Cmd+C` | Copy the current selection. |
|
|
58
|
+
| `Enter` | Confirm the current search. |
|
|
59
|
+
| `Esc` | Cancel search, or close the diff viewer. |
|
|
60
|
+
| `Ctrl+Q` | Close the diff viewer. |
|
|
61
|
+
|
|
62
|
+
After you close the viewer, Kward returns to the Git overlay with the file list refreshed.
|
|
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 [Configuration](configuration.md) for editor modes and settings).
|
|
65
|
+
|
|
66
|
+
## Example workflow
|
|
67
|
+
|
|
68
|
+
A typical end-to-end flow looks like this:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
/git
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
1. Use `↑` and `↓` to scan the changed files.
|
|
75
|
+
2. Press `Enter` on a file that looks risky.
|
|
76
|
+
3. Search the diff with `/` if you need to find a symbol or error message.
|
|
77
|
+
4. Press `Esc` to close the diff viewer.
|
|
78
|
+
5. Press `s` on files you want in this commit.
|
|
79
|
+
6. Press `Tab` to write the commit message.
|
|
80
|
+
7. Press `Enter` to commit.
|
|
81
|
+
|
|
82
|
+
If no files are staged when you submit the commit message, Kward stages all current workspace changes before committing. If at least one file is already staged, Kward commits only the staged changes.
|
|
83
|
+
|
|
84
|
+
That means you can use `/git` in two ways:
|
|
85
|
+
|
|
86
|
+
- **Simple commit:** do not stage anything manually; write a message and Kward commits all current changes.
|
|
87
|
+
- **Selective commit:** stage specific files with `s`; Kward commits only what is staged.
|
|
88
|
+
|
|
89
|
+
## How staged changes work
|
|
90
|
+
|
|
91
|
+
The `s` key toggles the selected file:
|
|
92
|
+
|
|
93
|
+
- unstaged files are staged with `git add -- <path>`
|
|
94
|
+
- staged files are unstaged with `git restore --staged -- <path>`
|
|
95
|
+
|
|
96
|
+
The status list refreshes after each toggle, so you can see what will be included before committing.
|
|
97
|
+
|
|
98
|
+
For untracked files, the diff viewer shows the file as a new file with every line added. That makes it possible to review new files before staging them.
|
|
99
|
+
|
|
100
|
+
Renamed or copied files (status codes `R` and `C`) appear in the list with their destination path after the `->` arrow, and the diff viewer shows the destination file.
|
|
101
|
+
|
|
102
|
+
## Git branch indicator
|
|
103
|
+
|
|
104
|
+
In the interactive composer status line, Kward also shows the current Git branch or short commit SHA when the workspace is inside a repository. The indicator turns yellow when the working tree has uncommitted changes.
|
|
105
|
+
|
|
106
|
+
This is just a lightweight status hint. Use `/git` when you want to review or commit the changes.
|
|
107
|
+
|
|
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
|
+
|
|
110
|
+
## Notes and limitations
|
|
111
|
+
|
|
112
|
+
- `/git` is available in the interactive terminal UI, not in one-shot prompts or the RPC backend.
|
|
113
|
+
- The command must run inside a Git repository.
|
|
114
|
+
- The diff viewer compares tracked files against `HEAD` with `git diff HEAD -- <path>`.
|
|
115
|
+
- The commit command uses `git commit -m <message>`.
|
|
116
|
+
- Kward does not push, pull, merge, rebase, amend, or manage branches from this overlay.
|
|
117
|
+
- Commit success still depends on your local Git configuration, hooks, and repository state.
|
|
118
|
+
|
|
119
|
+
For AI-assisted review without committing, you can still pipe a diff into a one-shot prompt:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git diff | kward "Review this diff"
|
|
123
|
+
```
|
data/doc/memory.md
CHANGED
|
@@ -51,7 +51,7 @@ Add a workspace-specific hint when it only applies to the current project:
|
|
|
51
51
|
/memory add "This workspace uses Minitest."
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Use global core memory sparingly. It has
|
|
54
|
+
Use global core memory sparingly. It applies everywhere, so it has a wider blast radius than workspace memory.
|
|
55
55
|
|
|
56
56
|
## Let Kward summarize useful memories
|
|
57
57
|
|
|
@@ -61,6 +61,12 @@ Auto-summary is off by default. Enable it if you want Kward to learn recurring p
|
|
|
61
61
|
/memory auto-summary enable
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
Disable it again:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
/memory auto-summary disable
|
|
68
|
+
```
|
|
69
|
+
|
|
64
70
|
This only runs when memory is enabled. It does not run for one-shot prompts.
|
|
65
71
|
|
|
66
72
|
You can also ask Kward to summarize the current session manually:
|
|
@@ -69,10 +75,14 @@ You can also ask Kward to summarize the current session manually:
|
|
|
69
75
|
/memory summarize
|
|
70
76
|
```
|
|
71
77
|
|
|
78
|
+
`/memory learn` is an alias for `/memory summarize`.
|
|
79
|
+
|
|
72
80
|
Kward is conservative about inferred memories and refuses to automatically persist emotional, intimate, romantic, or dependency-forming memories.
|
|
73
81
|
|
|
74
82
|
## Inspect what Kward remembers
|
|
75
83
|
|
|
84
|
+
Running `/memory` with no argument prints a summary of all available subcommands.
|
|
85
|
+
|
|
76
86
|
List active memories for the current workspace:
|
|
77
87
|
|
|
78
88
|
```text
|
|
@@ -108,6 +118,12 @@ Promote a workspace hint when it should become a stronger rule:
|
|
|
108
118
|
/memory promote soft_001
|
|
109
119
|
```
|
|
110
120
|
|
|
121
|
+
`/memory promote` also works on workspace core memories, promoting them to global scope so they apply everywhere:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
/memory promote core_003
|
|
125
|
+
```
|
|
126
|
+
|
|
111
127
|
Relax a global memory back to the current workspace:
|
|
112
128
|
|
|
113
129
|
```text
|
|
@@ -124,7 +140,7 @@ Kward uses three layers:
|
|
|
124
140
|
|
|
125
141
|
Core memories override soft memories. Soft memories are treated as hints, not facts.
|
|
126
142
|
|
|
127
|
-
Kward does not inject every stored memory into every prompt. It retrieves a bounded set that appears relevant to the current turn.
|
|
143
|
+
Kward does not inject every stored memory into every prompt. It retrieves a bounded set that appears relevant to the current turn: up to 6 core and 6 soft memories. Core memories are included by scope match (global and current workspace). Soft memories are scored by text and tag overlap with the current input, confidence level, and expiry, and only the top-scoring ones are injected.
|
|
128
144
|
|
|
129
145
|
## Where memory is stored
|
|
130
146
|
|
|
@@ -136,12 +152,16 @@ Default files:
|
|
|
136
152
|
~/.kward/memory/events.jsonl
|
|
137
153
|
```
|
|
138
154
|
|
|
155
|
+
The memory directory is created with mode `0700` and each file with mode `0600`.
|
|
156
|
+
|
|
139
157
|
`events.jsonl` stores a small audit trail for actions such as enable, add, retrieve, summarize, promote, and forget.
|
|
140
158
|
|
|
141
159
|
When a soft memory is forgotten, its text is replaced with `[forgotten]` while inactive audit metadata can remain.
|
|
142
160
|
|
|
143
|
-
|
|
161
|
+
Soft memories have a time-to-live of 60 days by default. Each time a soft memory is retrieved, its `last_seen_at` timestamp is updated and its hit count is incremented. If a soft memory is not retrieved within its TTL window, it expires and is no longer injected into prompts. Forgotten and expired memories remain in the file for audit but are not shown in `/memory list`.
|
|
162
|
+
|
|
163
|
+
If `KWARD_CONFIG_PATH` is set, memory files live beside that config file instead of under `~/.kward`. See [Configuration](configuration.md) for the config-file representation.
|
|
144
164
|
|
|
145
165
|
## RPC support
|
|
146
166
|
|
|
147
|
-
The experimental RPC backend exposes memory methods
|
|
167
|
+
The experimental RPC backend exposes memory methods including `memory/status`, `memory/enable`, `memory/disable`, `memory/autoSummary/enable`, `memory/autoSummary/disable`, `memory/list`, `memory/add`, `memory/addCore`, `memory/forget`, `memory/promote`, `memory/relax`, `memory/inspect`, `memory/why`, and `memory/summarize`. See the [RPC documentation](rpc.md) for the full protocol.
|
data/doc/personas.md
CHANGED
|
@@ -108,7 +108,7 @@ Assistant> I found the failing test.
|
|
|
108
108
|
Samantha> I found the failing test.
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
This is not only decorative. It is the name Kward uses when rendering assistant messages in the terminal transcript. If
|
|
111
|
+
This is not only decorative. It is the name Kward uses when rendering assistant messages in the terminal transcript. If the active persona has no `label` field, Kward uses `Assistant>` instead — the character `key` is not used as a fallback label. If no persona is active at all, Kward also uses `Assistant>`.
|
|
112
112
|
|
|
113
113
|
For RPC clients, the active label is also exposed as `activePersonaLabel` so a UI can show the same speaker identity.
|
|
114
114
|
|
|
@@ -163,6 +163,19 @@ You can also define characters as a map:
|
|
|
163
163
|
}
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
+
In the map form, the key is the character key. You can also use a bare string as the definition, which becomes the instruction; the transcript label then falls back to `Assistant>` unless you use a hash with `label`:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"personas": {
|
|
171
|
+
"characters": {
|
|
172
|
+
"duck": "You are a patient rubber duck."
|
|
173
|
+
},
|
|
174
|
+
"default": "duck"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
166
179
|
The array form is easier to read and is recommended for new configs.
|
|
167
180
|
|
|
168
181
|
`personas.crew` is accepted as a legacy alias for `personas.characters`.
|
|
@@ -179,13 +192,25 @@ Set `personas.default` to the character key you want by default:
|
|
|
179
192
|
}
|
|
180
193
|
```
|
|
181
194
|
|
|
195
|
+
`personas.default` can also be a raw instruction string instead of a character key. When the value does not match any character, Kward uses it directly as the persona instruction:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"personas": {
|
|
200
|
+
"default": "You are a calm assistant."
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
This is a quick way to set a persona without defining a `characters` entry.
|
|
206
|
+
|
|
182
207
|
You can also change the default from interactive Kward:
|
|
183
208
|
|
|
184
209
|
```text
|
|
185
210
|
/settings
|
|
186
211
|
```
|
|
187
212
|
|
|
188
|
-
|
|
213
|
+
Choose **Personalization**, then **Default persona** to pick from your configured characters. The same menu also offers **Active instructions summary**, which shows the active persona label and whether `PRINCIPLES.md` and workspace `AGENTS.md` are present.
|
|
189
214
|
|
|
190
215
|
## Workspace-specific personas
|
|
191
216
|
|
|
@@ -268,7 +293,7 @@ anthropic_reasoning_effort
|
|
|
268
293
|
copilot_reasoning_effort
|
|
269
294
|
```
|
|
270
295
|
|
|
271
|
-
Personas do not choose the model and do not set reasoning effort by themselves. What personas can do is add extra character direction based on the active reasoning effort.
|
|
296
|
+
Personas do not choose the model and do not set reasoning effort by themselves. What personas can do is add extra character direction based on the active reasoning effort. See [Configuration](configuration.md) for the full provider, model, and reasoning config reference.
|
|
272
297
|
|
|
273
298
|
In plain English:
|
|
274
299
|
|
|
@@ -324,7 +349,7 @@ Example:
|
|
|
324
349
|
}
|
|
325
350
|
```
|
|
326
351
|
|
|
327
|
-
If no bucket matches, no time-of-day modifier is added.
|
|
352
|
+
If no bucket matches, no time-of-day modifier is added. Hours 12:00-20:59 (noon through early evening) have no bucket, so no time-of-day modifier is applied during that window.
|
|
328
353
|
|
|
329
354
|
## Weekday modifiers
|
|
330
355
|
|
|
@@ -404,7 +429,11 @@ From the shell:
|
|
|
404
429
|
kward sysprompt
|
|
405
430
|
```
|
|
406
431
|
|
|
407
|
-
`kward sysprompt` shows the assembled prompt sections, including the persona text that would be used for a new conversation.
|
|
432
|
+
`kward sysprompt` shows the assembled prompt sections, including the persona text that would be used for a new conversation. Add `--raw` to print the raw system prompt content without section formatting, which is useful for scripting or piping to another tool:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
kward sysprompt --raw
|
|
436
|
+
```
|
|
408
437
|
|
|
409
438
|
## When to use personas
|
|
410
439
|
|
data/doc/plugins.md
CHANGED
|
@@ -21,6 +21,8 @@ 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.
|
|
25
|
+
|
|
24
26
|
## Where plugins live
|
|
25
27
|
|
|
26
28
|
Kward loads top-level Ruby files from:
|
|
@@ -56,6 +58,8 @@ Start Kward and run:
|
|
|
56
58
|
/hello World
|
|
57
59
|
```
|
|
58
60
|
|
|
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.
|
|
62
|
+
|
|
59
63
|
## Add a slash command
|
|
60
64
|
|
|
61
65
|
Use plugin commands for local actions that should not call the model.
|
|
@@ -77,7 +81,7 @@ A plugin command cannot replace a built-in command or prompt-template command.
|
|
|
77
81
|
|
|
78
82
|
Prompt context is short text injected into future model requests.
|
|
79
83
|
|
|
80
|
-
Use it for stable facts the model should know, not for large files or secrets.
|
|
84
|
+
Use it for stable facts the model should know, not for large files or secrets. The block should return a string (injected into the system prompt) or `nil` (skipped). The example below uses Ruby's `next` to return `nil` early when the condition does not match.
|
|
81
85
|
|
|
82
86
|
```ruby
|
|
83
87
|
Kward.plugin do |plugin|
|
|
@@ -109,6 +113,71 @@ end
|
|
|
109
113
|
|
|
110
114
|
Only one footer is active. If multiple plugins register footers, the later one replaces the earlier one and Kward prints a warning.
|
|
111
115
|
|
|
116
|
+
## Add an interactive command
|
|
117
|
+
|
|
118
|
+
Interactive commands take over the composer region with a Kward-driven render and
|
|
119
|
+
input loop. The plugin receives a controller object with a canvas API for
|
|
120
|
+
drawing colored cells and reading keys. This is useful for games, dashboards,
|
|
121
|
+
viewers, and similar full-region interactive experiences.
|
|
122
|
+
|
|
123
|
+
`interactive_command` accepts `description:` and `argument_hint:` keyword arguments, which appear in the slash command list and completion overlay just like regular plugin commands. `rows:` sets the fixed canvas height (minimum 1), and `fps:` sets the target frame rate (1–120, default 30).
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
Kward.plugin do |plugin|
|
|
127
|
+
plugin.interactive_command "demo", rows: 10, fps: 30, description: "Canvas demo" do |ui, ctx|
|
|
128
|
+
x = 0
|
|
129
|
+
ui.on_tick do |ui|
|
|
130
|
+
ui.clear_frame
|
|
131
|
+
ui.put(0, x, "X", :red)
|
|
132
|
+
x = (x + 1) % ui.width
|
|
133
|
+
key = ui.poll_key
|
|
134
|
+
return :exit if key == :ctrl_c || key == "q"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Run it with `/demo` from the interactive TUI. The canvas renders inside the
|
|
141
|
+
composer area for the specified number of rows. The transcript above stays
|
|
142
|
+
intact.
|
|
143
|
+
|
|
144
|
+
### Controller API
|
|
145
|
+
|
|
146
|
+
The `ui` controller object passed to the handler block exposes:
|
|
147
|
+
|
|
148
|
+
| Method | Description |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| `put(row, col, char, *colors)` | Place a character at a zero-based position with optional ANSI color styles |
|
|
151
|
+
| `clear_frame` | Reset all canvas cells to blank |
|
|
152
|
+
| `render` | Mark the canvas as ready for Kward to draw |
|
|
153
|
+
| `poll_key` | Return the next pending key (non-blocking, nil if none) |
|
|
154
|
+
| `exit` | Request that the interactive loop exit |
|
|
155
|
+
| `on_tick { \|ui\| }` | Register a tick callback invoked each frame at the configured fps |
|
|
156
|
+
| `width` | Canvas width in terminal columns |
|
|
157
|
+
| `height` | Canvas height in terminal rows |
|
|
158
|
+
| `fps` | Target frame rate |
|
|
159
|
+
|
|
160
|
+
Keys are returned as symbols (`:left`, `:right`, `:up`, `:down`, `:return`,
|
|
161
|
+
`:backspace`, `:space`, `:pageup`, `:pagedown`) or raw strings for keys
|
|
162
|
+
without a named mapping. Ctrl+C always exits the loop immediately.
|
|
163
|
+
|
|
164
|
+
The tick callback runs at the configured frame rate (1–120 fps, default 30).
|
|
165
|
+
Returning `:exit` from the tick callback ends the loop, same as calling
|
|
166
|
+
`ui.exit`.
|
|
167
|
+
|
|
168
|
+
### Lifecycle
|
|
169
|
+
|
|
170
|
+
- The composer state is saved on entry and fully restored on exit (input text,
|
|
171
|
+
cursor, and transcript viewport).
|
|
172
|
+
- Interactive mode is a distinct state from the busy-input spinner lifecycle —
|
|
173
|
+
no spinner or busy chrome is shown.
|
|
174
|
+
- Ctrl+C, the plugin calling `exit`, or the tick callback returning `:exit`
|
|
175
|
+
all exit cleanly and restore the prior composer state.
|
|
176
|
+
- Resize during interactive mode forces a clean exit and restore.
|
|
177
|
+
|
|
178
|
+
Interactive commands require the TUI prompt interface. They are not available
|
|
179
|
+
in piped/non-interactive mode or through RPC.
|
|
180
|
+
|
|
112
181
|
## Observe transcript events
|
|
113
182
|
|
|
114
183
|
Use transcript events when you need to log or react to live activity:
|
|
@@ -151,6 +220,8 @@ Handlers receive a `ctx` object. Common methods:
|
|
|
151
220
|
- `ctx.session_path`
|
|
152
221
|
- `ctx.refresh_system_message!`
|
|
153
222
|
|
|
223
|
+
These methods are available in all handler types: commands, footers, prompt context renderers, and transcript event observers. `ctx.say` outputs to the active frontend (terminal or RPC) wherever it is called.
|
|
224
|
+
|
|
154
225
|
The transcript is read-only. Use context methods instead of mutating Kward internals.
|
|
155
226
|
|
|
156
227
|
## RPC support
|
data/doc/releasing.md
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
# Releasing Kward
|
|
2
2
|
|
|
3
|
+
Kward requires Ruby >= 3.2 (`spec.required_ruby_version` in `kward.gemspec`). If you develop with a newer Ruby, verify tests pass against the minimum supported version before releasing.
|
|
4
|
+
|
|
3
5
|
Release steps before publishing:
|
|
4
6
|
|
|
5
|
-
1. Update `CHANGELOG.md` for the version.
|
|
7
|
+
1. Update `CHANGELOG.md` for the version. Move `[Unreleased]` entries under a new version heading.
|
|
6
8
|
2. Update `Kward::VERSION` in `lib/kward/version.rb`.
|
|
7
|
-
3. Run the test suite:
|
|
9
|
+
3. Run the full test suite:
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
bundle exec rake test
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
4.
|
|
15
|
+
4. Run focused tests for any areas you changed during the release prep itself (docs, config, etc.):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
ruby -Itest test/test_cli.rb
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
5. Preview docs locally if you changed documentation or public APIs:
|
|
14
22
|
|
|
15
23
|
```bash
|
|
16
24
|
bundle exec rake docs:serve
|
|
@@ -18,24 +26,36 @@ Release steps before publishing:
|
|
|
18
26
|
|
|
19
27
|
The preview builds `_yardoc/`, serves it with WEBrick, and rebuilds in a fresh process when documentation sources, library code, or templates change. Refresh your browser after rebuilds.
|
|
20
28
|
|
|
21
|
-
|
|
29
|
+
6. Generate and check documentation:
|
|
22
30
|
|
|
23
31
|
```bash
|
|
24
|
-
bundle exec rake rdoc
|
|
25
32
|
bundle exec rake docs:build
|
|
26
33
|
bundle exec rake docs:check
|
|
27
34
|
```
|
|
28
35
|
|
|
29
|
-
`docs:check` validates generated internal links, images, and scripts. Pushes to `main` deploy the generated YARD site to GitHub Pages.
|
|
36
|
+
`docs:check` validates generated internal links, images, and scripts. Pushes to `main` deploy the generated YARD site to GitHub Pages. You can also run `bundle exec rake rdoc` to generate a separate RDoc site as a sanity check, but it is not deployed.
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
7. Build the gem locally:
|
|
32
39
|
|
|
33
40
|
```bash
|
|
34
41
|
gem build kward.gemspec
|
|
35
42
|
```
|
|
36
43
|
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
8. Inspect the packaged files and confirm no local config, sessions, logs, or secrets are included. The gemspec uses `git ls-files` and excludes `test/`, `plan/`, `.ruby-lsp/`, `.gitignore`, and `AGENTS.md`. To verify what is packaged:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
tar tf kward-VERSION.gem
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
9. Install the built gem locally and smoke test the `kward` executable in a clean workspace.
|
|
51
|
+
|
|
52
|
+
Commit the version bump and create a git tag:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git commit -am "Bump to VERSION"
|
|
56
|
+
git tag vVERSION
|
|
57
|
+
git push && git push --tags
|
|
58
|
+
```
|
|
39
59
|
|
|
40
60
|
Publish the built gem from the release checkout:
|
|
41
61
|
|
|
@@ -44,3 +64,11 @@ gem push kward-VERSION.gem
|
|
|
44
64
|
```
|
|
45
65
|
|
|
46
66
|
RubyGems MFA is required for publishing. Prefer RubyGems trusted publishing for automated releases if CI publishing is added later, so long-lived API keys do not need to be stored in CI secrets.
|
|
67
|
+
|
|
68
|
+
If a published gem has a serious problem, you can yank it within 24 hours of pushing:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
gem yank kward --version VERSION
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Yanking removes the gem from the default install index but does not delete the version entirely. After yanking, fix the issue, bump the version, and release again.
|