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.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile.lock +2 -2
  4. data/README.md +5 -5
  5. data/doc/authentication.md +24 -1
  6. data/doc/configuration.md +9 -2
  7. data/doc/extensibility.md +1 -1
  8. data/doc/getting-started.md +4 -6
  9. data/doc/plugins.md +0 -2
  10. data/doc/releasing.md +7 -8
  11. data/doc/rpc.md +6 -6
  12. data/doc/usage.md +5 -2
  13. data/doc/web-search.md +2 -2
  14. data/kward.gemspec +4 -0
  15. data/lib/kward/agent.rb +29 -2
  16. data/lib/kward/ansi.rb +3 -0
  17. data/lib/kward/auth/anthropic_oauth.rb +291 -0
  18. data/lib/kward/auth/file.rb +2 -0
  19. data/lib/kward/auth/github_oauth.rb +3 -0
  20. data/lib/kward/auth/openai_oauth.rb +4 -0
  21. data/lib/kward/auth/openrouter_api_key.rb +2 -0
  22. data/lib/kward/cancellation.rb +3 -0
  23. data/lib/kward/cli/auth_commands.rb +82 -0
  24. data/lib/kward/cli/commands.rb +222 -0
  25. data/lib/kward/cli/compaction.rb +25 -0
  26. data/lib/kward/cli/doctor.rb +121 -0
  27. data/lib/kward/cli/interactive_turn.rb +225 -0
  28. data/lib/kward/cli/memory_commands.rb +133 -0
  29. data/lib/kward/cli/plugins.rb +112 -0
  30. data/lib/kward/cli/prompt_interface.rb +132 -0
  31. data/lib/kward/cli/rendering.rb +389 -0
  32. data/lib/kward/cli/runtime_helpers.rb +159 -0
  33. data/lib/kward/cli/sessions.rb +376 -0
  34. data/lib/kward/cli/settings.rb +663 -0
  35. data/lib/kward/cli/slash_commands.rb +112 -0
  36. data/lib/kward/cli/stats.rb +64 -0
  37. data/lib/kward/cli/tool_summaries.rb +153 -0
  38. data/lib/kward/cli.rb +38 -2790
  39. data/lib/kward/cli_transcript_formatter.rb +4 -7
  40. data/lib/kward/clipboard.rb +1 -0
  41. data/lib/kward/compaction/file_operation_tracker.rb +3 -0
  42. data/lib/kward/compactor.rb +29 -7
  43. data/lib/kward/config_files.rb +33 -24
  44. data/lib/kward/conversation.rb +70 -5
  45. data/lib/kward/events.rb +2 -0
  46. data/lib/kward/export_path.rb +2 -0
  47. data/lib/kward/image_attachments.rb +2 -0
  48. data/lib/kward/markdown_transcript.rb +2 -0
  49. data/lib/kward/memory/manager.rb +13 -0
  50. data/lib/kward/message_access.rb +23 -2
  51. data/lib/kward/message_text.rb +45 -0
  52. data/lib/kward/model/chat_invocation.rb +2 -0
  53. data/lib/kward/model/client.rb +295 -77
  54. data/lib/kward/model/context_overflow.rb +2 -0
  55. data/lib/kward/model/context_usage.rb +3 -0
  56. data/lib/kward/model/model_info.rb +143 -4
  57. data/lib/kward/model/payloads.rb +166 -13
  58. data/lib/kward/model/retry_message.rb +2 -0
  59. data/lib/kward/model/stream_parser.rb +129 -0
  60. data/lib/kward/pan/server.rb +3 -1
  61. data/lib/kward/plugin_registry.rb +12 -0
  62. data/lib/kward/private_file.rb +2 -0
  63. data/lib/kward/prompt_interface/banner.rb +3 -0
  64. data/lib/kward/prompt_interface/composer_controller.rb +262 -0
  65. data/lib/kward/prompt_interface/composer_renderer.rb +172 -0
  66. data/lib/kward/prompt_interface/composer_state.rb +221 -0
  67. data/lib/kward/prompt_interface/key_handler.rb +365 -0
  68. data/lib/kward/prompt_interface/layout.rb +31 -0
  69. data/lib/kward/prompt_interface/overlay_renderer.rb +111 -0
  70. data/lib/kward/prompt_interface/prompt_renderer.rb +91 -0
  71. data/lib/kward/prompt_interface/question_prompt.rb +328 -0
  72. data/lib/kward/prompt_interface/runtime_state.rb +59 -0
  73. data/lib/kward/prompt_interface/screen.rb +186 -0
  74. data/lib/kward/prompt_interface/selection_prompt.rb +242 -0
  75. data/lib/kward/prompt_interface/slash_overlay.rb +102 -0
  76. data/lib/kward/prompt_interface/stream_state.rb +65 -0
  77. data/lib/kward/prompt_interface/transcript_buffer.rb +85 -0
  78. data/lib/kward/prompt_interface/transcript_renderer.rb +142 -0
  79. data/lib/kward/prompt_interface.rb +69 -1832
  80. data/lib/kward/prompts/commands.rb +2 -0
  81. data/lib/kward/prompts/templates.rb +3 -0
  82. data/lib/kward/prompts.rb +2 -0
  83. data/lib/kward/question_contract.rb +66 -0
  84. data/lib/kward/resources/avatar_kward_logo.rb +2 -0
  85. data/lib/kward/resources/pixel_logo.rb +2 -0
  86. data/lib/kward/rpc/attachment_normalizer.rb +60 -0
  87. data/lib/kward/rpc/auth_manager.rb +65 -11
  88. data/lib/kward/rpc/config_manager.rb +11 -0
  89. data/lib/kward/rpc/prompt_bridge.rb +5 -26
  90. data/lib/kward/rpc/redactor.rb +3 -0
  91. data/lib/kward/rpc/runtime_payloads.rb +4 -1
  92. data/lib/kward/rpc/server.rb +36 -9
  93. data/lib/kward/rpc/session_manager.rb +121 -345
  94. data/lib/kward/rpc/session_metrics.rb +68 -0
  95. data/lib/kward/rpc/session_tree.rb +48 -0
  96. data/lib/kward/rpc/session_tree_rows.rb +208 -0
  97. data/lib/kward/rpc/tool_event_normalizer.rb +3 -0
  98. data/lib/kward/rpc/tool_metadata.rb +3 -0
  99. data/lib/kward/rpc/transcript_normalizer.rb +3 -0
  100. data/lib/kward/rpc/transport.rb +3 -0
  101. data/lib/kward/session_diff.rb +2 -0
  102. data/lib/kward/session_store.rb +114 -24
  103. data/lib/kward/session_trash.rb +1 -0
  104. data/lib/kward/session_tree_renderer.rb +8 -41
  105. data/lib/kward/session_tree_tool_display.rb +56 -0
  106. data/lib/kward/skills/registry.rb +3 -0
  107. data/lib/kward/starter_pack_installer.rb +1 -0
  108. data/lib/kward/steering.rb +2 -0
  109. data/lib/kward/telemetry/logger.rb +3 -0
  110. data/lib/kward/telemetry/stats.rb +3 -0
  111. data/lib/kward/tools/ask_user_question.rb +20 -32
  112. data/lib/kward/tools/base.rb +8 -0
  113. data/lib/kward/tools/code_search.rb +5 -0
  114. data/lib/kward/tools/edit_file.rb +5 -0
  115. data/lib/kward/tools/list_directory.rb +5 -0
  116. data/lib/kward/tools/read_file.rb +5 -0
  117. data/lib/kward/tools/read_skill.rb +5 -0
  118. data/lib/kward/tools/registry.rb +33 -2
  119. data/lib/kward/tools/run_shell_command.rb +5 -0
  120. data/lib/kward/tools/search/code.rb +7 -0
  121. data/lib/kward/tools/search/web.rb +17 -14
  122. data/lib/kward/tools/tool_call.rb +25 -5
  123. data/lib/kward/tools/web_search.rb +7 -1
  124. data/lib/kward/tools/write_file.rb +5 -0
  125. data/lib/kward/transcript_export.rb +2 -0
  126. data/lib/kward/version.rb +2 -1
  127. data/lib/kward/workspace.rb +45 -5
  128. metadata +43 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d03a2b137c3ef3a1bc27e44b2629de49a41c70c3044088f9bd0c162cf50e3387
4
- data.tar.gz: 241753e7eca9acb6ff94cae50afa7ea43ea2e4c13a8d22eb5031d399ae7fad5a
3
+ metadata.gz: 73a17b20e90d49d2bd6b3a7379e19e93bf21f44b14da57b572d34dc36068e49d
4
+ data.tar.gz: f521cd144677b097744b1e97913b47cb322760c526eee68c2b7262d57856c676
5
5
  SHA512:
6
- metadata.gz: ac0d8465faa573ac9878c4bf5b83327145a7810cbe375b64ce8019531ba00ea3be779a82ed912825de2372ba18917dc56137f67f60161d3234e396b6ec82f3a2
7
- data.tar.gz: 3e50a23badb84faf825a75cec5f9d0f4b62cc2bb0c76d643ac8bfb41d99a97c0cbc95268508e4b8a0c2e172249d105f3246b8b0e6a44c81725eae52db71235e6
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.67.1)
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.67.1)
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 is being prepared for a RubyGems release. Once published, install it with:
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 confirmation before changes.
58
- - Run shell commands after confirmation.
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:
@@ -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 both OpenAI and OpenRouter credentials are available, OpenAI OAuth is used by default unless `provider` or `KWARD_PROVIDER` selects another backend.
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 --install-starter-pack
26
+ kward init
27
27
  ```
28
28
 
29
29
  ## Agent instructions
@@ -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 is being prepared for a RubyGems release. Once published:
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 --install-starter-pack
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
- Until the gem is published, run Kward from a repository checkout:
29
+ If you are working from a repository checkout:
30
30
 
31
31
  ```bash
32
32
  bundle install
33
- ruby lib/main.rb --install-starter-pack # optional
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 that can be completed before publishing:
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
- RubyGems setup before the first public release:
29
+ Publish the built gem from the release checkout:
30
30
 
31
- 1. Create or sign in to a RubyGems.org account.
32
- 2. Enable multi-factor authentication for the account.
33
- 3. Confirm the `kward` gem name is available.
34
- 4. Add final homepage, source code, changelog, documentation, and bug tracker metadata to `kward.gemspec` once the public repository URLs are final.
35
- 5. Prefer RubyGems trusted publishing for automated releases so long-lived API keys do not need to be stored in CI secrets.
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 and OpenRouter API-key auth. Provider cards report whether credentials are configured, whether they came from stored config or environment variables, and whether stored credentials can be removed.
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 confirmed local commands.
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. Legacy DuckDuckGo HTML search, then bundled public SearXNG instances
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`, `legacy`, or `duckduckgo`
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