kward 0.67.1 → 0.68.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 +20 -0
- data/Gemfile.lock +2 -2
- data/README.md +5 -5
- data/doc/authentication.md +24 -1
- data/doc/configuration.md +9 -2
- data/doc/extensibility.md +1 -1
- data/doc/getting-started.md +4 -6
- data/doc/plugins.md +0 -2
- data/doc/releasing.md +7 -8
- data/doc/rpc.md +6 -6
- data/doc/usage.md +5 -2
- data/doc/web-search.md +2 -2
- data/kward.gemspec +4 -0
- data/lib/kward/agent.rb +29 -2
- data/lib/kward/ansi.rb +3 -0
- data/lib/kward/auth/anthropic_oauth.rb +291 -0
- data/lib/kward/auth/file.rb +2 -0
- data/lib/kward/auth/github_oauth.rb +3 -0
- data/lib/kward/auth/openai_oauth.rb +4 -0
- data/lib/kward/auth/openrouter_api_key.rb +2 -0
- data/lib/kward/cancellation.rb +3 -0
- data/lib/kward/cli/auth_commands.rb +82 -0
- data/lib/kward/cli/commands.rb +222 -0
- data/lib/kward/cli/compaction.rb +25 -0
- data/lib/kward/cli/doctor.rb +121 -0
- data/lib/kward/cli/interactive_turn.rb +225 -0
- data/lib/kward/cli/memory_commands.rb +133 -0
- data/lib/kward/cli/plugins.rb +112 -0
- data/lib/kward/cli/prompt_interface.rb +132 -0
- data/lib/kward/cli/rendering.rb +389 -0
- data/lib/kward/cli/runtime_helpers.rb +159 -0
- data/lib/kward/cli/sessions.rb +376 -0
- data/lib/kward/cli/settings.rb +663 -0
- data/lib/kward/cli/slash_commands.rb +112 -0
- data/lib/kward/cli/stats.rb +64 -0
- data/lib/kward/cli/tool_summaries.rb +153 -0
- data/lib/kward/cli.rb +38 -2790
- data/lib/kward/cli_transcript_formatter.rb +4 -7
- data/lib/kward/clipboard.rb +1 -0
- data/lib/kward/compaction/file_operation_tracker.rb +3 -0
- data/lib/kward/compactor.rb +29 -7
- data/lib/kward/config_files.rb +33 -24
- data/lib/kward/conversation.rb +70 -5
- data/lib/kward/events.rb +2 -0
- data/lib/kward/export_path.rb +2 -0
- data/lib/kward/image_attachments.rb +2 -0
- data/lib/kward/markdown_transcript.rb +2 -0
- data/lib/kward/memory/manager.rb +13 -0
- data/lib/kward/message_access.rb +23 -2
- data/lib/kward/message_text.rb +45 -0
- data/lib/kward/model/chat_invocation.rb +2 -0
- data/lib/kward/model/client.rb +295 -77
- data/lib/kward/model/context_overflow.rb +2 -0
- data/lib/kward/model/context_usage.rb +3 -0
- data/lib/kward/model/model_info.rb +143 -4
- data/lib/kward/model/payloads.rb +166 -13
- data/lib/kward/model/retry_message.rb +2 -0
- data/lib/kward/model/stream_parser.rb +129 -0
- data/lib/kward/pan/server.rb +3 -1
- data/lib/kward/plugin_registry.rb +12 -0
- data/lib/kward/private_file.rb +2 -0
- data/lib/kward/prompt_interface/banner.rb +3 -0
- data/lib/kward/prompt_interface/composer_controller.rb +262 -0
- data/lib/kward/prompt_interface/composer_renderer.rb +172 -0
- data/lib/kward/prompt_interface/composer_state.rb +221 -0
- data/lib/kward/prompt_interface/key_handler.rb +365 -0
- data/lib/kward/prompt_interface/layout.rb +31 -0
- data/lib/kward/prompt_interface/overlay_renderer.rb +111 -0
- data/lib/kward/prompt_interface/prompt_renderer.rb +91 -0
- data/lib/kward/prompt_interface/question_prompt.rb +328 -0
- data/lib/kward/prompt_interface/runtime_state.rb +59 -0
- data/lib/kward/prompt_interface/screen.rb +186 -0
- data/lib/kward/prompt_interface/selection_prompt.rb +242 -0
- data/lib/kward/prompt_interface/slash_overlay.rb +102 -0
- data/lib/kward/prompt_interface/stream_state.rb +65 -0
- data/lib/kward/prompt_interface/transcript_buffer.rb +85 -0
- data/lib/kward/prompt_interface/transcript_renderer.rb +142 -0
- data/lib/kward/prompt_interface.rb +69 -1832
- data/lib/kward/prompts/commands.rb +2 -0
- data/lib/kward/prompts/templates.rb +3 -0
- data/lib/kward/prompts.rb +2 -0
- data/lib/kward/question_contract.rb +66 -0
- data/lib/kward/resources/avatar_kward_logo.rb +2 -0
- data/lib/kward/resources/pixel_logo.rb +2 -0
- data/lib/kward/rpc/attachment_normalizer.rb +60 -0
- data/lib/kward/rpc/auth_manager.rb +65 -11
- data/lib/kward/rpc/config_manager.rb +11 -0
- data/lib/kward/rpc/prompt_bridge.rb +5 -26
- data/lib/kward/rpc/redactor.rb +3 -0
- data/lib/kward/rpc/runtime_payloads.rb +4 -1
- data/lib/kward/rpc/server.rb +36 -9
- data/lib/kward/rpc/session_manager.rb +121 -345
- data/lib/kward/rpc/session_metrics.rb +68 -0
- data/lib/kward/rpc/session_tree.rb +48 -0
- data/lib/kward/rpc/session_tree_rows.rb +208 -0
- data/lib/kward/rpc/tool_event_normalizer.rb +3 -0
- data/lib/kward/rpc/tool_metadata.rb +3 -0
- data/lib/kward/rpc/transcript_normalizer.rb +3 -0
- data/lib/kward/rpc/transport.rb +3 -0
- data/lib/kward/session_diff.rb +2 -0
- data/lib/kward/session_store.rb +114 -24
- data/lib/kward/session_trash.rb +1 -0
- data/lib/kward/session_tree_renderer.rb +8 -41
- data/lib/kward/session_tree_tool_display.rb +56 -0
- data/lib/kward/skills/registry.rb +3 -0
- data/lib/kward/starter_pack_installer.rb +1 -0
- data/lib/kward/steering.rb +2 -0
- data/lib/kward/telemetry/logger.rb +3 -0
- data/lib/kward/telemetry/stats.rb +3 -0
- data/lib/kward/tools/ask_user_question.rb +20 -32
- data/lib/kward/tools/base.rb +8 -0
- data/lib/kward/tools/code_search.rb +5 -0
- data/lib/kward/tools/edit_file.rb +5 -0
- data/lib/kward/tools/list_directory.rb +5 -0
- data/lib/kward/tools/read_file.rb +5 -0
- data/lib/kward/tools/read_skill.rb +5 -0
- data/lib/kward/tools/registry.rb +33 -2
- data/lib/kward/tools/run_shell_command.rb +5 -0
- data/lib/kward/tools/search/code.rb +7 -0
- data/lib/kward/tools/search/web.rb +17 -14
- data/lib/kward/tools/tool_call.rb +25 -5
- data/lib/kward/tools/web_search.rb +7 -1
- data/lib/kward/tools/write_file.rb +5 -0
- data/lib/kward/transcript_export.rb +2 -0
- data/lib/kward/version.rb +2 -1
- data/lib/kward/workspace.rb +45 -5
- metadata +43 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 73a17b20e90d49d2bd6b3a7379e19e93bf21f44b14da57b572d34dc36068e49d
|
|
4
|
+
data.tar.gz: f521cd144677b097744b1e97913b47cb322760c526eee68c2b7262d57856c676
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 24b64b2f6a4ab6d7e3c9ac4d819994b3add061c8ef0d19ac164aed829b9160639ed9dde1e0b3a7ebaf478e8b2bb515ce8d5c13710ab4adb246f9e4929c85214b
|
|
7
|
+
data.tar.gz: 48ba9b202ac846fb98123edf732f9ec9e58bacfb63ac7e4e58b6e9f4dd4d9e04c5d0d096477344f494f9539a569e261d531ece9fa6d94d65fec41e57223819be
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,26 @@ All notable changes to Kward will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.68.0] - 2026-06-14
|
|
8
|
+
|
|
9
|
+
In this release, most changes are under the hood, as it included massive refactors to have an even more robust way forward.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added Anthropic Claude Pro/Max subscription provider support with OAuth login, static Claude model choices, and Anthropic Messages streaming.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Changed known context windows and reasoning effort choices to use provider/model-specific metadata for Codex, OpenRouter, Copilot, and Anthropic models.
|
|
18
|
+
- Changed the default Anthropic model to Claude Sonnet 4.6 and expanded direct Anthropic model choices to include newer Claude Opus/Sonnet releases.
|
|
19
|
+
- Changed resumed sessions to restore the session's last-used provider, model, and reasoning effort without rewriting default config.
|
|
20
|
+
- Documented the tool contract: schemas define strict generated/returned payloads, while runtime accepts tolerant incoming tool-call input for compatibility.
|
|
21
|
+
- Expanded RDoc coverage past 50% across message compatibility, tool-call normalization, session persistence, session tree helpers, model/client boundaries, config paths, workspace operations, telemetry, RPC, plugins, memory, auth, compaction, search internals, CLI mixins, and prompt interface components.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Fixed session tree editing and RPC fork text so prompt-template turns use the original visible slash command instead of expanded model content.
|
|
26
|
+
|
|
7
27
|
## [0.67.1] - 2026-06-14
|
|
8
28
|
|
|
9
29
|
### Fixed
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
kward (0.
|
|
4
|
+
kward (0.68.0)
|
|
5
5
|
base64
|
|
6
6
|
nokogiri
|
|
7
7
|
tiktoken_ruby
|
|
@@ -66,7 +66,7 @@ CHECKSUMS
|
|
|
66
66
|
date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0
|
|
67
67
|
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
68
68
|
erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9
|
|
69
|
-
kward (0.
|
|
69
|
+
kward (0.68.0)
|
|
70
70
|
minitest (6.0.6) sha256=153ea36d1d987a62942382b61075745042a2b3123b1cd48f4c3675af9cc7d6f1
|
|
71
71
|
nokogiri (1.19.3-arm64-darwin) sha256=71b9bd424b1b7abc18b05052a1a3cfd3627abdca62be280854cc411791357e42
|
|
72
72
|
pastel (0.8.0) sha256=481da9fb7d2f6e6b1a08faf11fa10363172dc40fd47848f096ae21209f805a75
|
data/README.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Kward is an extendable Ruby CLI coding agent. It can chat with you about a project, inspect and edit files, run confirmed shell commands, search the web, look up public source code, save local sessions, and load trusted Ruby plugins for custom workflows.
|
|
4
4
|
|
|
5
|
-
It currently supports the OpenAI/ChatGPT Codex backend, OpenRouter, and experimental Copilot provider support.
|
|
5
|
+
It currently supports the OpenAI/ChatGPT Codex backend, Anthropic Claude Pro/Max subscription, OpenRouter, and experimental Copilot provider support.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
|
-
Kward
|
|
9
|
+
Install Kward from RubyGems:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
gem install kward
|
|
@@ -54,8 +54,8 @@ exe/kward
|
|
|
54
54
|
## What Kward can do
|
|
55
55
|
|
|
56
56
|
- Keep a multi-turn coding conversation in your terminal.
|
|
57
|
-
- Read, write, and edit workspace files with
|
|
58
|
-
- Run shell commands
|
|
57
|
+
- Read, write, and edit workspace files with read-before-write guardrails.
|
|
58
|
+
- Run local shell commands from the workspace.
|
|
59
59
|
- Search the live web and inspect cached public GitHub repositories.
|
|
60
60
|
- Save, resume, clone, compact, and export sessions.
|
|
61
61
|
- Extend the Agent with trusted Ruby plugins for custom commands, footer UI, prompt context, and transcript-event observers.
|
|
@@ -69,7 +69,7 @@ Start here:
|
|
|
69
69
|
- [Getting started](doc/getting-started.md): first run, authentication choices, and basic commands.
|
|
70
70
|
- [Usage](doc/usage.md): interactive chat, slash commands, sessions, tools, images, and Pan mode.
|
|
71
71
|
- [Configuration](doc/configuration.md): config files, providers, models, web search, logging, and color output.
|
|
72
|
-
- [Authentication](doc/authentication.md): OpenAI OAuth, OpenRouter API keys, and Copilot/GitHub setup.
|
|
72
|
+
- [Authentication](doc/authentication.md): OpenAI OAuth, Anthropic OAuth, OpenRouter API keys, and Copilot/GitHub setup.
|
|
73
73
|
- [Troubleshooting](doc/troubleshooting.md): environment-specific install and runtime issues.
|
|
74
74
|
|
|
75
75
|
Feature guides:
|
data/doc/authentication.md
CHANGED
|
@@ -5,6 +5,7 @@ Kward needs credentials for a model provider before it can answer prompts. The e
|
|
|
5
5
|
Kward supports:
|
|
6
6
|
|
|
7
7
|
- OpenAI/ChatGPT OAuth for the Codex backend.
|
|
8
|
+
- Anthropic OAuth for Claude Pro/Max subscription support.
|
|
8
9
|
- OpenRouter API keys.
|
|
9
10
|
- GitHub OAuth or `COPILOT_GITHUB_TOKEN` for experimental Copilot provider support.
|
|
10
11
|
|
|
@@ -24,6 +25,7 @@ From your shell, you can also run:
|
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
27
|
kward login # OpenAI/ChatGPT OAuth
|
|
28
|
+
kward login anthropic # Anthropic Claude Pro/Max OAuth
|
|
27
29
|
kward login openrouter # save an OpenRouter API key
|
|
28
30
|
kward login github # GitHub OAuth for experimental Copilot support
|
|
29
31
|
```
|
|
@@ -58,6 +60,26 @@ OpenAI OAuth requires an OAuth client ID in `~/.kward/config.json`:
|
|
|
58
60
|
|
|
59
61
|
If it is missing, Kward tells you which config file to update.
|
|
60
62
|
|
|
63
|
+
## Anthropic OAuth
|
|
64
|
+
|
|
65
|
+
Anthropic OAuth uses your Claude Pro/Max subscription and sends requests to the Anthropic Messages API with Claude Code-compatible subscription headers. To start the browser login from your shell:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
kward login anthropic
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
In an interactive session, run `/login` and choose Anthropic.
|
|
72
|
+
|
|
73
|
+
Tokens are saved to:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
~/.kward/anthropic_auth.json
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The auth file is written with file mode `0600`. Kward refreshes the access token when the saved refresh token is available.
|
|
80
|
+
|
|
81
|
+
Important: Anthropic subscription access follows the same direct OAuth approach Pi uses for Claude Pro/Max. Subscription provider behavior may change upstream.
|
|
82
|
+
|
|
61
83
|
## OpenRouter API key
|
|
62
84
|
|
|
63
85
|
OpenRouter uses an API key rather than OAuth. To save it from your shell:
|
|
@@ -97,9 +119,10 @@ Important: Kward's Copilot provider follows Pi Agent's direct HTTPS approach. It
|
|
|
97
119
|
Credential priority is provider-aware:
|
|
98
120
|
|
|
99
121
|
- OpenAI OAuth is used by default after login, even when `OPENROUTER_API_KEY` or `openrouter_api_key` is also present.
|
|
122
|
+
- Anthropic OAuth is used when `provider` or `KWARD_PROVIDER` selects `anthropic` or `claude`.
|
|
100
123
|
- `OPENAI_ACCESS_TOKEN` can be used as an OpenAI environment fallback.
|
|
101
124
|
- `OPENROUTER_API_KEY` is a fallback only when no OpenAI OAuth/access token exists.
|
|
102
125
|
- `COPILOT_GITHUB_TOKEN` can be used as a Copilot environment fallback.
|
|
103
|
-
- If `provider` in config or `KWARD_PROVIDER` in the environment is set to `codex`, `openrouter`, or `copilot`, Kward uses that provider and does not fall through to another provider.
|
|
126
|
+
- If `provider` in config or `KWARD_PROVIDER` in the environment is set to `codex`, `anthropic`, `openrouter`, or `copilot`, Kward uses that provider and does not fall through to another provider.
|
|
104
127
|
|
|
105
128
|
See [Configuration](configuration.md) for model and provider settings.
|
data/doc/configuration.md
CHANGED
|
@@ -28,6 +28,7 @@ By default, Kward stores user data under `~/.kward`:
|
|
|
28
28
|
```text
|
|
29
29
|
~/.kward/config.json
|
|
30
30
|
~/.kward/auth.json
|
|
31
|
+
~/.kward/anthropic_auth.json
|
|
31
32
|
~/.kward/github_auth.json
|
|
32
33
|
~/.kward/sessions/
|
|
33
34
|
~/.kward/memory/
|
|
@@ -50,6 +51,7 @@ Set `provider` to choose the active backend:
|
|
|
50
51
|
Supported values are:
|
|
51
52
|
|
|
52
53
|
- `codex` for the OpenAI/ChatGPT Codex backend.
|
|
54
|
+
- `anthropic` for Anthropic Claude Pro/Max subscription support.
|
|
53
55
|
- `openrouter` for OpenRouter.
|
|
54
56
|
- `copilot` for experimental Copilot provider support.
|
|
55
57
|
|
|
@@ -60,21 +62,24 @@ Model settings:
|
|
|
60
62
|
"model": "gpt-5.5",
|
|
61
63
|
"openai_model": "gpt-5.5",
|
|
62
64
|
"openrouter_model": "openai/gpt-5.5",
|
|
65
|
+
"anthropic_model": "claude-sonnet-4-5",
|
|
63
66
|
"copilot_model": "gpt-5-mini",
|
|
64
67
|
"reasoning_effort": "medium",
|
|
65
68
|
"openai_reasoning_effort": "medium",
|
|
66
69
|
"openrouter_reasoning_effort": "medium",
|
|
70
|
+
"anthropic_reasoning_effort": "medium",
|
|
67
71
|
"copilot_reasoning_effort": "medium",
|
|
68
72
|
"thinking_level": "medium"
|
|
69
73
|
}
|
|
70
74
|
```
|
|
71
75
|
|
|
72
|
-
`model` is a generic setting for the active provider. Provider-specific values such as `openai_model`, `openrouter_model`, and `copilot_model` take precedence for their provider. `reasoning_effort` and `thinking_level` are generic reasoning settings. `openai_reasoning_effort`, `openrouter_reasoning_effort`, and `copilot_reasoning_effort` are provider-specific forms.
|
|
76
|
+
`model` is a generic setting for the active provider. Provider-specific values such as `openai_model`, `anthropic_model`, `openrouter_model`, and `copilot_model` take precedence for their provider. `reasoning_effort` and `thinking_level` are generic reasoning settings. `openai_reasoning_effort`, `anthropic_reasoning_effort`, `openrouter_reasoning_effort`, and `copilot_reasoning_effort` are provider-specific forms.
|
|
73
77
|
|
|
74
78
|
Defaults:
|
|
75
79
|
|
|
76
80
|
- OpenAI/Codex: `gpt-5.5`
|
|
77
81
|
- OpenRouter: `openai/gpt-5.5`
|
|
82
|
+
- Anthropic: `claude-sonnet-4-5`
|
|
78
83
|
- Copilot: `gpt-5-mini`
|
|
79
84
|
- Reasoning effort: `medium`
|
|
80
85
|
|
|
@@ -91,6 +96,8 @@ Provider and model:
|
|
|
91
96
|
- `OPENAI_REASONING_EFFORT`
|
|
92
97
|
- `OPENROUTER_MODEL`
|
|
93
98
|
- `OPENROUTER_REASONING_EFFORT`
|
|
99
|
+
- `ANTHROPIC_MODEL`
|
|
100
|
+
- `ANTHROPIC_REASONING_EFFORT`
|
|
94
101
|
- `COPILOT_MODEL`
|
|
95
102
|
- `COPILOT_REASONING_EFFORT`
|
|
96
103
|
|
|
@@ -122,7 +129,7 @@ Credential settings can also live in config:
|
|
|
122
129
|
}
|
|
123
130
|
```
|
|
124
131
|
|
|
125
|
-
Use environment variables for temporary or local-only secrets when possible. If
|
|
132
|
+
Use environment variables for temporary or local-only secrets when possible. If multiple credentials are available, OpenAI OAuth is used by default unless `provider` or `KWARD_PROVIDER` selects another backend such as `anthropic`, `openrouter`, or `copilot`.
|
|
126
133
|
|
|
127
134
|
## Overlay settings
|
|
128
135
|
|
data/doc/extensibility.md
CHANGED
|
@@ -23,7 +23,7 @@ Plugins are different: user plugins are loaded only from `~/.kward/plugins`, reg
|
|
|
23
23
|
The optional starter pack installs a useful base `AGENTS.md` and prompt templates. You can install it with:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
kward
|
|
26
|
+
kward init
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
## Agent instructions
|
data/doc/getting-started.md
CHANGED
|
@@ -12,7 +12,7 @@ This page gets you to a first working chat. For day-to-day features after that,
|
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
15
|
-
Kward
|
|
15
|
+
Install Kward from RubyGems:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
gem install kward
|
|
@@ -21,16 +21,16 @@ gem install kward
|
|
|
21
21
|
Optionally install the starter pack:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
kward
|
|
24
|
+
kward init
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
The starter pack adds useful default prompts and a base `AGENTS.md` to your config directory. It is helpful for a first setup, but safe to skip if you want to write your own instructions. Existing files are not overwritten.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
If you are working from a repository checkout:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
32
|
bundle install
|
|
33
|
-
ruby lib/main.rb
|
|
33
|
+
ruby lib/main.rb init # optional
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Start Kward and sign in
|
|
@@ -108,8 +108,6 @@ Kward saves interactive sessions under `~/.kward/sessions/`.
|
|
|
108
108
|
## Safety basics
|
|
109
109
|
|
|
110
110
|
- Kward must read an existing file in the current conversation before it can edit or overwrite it.
|
|
111
|
-
- File writes and edits ask for confirmation first.
|
|
112
|
-
- Shell commands ask for confirmation before running.
|
|
113
111
|
- Tool reads are bounded so large files are not accidentally loaded into context.
|
|
114
112
|
|
|
115
113
|
## Run tests
|
data/doc/plugins.md
CHANGED
|
@@ -24,8 +24,6 @@ Kward loads top-level Ruby files from:
|
|
|
24
24
|
|
|
25
25
|
Plugins are intentionally **not** loaded from the current workspace, from a project repository, or from a custom `KWARD_CONFIG_PATH` directory. This keeps plugin loading tied to the local user account rather than to whatever project Kward is currently inspecting.
|
|
26
26
|
|
|
27
|
-
If a legacy plugin directory exists beside a custom config path, Kward warns and ignores it.
|
|
28
|
-
|
|
29
27
|
## A first plugin
|
|
30
28
|
|
|
31
29
|
Create the plugin directory:
|
data/doc/releasing.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Releasing Kward
|
|
2
2
|
|
|
3
|
-
Release steps
|
|
3
|
+
Release steps before publishing:
|
|
4
4
|
|
|
5
5
|
1. Update `CHANGELOG.md` for the version.
|
|
6
6
|
2. Update `Kward::VERSION` in `lib/kward/version.rb`.
|
|
@@ -26,11 +26,10 @@ Release steps that can be completed before publishing:
|
|
|
26
26
|
6. Inspect the packaged files and confirm no local config, sessions, logs, or secrets are included.
|
|
27
27
|
7. Install the built gem locally and smoke test the `kward` executable.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Publish the built gem from the release checkout:
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
6. Push the built gem or publish through the trusted publishing workflow.
|
|
31
|
+
```bash
|
|
32
|
+
gem push kward-VERSION.gem
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
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.
|
data/doc/rpc.md
CHANGED
|
@@ -59,7 +59,7 @@ Detailed capability fields include:
|
|
|
59
59
|
- `models`: model/reasoning RPC methods, explicit OpenRouter catalog listing, exposed model fields, and no scoped model support.
|
|
60
60
|
- `runtime`: supported state/stats methods with message-count stats and OpenAI/Codex context usage. Cumulative token and cost stats are not computed.
|
|
61
61
|
- `runtimeSettings`: live `runtime/updateSetting` support for `defaultModel` and `defaultThinkingLevel`, plus `runtime/reload`.
|
|
62
|
-
- `auth`: Tauren auth provider format, OpenAI OAuth, OpenRouter API-key login, and provider logout for stored credentials.
|
|
62
|
+
- `auth`: Tauren auth provider format, OpenAI and Anthropic OAuth, OpenRouter API-key login, and provider logout for stored credentials.
|
|
63
63
|
- `memory`: opt-in structured memory support, interactive prompt injection only, JSON/JSONL local storage, and dedicated `memory/*` methods.
|
|
64
64
|
- `commands`: supported `commands/list` capability for prompt, skill, and plugin command sources, plus plugin execution through `commands/run` or plugin slash turns.
|
|
65
65
|
- `startupResources`: supported startup resource listing for context, skills, prompts, and plugins.
|
|
@@ -589,11 +589,11 @@ Updates config, including secret values, and returns a redacted config object. T
|
|
|
589
589
|
|
|
590
590
|
### `auth/status`
|
|
591
591
|
|
|
592
|
-
Returns whether OpenAI OAuth, OpenAI access token env, and OpenRouter API key env/config are available.
|
|
592
|
+
Returns whether OpenAI OAuth, Anthropic OAuth, OpenAI access token env, and OpenRouter API key env/config are available.
|
|
593
593
|
|
|
594
594
|
### `auth/providers`
|
|
595
595
|
|
|
596
|
-
Returns Tauren-compatible provider cards for OpenAI OAuth
|
|
596
|
+
Returns Tauren-compatible provider cards for OpenAI OAuth, Anthropic OAuth, OpenRouter API-key auth, and GitHub/Copilot status. Provider cards report whether credentials are configured, whether they came from stored config or environment variables, and whether stored credentials can be removed.
|
|
597
597
|
|
|
598
598
|
### `auth/loginWithApiKey`
|
|
599
599
|
|
|
@@ -608,7 +608,7 @@ Stores the API key with `0600` file permissions, refreshes client config, and re
|
|
|
608
608
|
|
|
609
609
|
Params:
|
|
610
610
|
|
|
611
|
-
- `providerId`: `openai` or `openrouter`.
|
|
611
|
+
- `providerId`: `openai`, `anthropic`, or `openrouter`.
|
|
612
612
|
|
|
613
613
|
Removes stored credentials only. Environment variables remain active and are still reported by `auth/providers`.
|
|
614
614
|
|
|
@@ -616,10 +616,10 @@ Removes stored credentials only. Environment variables remain active and are sti
|
|
|
616
616
|
|
|
617
617
|
Params:
|
|
618
618
|
|
|
619
|
-
- `providerId`: currently `openai`.
|
|
619
|
+
- `providerId`: currently `openai` or `anthropic`.
|
|
620
620
|
- `timeoutSeconds`: optional callback wait timeout.
|
|
621
621
|
|
|
622
|
-
Provider-scoped wrapper around the OpenAI OAuth flow. The result includes `providerId`, `loginId`, `authorizationUrl`, `redirectUri`, and `status`.
|
|
622
|
+
Provider-scoped wrapper around the OpenAI or Anthropic OAuth flow. The result includes `providerId`, `loginId`, `authorizationUrl`, `redirectUri`, and `status`.
|
|
623
623
|
|
|
624
624
|
### `auth/startOpenAILogin`
|
|
625
625
|
|
data/doc/usage.md
CHANGED
|
@@ -82,7 +82,7 @@ Kward can use these tools during a turn:
|
|
|
82
82
|
|
|
83
83
|
- `list_directory` and `read_file` to inspect the workspace.
|
|
84
84
|
- `write_file` and `edit_file` to create or change files.
|
|
85
|
-
- `run_shell_command` to run
|
|
85
|
+
- `run_shell_command` to run local commands from the workspace.
|
|
86
86
|
- `web_search` to search the live web.
|
|
87
87
|
- `code_search` to find packages, clone public GitHub repositories into cache, and read bounded source snippets.
|
|
88
88
|
- `ask_user_question` to ask structured clarification questions.
|
|
@@ -90,8 +90,11 @@ Kward can use these tools during a turn:
|
|
|
90
90
|
Safety rules:
|
|
91
91
|
|
|
92
92
|
- Existing files must be read in the current conversation before Kward can write or edit them.
|
|
93
|
-
- Every write, edit, and shell command asks for confirmation first.
|
|
94
93
|
- Text file reads and edits are capped at 256 KiB per file.
|
|
94
|
+
- Tool schemas are the official contract for generated tool calls and returned tool payloads.
|
|
95
|
+
- At runtime, Kward accepts tolerant incoming tool-call input for compatibility: extra fields are ignored, and existing legacy-compatible input shapes remain supported.
|
|
96
|
+
- Required fields and invalid required values still return explicit tool errors.
|
|
97
|
+
- Tool output payloads are kept schema-clean so future model calls and restored transcripts do not depend on accidental extra fields.
|
|
95
98
|
- When successful tool results include unified diffs, the composer status shows live session totals such as `+700|-572`.
|
|
96
99
|
|
|
97
100
|
## Slash commands
|
data/doc/web-search.md
CHANGED
|
@@ -15,7 +15,7 @@ The `web_search` tool is advertised by default so the agent can use current sour
|
|
|
15
15
|
1. Exa API when `EXA_API_KEY` is configured, otherwise keyless Exa MCP (`https://mcp.exa.ai/mcp`)
|
|
16
16
|
2. Perplexity API when configured and `allow_model_providers` is true
|
|
17
17
|
3. Gemini API with Google Search grounding when configured and `allow_model_providers` is true
|
|
18
|
-
4.
|
|
18
|
+
4. DuckDuckGo HTML search, then bundled public SearXNG instances
|
|
19
19
|
|
|
20
20
|
Queries are sent over the network to the selected provider. API keys are never bundled with Kward; configure your own keys only if you want higher limits or alternate providers. Set `web_search.enabled` to `false` to hide the tool. Direct `provider: perplexity` or `provider: gemini` requests still use those providers when keys are configured.
|
|
21
21
|
|
|
@@ -23,6 +23,6 @@ Supported arguments:
|
|
|
23
23
|
|
|
24
24
|
- `queries`: one to four search strings
|
|
25
25
|
- `max_results`: results per query, default 5, capped at 20
|
|
26
|
-
- `provider`: optional `auto`, `exa`, `perplexity`, `gemini`,
|
|
26
|
+
- `provider`: optional `auto`, `exa`, `perplexity`, `gemini`, or `duckduckgo`
|
|
27
27
|
- `recency_filter`: optional `day`, `week`, `month`, or `year`
|
|
28
28
|
- `domain_filter`: optional list of included domains, or excluded domains prefixed with `-`
|
data/kward.gemspec
CHANGED
|
@@ -13,6 +13,10 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.required_ruby_version = ">= 3.2"
|
|
14
14
|
|
|
15
15
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
16
|
+
spec.metadata["source_code_uri"] = "https://github.com/kaiwood/kward"
|
|
17
|
+
spec.metadata["changelog_uri"] = "https://github.com/kaiwood/kward/blob/main/CHANGELOG.md"
|
|
18
|
+
spec.metadata["documentation_uri"] = "https://github.com/kaiwood/kward#readme"
|
|
19
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/kaiwood/kward/issues"
|
|
16
20
|
|
|
17
21
|
spec.files = Dir.chdir(__dir__) do
|
|
18
22
|
`git ls-files -z`.split("\x0").reject do |file|
|
data/lib/kward/agent.rb
CHANGED
|
@@ -8,9 +8,21 @@ require_relative "steering"
|
|
|
8
8
|
require_relative "telemetry/logger"
|
|
9
9
|
require_relative "tools/registry"
|
|
10
10
|
|
|
11
|
+
# Namespace for the Kward CLI agent runtime.
|
|
11
12
|
module Kward
|
|
12
13
|
# Runs model turns, handles context compaction, dispatches tool calls, and
|
|
13
14
|
# streams high-level events back to CLI and RPC callers.
|
|
15
|
+
#
|
|
16
|
+
# `Agent` is the main turn orchestrator. It should know what a turn means:
|
|
17
|
+
# append the user's input, call the model, persist assistant/tool messages,
|
|
18
|
+
# retry once after recoverable context overflow, apply in-flight steering, and
|
|
19
|
+
# emit frontend-neutral `Events::*` objects. It should not know terminal or RPC
|
|
20
|
+
# rendering details; callers translate events into their own UI protocol.
|
|
21
|
+
#
|
|
22
|
+
# Tool implementations own local side effects. `Client` owns provider HTTP
|
|
23
|
+
# details. `Conversation` owns transcript state. Keep future changes in the
|
|
24
|
+
# lowest layer that owns the behavior, and use `Agent` only for cross-step turn
|
|
25
|
+
# coordination.
|
|
14
26
|
class Agent
|
|
15
27
|
def initialize(client:, tool_registry: ToolRegistry.new, conversation: Conversation.new, telemetry_logger: TelemetryLogger.new)
|
|
16
28
|
@client = client
|
|
@@ -67,6 +79,7 @@ module Kward
|
|
|
67
79
|
overflow_retried = true
|
|
68
80
|
next
|
|
69
81
|
end
|
|
82
|
+
update_conversation_runtime(message)
|
|
70
83
|
yield Events::AssistantMessage.new(message: message) if block_given?
|
|
71
84
|
@conversation.append_assistant(message)
|
|
72
85
|
steered_after_message = append_steering_events(steering_state)
|
|
@@ -207,11 +220,25 @@ module Kward
|
|
|
207
220
|
on_assistant_delta: assistant_delta,
|
|
208
221
|
on_retry: retry_callback,
|
|
209
222
|
cancellation: cancellation,
|
|
210
|
-
steering: steering
|
|
223
|
+
steering: steering,
|
|
224
|
+
provider: @conversation.provider,
|
|
225
|
+
model: @conversation.model,
|
|
226
|
+
reasoning: @conversation.reasoning_effort
|
|
211
227
|
}
|
|
212
228
|
)
|
|
213
229
|
end
|
|
214
230
|
|
|
231
|
+
def update_conversation_runtime(message)
|
|
232
|
+
return unless message.is_a?(Hash)
|
|
233
|
+
|
|
234
|
+
provider = message["provider"] || message[:provider]
|
|
235
|
+
model = message["model"] || message[:model]
|
|
236
|
+
return if provider.to_s.empty? || model.to_s.empty?
|
|
237
|
+
|
|
238
|
+
@conversation.update_runtime_context!(provider: provider, model: model, reasoning_effort: @conversation.reasoning_effort)
|
|
239
|
+
@conversation.persist_runtime_context!
|
|
240
|
+
end
|
|
241
|
+
|
|
215
242
|
def safe_answer(content)
|
|
216
243
|
text = content.to_s
|
|
217
244
|
return text unless claims_file_edit?(text)
|
|
@@ -222,7 +249,7 @@ module Kward
|
|
|
222
249
|
end
|
|
223
250
|
|
|
224
251
|
def claims_file_edit?(text)
|
|
225
|
-
text.match?(/\b(I|I've|I have)\s+(changed|updated|modified|edited|created|deleted|wrote)\b/i)
|
|
252
|
+
text.match?(/\b(?:I|I've|I have)\s+(?:changed|updated|modified|edited|created|deleted|wrote)\s+(?:the\s+)?(?:file|files|[\w.\/-]+\.[\w-]+)\b/i)
|
|
226
253
|
end
|
|
227
254
|
|
|
228
255
|
def last_file_change_succeeded?
|
data/lib/kward/ansi.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
# Namespace for the Kward CLI agent runtime.
|
|
1
2
|
module Kward
|
|
3
|
+
# ANSI color and terminal capability helpers.
|
|
2
4
|
module ANSI
|
|
3
5
|
ESCAPE_PATTERN = /\e\[[0-9;?]*[ -\/]*[@-~]/.freeze
|
|
4
6
|
SGR_PATTERN = /\e\[[0-9;:]*m/.freeze
|
|
@@ -125,6 +127,7 @@ module Kward
|
|
|
125
127
|
rendered.join("\n") + (string.end_with?("\n") ? "\n" : "")
|
|
126
128
|
end
|
|
127
129
|
|
|
130
|
+
# String wrapper that strips ANSI escape sequences while preserving visible text operations.
|
|
128
131
|
class MarkdownStream
|
|
129
132
|
def initialize(enabled: ANSI.enabled?)
|
|
130
133
|
@enabled = enabled
|