kward 0.73.1 → 0.75.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 +51 -0
- data/Gemfile.lock +2 -2
- data/README.md +4 -2
- data/Rakefile +18 -0
- data/doc/configuration.md +70 -4
- data/doc/extensibility.md +6 -19
- data/doc/getting-started.md +1 -1
- data/doc/lifecycle-hooks.md +424 -0
- data/doc/mcp.md +72 -0
- data/doc/memory.md +1 -1
- data/doc/personas.md +2 -2
- data/doc/plugins.md +1 -1
- data/doc/releasing.md +7 -15
- data/doc/rpc.md +108 -15
- data/doc/session-management.md +9 -9
- data/doc/skills.md +199 -0
- data/doc/usage.md +14 -7
- data/lib/kward/agent.rb +72 -22
- data/lib/kward/auth/anthropic_oauth.rb +5 -87
- data/lib/kward/auth/oauth_helpers.rb +105 -0
- data/lib/kward/auth/openai_oauth.rb +4 -86
- data/lib/kward/cli/commands.rb +12 -2
- data/lib/kward/cli/compaction.rb +7 -0
- data/lib/kward/cli/doctor.rb +18 -10
- data/lib/kward/cli/git.rb +30 -3
- data/lib/kward/cli/hook_commands.rb +258 -0
- data/lib/kward/cli/interactive_turn.rb +9 -3
- data/lib/kward/cli/memory_commands.rb +1 -5
- data/lib/kward/cli/plugins.rb +41 -1
- data/lib/kward/cli/prompt_interface.rb +32 -3
- data/lib/kward/cli/rendering.rb +1 -1
- data/lib/kward/cli/runtime_helpers.rb +44 -5
- data/lib/kward/cli/sessions.rb +13 -0
- data/lib/kward/cli/settings.rb +226 -152
- data/lib/kward/cli/slash_commands.rb +81 -42
- data/lib/kward/cli/tabs.rb +32 -15
- data/lib/kward/cli.rb +64 -4
- data/lib/kward/cli_transcript_formatter.rb +0 -7
- data/lib/kward/compaction/token_estimator.rb +112 -0
- data/lib/kward/compactor.rb +42 -116
- data/lib/kward/config_files.rb +152 -27
- data/lib/kward/deep_copy.rb +42 -0
- data/lib/kward/diff_view_mode.rb +36 -0
- data/lib/kward/events.rb +1 -0
- data/lib/kward/export_path.rb +2 -6
- data/lib/kward/frontmatter.rb +43 -0
- data/lib/kward/hooks/audit_log.rb +121 -0
- data/lib/kward/hooks/catalog.rb +110 -0
- data/lib/kward/hooks/command_handler.rb +66 -0
- data/lib/kward/hooks/config_loader.rb +104 -0
- data/lib/kward/hooks/decision.rb +102 -0
- data/lib/kward/hooks/event.rb +60 -0
- data/lib/kward/hooks/http_handler.rb +72 -0
- data/lib/kward/hooks/manager.rb +158 -0
- data/lib/kward/hooks/matcher.rb +75 -0
- data/lib/kward/hooks.rb +16 -0
- data/lib/kward/markdown_transcript.rb +4 -3
- data/lib/kward/mcp/client.rb +56 -0
- data/lib/kward/mcp/server_config.rb +59 -0
- data/lib/kward/mcp/stdio_transport.rb +112 -0
- data/lib/kward/memory/turn_context.rb +19 -0
- data/lib/kward/message_access.rb +2 -2
- data/lib/kward/message_text.rb +19 -0
- data/lib/kward/model/client.rb +13 -45
- data/lib/kward/model/context_usage.rb +10 -4
- data/lib/kward/model/copilot_models.rb +44 -0
- data/lib/kward/model/model_info.rb +24 -0
- data/lib/kward/model/payloads.rb +15 -17
- data/lib/kward/model/stream_parser.rb +178 -13
- data/lib/kward/pan/server.rb +51 -2
- data/lib/kward/path_guard.rb +13 -0
- data/lib/kward/plugin_registry.rb +86 -25
- data/lib/kward/prompt_interface/editor/controller.rb +124 -4
- data/lib/kward/prompt_interface/editor/modes/emacs.rb +4 -0
- data/lib/kward/prompt_interface/editor/modes/modern.rb +10 -4
- data/lib/kward/prompt_interface/editor/modes/vibe.rb +448 -20
- data/lib/kward/prompt_interface/editor/renderer.rb +27 -0
- data/lib/kward/prompt_interface/editor/search.rb +70 -13
- data/lib/kward/prompt_interface/editor/state.rb +72 -13
- data/lib/kward/prompt_interface/editor/vibe_state.rb +12 -1
- data/lib/kward/prompt_interface/selection_prompt.rb +26 -6
- data/lib/kward/prompt_interface.rb +4 -1
- data/lib/kward/prompts/commands.rb +3 -3
- data/lib/kward/prompts.rb +7 -7
- data/lib/kward/rpc/mcp_status.rb +50 -0
- data/lib/kward/rpc/prompt_bridge.rb +38 -4
- data/lib/kward/rpc/runtime_payloads.rb +1 -1
- data/lib/kward/rpc/server.rb +94 -13
- data/lib/kward/rpc/session_manager.rb +258 -33
- data/lib/kward/rpc/session_metrics.rb +1 -1
- data/lib/kward/rpc/session_tree_rows.rb +13 -64
- data/lib/kward/rpc/tool_event_normalizer.rb +16 -2
- data/lib/kward/rpc/transcript_normalizer.rb +9 -10
- data/lib/kward/rpc/turn_context.rb +109 -0
- data/lib/kward/session_store.rb +6 -20
- data/lib/kward/session_tree_nodes.rb +98 -18
- data/lib/kward/session_tree_renderer.rb +6 -61
- data/lib/kward/skills/registry.rb +109 -17
- data/lib/kward/tools/mcp_tool.rb +122 -0
- data/lib/kward/tools/read_skill.rb +9 -4
- data/lib/kward/tools/registry.rb +297 -9
- data/lib/kward/tools/search/code.rb +4 -22
- data/lib/kward/tools/search/web.rb +28 -2
- data/lib/kward/update_check.rb +117 -0
- data/lib/kward/version.rb +1 -1
- data/lib/kward/workers/manager.rb +43 -3
- data/lib/kward/workspace.rb +3 -1
- data/templates/default/fulldoc/html/css/kward.css +22 -0
- data/templates/default/fulldoc/html/js/kward.js +2 -0
- data/templates/default/kward_navigation.rb +4 -2
- data/templates/default/layout/html/setup.rb +2 -0
- metadata +30 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "json"
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "time"
|
|
5
|
+
require "uri"
|
|
6
|
+
|
|
7
|
+
# Namespace for the Kward CLI agent runtime.
|
|
8
|
+
module Kward
|
|
9
|
+
# Cached RubyGems update check for the interactive startup screen.
|
|
10
|
+
class UpdateCheck
|
|
11
|
+
CHECK_INTERVAL_SECONDS = 24 * 60 * 60
|
|
12
|
+
LATEST_VERSION_URL = URI("https://rubygems.org/api/v1/versions/kward/latest.json")
|
|
13
|
+
|
|
14
|
+
Notice = Struct.new(:latest_version, keyword_init: true)
|
|
15
|
+
|
|
16
|
+
def initialize(current_version:, config: ConfigFiles.read_config, path: ConfigFiles.update_check_cache_path, now: Time.now)
|
|
17
|
+
@current_version = current_version.to_s
|
|
18
|
+
@config = config
|
|
19
|
+
@path = path
|
|
20
|
+
@now = now
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def enabled?
|
|
24
|
+
return false if disabled_by_environment?
|
|
25
|
+
|
|
26
|
+
updates = @config["updates"]
|
|
27
|
+
return false if updates.is_a?(Hash) && updates["check"] == false
|
|
28
|
+
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def notice
|
|
33
|
+
return nil unless enabled?
|
|
34
|
+
|
|
35
|
+
latest_version = cache["latest_version"].to_s
|
|
36
|
+
return nil if latest_version.empty?
|
|
37
|
+
return nil if dismissed_version == latest_version
|
|
38
|
+
return nil unless newer_than_current?(latest_version)
|
|
39
|
+
|
|
40
|
+
Notice.new(latest_version: latest_version)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def refresh_if_stale
|
|
44
|
+
return false unless enabled?
|
|
45
|
+
return false unless stale?
|
|
46
|
+
|
|
47
|
+
refresh
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def refresh
|
|
51
|
+
latest_version = fetch_latest_version
|
|
52
|
+
write_cache(cache.merge(
|
|
53
|
+
"checked_at" => @now.utc.iso8601,
|
|
54
|
+
"latest_version" => latest_version
|
|
55
|
+
))
|
|
56
|
+
true
|
|
57
|
+
rescue StandardError
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def disabled_by_environment?
|
|
64
|
+
value = ENV["KWARD_DISABLE_UPDATE_CHECK"].to_s.strip.downcase
|
|
65
|
+
["1", "true", "yes", "on"].include?(value)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def dismissed_version
|
|
69
|
+
cache["dismissed_version"].to_s
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def stale?
|
|
73
|
+
checked_at = Time.iso8601(cache["checked_at"].to_s)
|
|
74
|
+
(@now - checked_at) >= CHECK_INTERVAL_SECONDS
|
|
75
|
+
rescue ArgumentError, TypeError
|
|
76
|
+
true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def cache
|
|
80
|
+
@cache ||= read_cache
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def read_cache
|
|
84
|
+
return {} unless File.file?(@path)
|
|
85
|
+
|
|
86
|
+
data = JSON.parse(File.read(@path))
|
|
87
|
+
data.is_a?(Hash) ? data : {}
|
|
88
|
+
rescue JSON::ParserError, SystemCallError
|
|
89
|
+
{}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def write_cache(data)
|
|
93
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
|
94
|
+
File.write(@path, JSON.pretty_generate(data) + "\n")
|
|
95
|
+
@cache = data
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def fetch_latest_version
|
|
99
|
+
request = Net::HTTP::Get.new(LATEST_VERSION_URL)
|
|
100
|
+
request["User-Agent"] = "kward/#{Kward::VERSION}"
|
|
101
|
+
response = Net::HTTP.start(LATEST_VERSION_URL.hostname, LATEST_VERSION_URL.port, use_ssl: true, open_timeout: 2, read_timeout: 2) do |http|
|
|
102
|
+
http.request(request)
|
|
103
|
+
end
|
|
104
|
+
return "" unless response.is_a?(Net::HTTPSuccess)
|
|
105
|
+
|
|
106
|
+
JSON.parse(response.body)["version"].to_s
|
|
107
|
+
rescue JSON::ParserError
|
|
108
|
+
""
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def newer_than_current?(version)
|
|
112
|
+
Gem::Version.new(version) > Gem::Version.new(@current_version)
|
|
113
|
+
rescue ArgumentError
|
|
114
|
+
false
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/kward/version.rb
CHANGED
|
@@ -2,6 +2,7 @@ require "timeout"
|
|
|
2
2
|
require_relative "../agent"
|
|
3
3
|
require_relative "../cancellation"
|
|
4
4
|
require_relative "../conversation"
|
|
5
|
+
require_relative "../hooks"
|
|
5
6
|
require_relative "../model/client"
|
|
6
7
|
require_relative "../session_store"
|
|
7
8
|
require_relative "../tools/registry"
|
|
@@ -16,7 +17,7 @@ module Kward
|
|
|
16
17
|
class Manager
|
|
17
18
|
DEFAULT_TIMEOUT_SECONDS = 180
|
|
18
19
|
|
|
19
|
-
def initialize(client_factory: -> { Client.new }, prompt: nil, workspace_root: Dir.pwd, timeout_seconds: DEFAULT_TIMEOUT_SECONDS, on_status_change: nil, session_store: nil, provider: nil, model: nil, reasoning_effort: nil, write_lock: nil, worker_store: nil, git_guard: nil, write_lane_available: -> { true })
|
|
20
|
+
def initialize(client_factory: -> { Client.new }, prompt: nil, workspace_root: Dir.pwd, timeout_seconds: DEFAULT_TIMEOUT_SECONDS, on_status_change: nil, session_store: nil, provider: nil, model: nil, reasoning_effort: nil, write_lock: nil, worker_store: nil, git_guard: nil, write_lane_available: -> { true }, hook_manager: nil, hook_context: nil)
|
|
20
21
|
@client_factory = client_factory
|
|
21
22
|
@prompt = prompt
|
|
22
23
|
@workspace_root = ConfigFiles.canonical_workspace_root(workspace_root)
|
|
@@ -30,12 +31,15 @@ module Kward
|
|
|
30
31
|
@worker_store = worker_store
|
|
31
32
|
@git_guard = git_guard || GitGuard.new(root: @workspace_root)
|
|
32
33
|
@write_lane_available = write_lane_available
|
|
34
|
+
@hook_manager = hook_manager
|
|
35
|
+
@hook_context = hook_context
|
|
33
36
|
@workers = {}
|
|
34
37
|
@mutex = Mutex.new
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
def start(role:, prompt:, title: nil, id: nil)
|
|
38
41
|
worker = build_worker(role: role, prompt: prompt, title: title, id: id)
|
|
42
|
+
run_blocking_hook("worker_job_create", worker)
|
|
39
43
|
enqueue(worker)
|
|
40
44
|
end
|
|
41
45
|
|
|
@@ -105,15 +109,19 @@ module Kward
|
|
|
105
109
|
worker.conversation = conversation
|
|
106
110
|
attach_session(worker, conversation)
|
|
107
111
|
writer_id = wait_for_worker_writer(worker)
|
|
112
|
+
run_blocking_hook("worker_job_start_before", worker)
|
|
108
113
|
update_status(worker, "running")
|
|
114
|
+
run_hook("worker_job_start_after", worker)
|
|
109
115
|
registry = ToolRegistry.new(
|
|
110
116
|
workspace: Workspace.new(root: worker.workspace_root),
|
|
111
117
|
prompt: @prompt,
|
|
112
118
|
allowed_tool_names: ToolPolicy.allowed_tool_names(worker.role),
|
|
113
119
|
write_lock: @write_lock,
|
|
114
|
-
writer_id: writer_id
|
|
120
|
+
writer_id: writer_id,
|
|
121
|
+
hook_manager: @hook_manager,
|
|
122
|
+
hook_context: @hook_context
|
|
115
123
|
)
|
|
116
|
-
agent = Agent.new(client: @client_factory.call, tool_registry: registry, conversation: conversation)
|
|
124
|
+
agent = Agent.new(client: @client_factory.call, tool_registry: registry, conversation: conversation, hook_manager: @hook_manager, hook_context: @hook_context)
|
|
117
125
|
report = Timeout.timeout(@timeout_seconds, WorkerTimeoutError) do
|
|
118
126
|
agent.ask(worker_prompt(worker), cancellation: worker.cancellation) do |event|
|
|
119
127
|
worker.record_event(event)
|
|
@@ -121,16 +129,48 @@ module Kward
|
|
|
121
129
|
end
|
|
122
130
|
report = finalize_write_worker(worker, report)
|
|
123
131
|
update_status(worker, "ready", report: report, error: "")
|
|
132
|
+
run_hook("worker_job_ready_for_review", worker)
|
|
124
133
|
rescue WorkerTimeoutError
|
|
125
134
|
update_status(worker, "failed", error: "Worker timed out after #{@timeout_seconds} seconds")
|
|
135
|
+
run_hook("worker_job_failed", worker, error: "Worker timed out after #{@timeout_seconds} seconds")
|
|
126
136
|
rescue Cancellation::CancelledError
|
|
127
137
|
update_status(worker, "cancelled")
|
|
128
138
|
rescue StandardError => e
|
|
129
139
|
update_status(worker, "failed", error: e.message)
|
|
140
|
+
run_hook("worker_job_failed", worker, error: e.message)
|
|
130
141
|
ensure
|
|
131
142
|
release_worker_writer(worker)
|
|
132
143
|
end
|
|
133
144
|
|
|
145
|
+
def run_blocking_hook(name, worker, payload = {})
|
|
146
|
+
result = run_hook(name, worker, payload)
|
|
147
|
+
return result unless result && !result.allowed?
|
|
148
|
+
|
|
149
|
+
raise HookDenied, result.decision.message || "Worker lifecycle hook #{name} blocked the job"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def run_hook(name, worker, payload = {})
|
|
153
|
+
return unless @hook_manager
|
|
154
|
+
|
|
155
|
+
@hook_manager.run(Hooks::Event.new(
|
|
156
|
+
name: name,
|
|
157
|
+
workspace: { root: worker.workspace_root },
|
|
158
|
+
payload: worker_payload(worker).merge(payload)
|
|
159
|
+
), context: @hook_context)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
HookDenied = Class.new(StandardError)
|
|
163
|
+
|
|
164
|
+
def worker_payload(worker)
|
|
165
|
+
{
|
|
166
|
+
worker_id: worker.id,
|
|
167
|
+
role: worker.role,
|
|
168
|
+
title: worker.title,
|
|
169
|
+
status: worker.status,
|
|
170
|
+
session_path: worker.session&.path
|
|
171
|
+
}.compact
|
|
172
|
+
end
|
|
173
|
+
|
|
134
174
|
def update_status(worker, status, **values)
|
|
135
175
|
return worker if worker.status == "archived" && status.to_s != "archived"
|
|
136
176
|
|
data/lib/kward/workspace.rb
CHANGED
|
@@ -2,6 +2,8 @@ require "pathname"
|
|
|
2
2
|
require_relative "local_command_runner"
|
|
3
3
|
require_relative "session_diff"
|
|
4
4
|
|
|
5
|
+
require_relative "path_guard"
|
|
6
|
+
|
|
5
7
|
# Namespace for the Kward CLI agent runtime.
|
|
6
8
|
module Kward
|
|
7
9
|
# Filesystem and shell-command boundary for workspace tools.
|
|
@@ -212,7 +214,7 @@ module Kward
|
|
|
212
214
|
end
|
|
213
215
|
|
|
214
216
|
def inside_workspace?(path)
|
|
215
|
-
|
|
217
|
+
PathGuard.inside?(path, @root)
|
|
216
218
|
end
|
|
217
219
|
|
|
218
220
|
def relative_path(path)
|
|
@@ -1030,6 +1030,21 @@ body.kward-docs .kward-home #footer p {
|
|
|
1030
1030
|
}
|
|
1031
1031
|
|
|
1032
1032
|
@media (max-width: 620px) {
|
|
1033
|
+
.kward-hero > *,
|
|
1034
|
+
.kward-install-card > *,
|
|
1035
|
+
.kward-feature-strip > *,
|
|
1036
|
+
.kward-capabilities li {
|
|
1037
|
+
min-width: 0;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
.kward-hero h1 {
|
|
1041
|
+
font-size: clamp(32px, 10vw, 38px);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.kward-swosh {
|
|
1045
|
+
max-width: 100%;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1033
1048
|
.kward-feature-strip,
|
|
1034
1049
|
.kward-capabilities ul {
|
|
1035
1050
|
grid-template-columns: 1fr;
|
|
@@ -1370,6 +1385,7 @@ body.kward-docs .kward-home #footer {
|
|
|
1370
1385
|
flex-direction: column;
|
|
1371
1386
|
gap: 2px;
|
|
1372
1387
|
height: auto !important;
|
|
1388
|
+
justify-content: flex-start;
|
|
1373
1389
|
left: 12px;
|
|
1374
1390
|
max-height: calc(100vh - 100px);
|
|
1375
1391
|
overflow-y: auto;
|
|
@@ -1810,6 +1826,12 @@ body.kward-docs #toc li > ol {
|
|
|
1810
1826
|
margin-top: 6px;
|
|
1811
1827
|
}
|
|
1812
1828
|
|
|
1829
|
+
body.kward-docs #content code,
|
|
1830
|
+
body.kward-docs #filecontents code,
|
|
1831
|
+
body.kward-docs #toc code {
|
|
1832
|
+
overflow-wrap: anywhere;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1813
1835
|
|
|
1814
1836
|
/* Keep TOC hover states readable on the dark theme. */
|
|
1815
1837
|
body.kward-docs #toc a:hover,
|
|
@@ -8,8 +8,10 @@ const guideLinks = {
|
|
|
8
8
|
'doc/session-management.md': 'file.session-management.html',
|
|
9
9
|
'doc/memory.md': 'file.memory.html',
|
|
10
10
|
'doc/personas.md': 'file.personas.html',
|
|
11
|
+
'doc/skills.md': 'file.skills.html',
|
|
11
12
|
'doc/extensibility.md': 'file.extensibility.html',
|
|
12
13
|
'doc/plugins.md': 'file.plugins.html',
|
|
14
|
+
'doc/lifecycle-hooks.md': 'file.lifecycle-hooks.html',
|
|
13
15
|
'doc/agent-tools.md': 'file.agent-tools.html',
|
|
14
16
|
'doc/workspace-tools.md': 'file.workspace-tools.html',
|
|
15
17
|
'doc/web-search.md': 'file.web-search.html',
|
|
@@ -18,7 +18,8 @@ module KwardDocsNavigationData
|
|
|
18
18
|
["Sessions", "file.session-management.html"],
|
|
19
19
|
["Tabs", "file.tabs.html"],
|
|
20
20
|
["Memory", "file.memory.html"],
|
|
21
|
-
["Personas", "file.personas.html"]
|
|
21
|
+
["Personas", "file.personas.html"],
|
|
22
|
+
["Skills", "file.skills.html"]
|
|
22
23
|
]
|
|
23
24
|
],
|
|
24
25
|
[
|
|
@@ -37,7 +38,8 @@ module KwardDocsNavigationData
|
|
|
37
38
|
"Customize",
|
|
38
39
|
[
|
|
39
40
|
["Extensibility", "file.extensibility.html"],
|
|
40
|
-
["Plugins", "file.plugins.html"]
|
|
41
|
+
["Plugins", "file.plugins.html"],
|
|
42
|
+
["Lifecycle hooks", "file.lifecycle-hooks.html"]
|
|
41
43
|
]
|
|
42
44
|
],
|
|
43
45
|
[
|
|
@@ -38,8 +38,10 @@ module KwardDocsNavigation
|
|
|
38
38
|
"doc/shell.md" => "file.shell.html",
|
|
39
39
|
"doc/memory.md" => "file.memory.html",
|
|
40
40
|
"doc/personas.md" => "file.personas.html",
|
|
41
|
+
"doc/skills.md" => "file.skills.html",
|
|
41
42
|
"doc/extensibility.md" => "file.extensibility.html",
|
|
42
43
|
"doc/plugins.md" => "file.plugins.html",
|
|
44
|
+
"doc/lifecycle-hooks.md" => "file.lifecycle-hooks.html",
|
|
43
45
|
"doc/agent-tools.md" => "file.agent-tools.html",
|
|
44
46
|
"doc/workspace-tools.md" => "file.workspace-tools.html",
|
|
45
47
|
"doc/context-budgeting.md" => "file.context-budgeting.html",
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kward
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.75.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kai Wood
|
|
@@ -137,6 +137,8 @@ files:
|
|
|
137
137
|
- doc/files.md
|
|
138
138
|
- doc/getting-started.md
|
|
139
139
|
- doc/git.md
|
|
140
|
+
- doc/lifecycle-hooks.md
|
|
141
|
+
- doc/mcp.md
|
|
140
142
|
- doc/memory.md
|
|
141
143
|
- doc/personas.md
|
|
142
144
|
- doc/plugins.md
|
|
@@ -144,6 +146,7 @@ files:
|
|
|
144
146
|
- doc/rpc.md
|
|
145
147
|
- doc/session-management.md
|
|
146
148
|
- doc/shell.md
|
|
149
|
+
- doc/skills.md
|
|
147
150
|
- doc/tabs.md
|
|
148
151
|
- doc/troubleshooting.md
|
|
149
152
|
- doc/usage.md
|
|
@@ -158,6 +161,7 @@ files:
|
|
|
158
161
|
- lib/kward/auth/anthropic_oauth.rb
|
|
159
162
|
- lib/kward/auth/file.rb
|
|
160
163
|
- lib/kward/auth/github_oauth.rb
|
|
164
|
+
- lib/kward/auth/oauth_helpers.rb
|
|
161
165
|
- lib/kward/auth/openai_oauth.rb
|
|
162
166
|
- lib/kward/auth/openrouter_api_key.rb
|
|
163
167
|
- lib/kward/cancellation.rb
|
|
@@ -167,6 +171,7 @@ files:
|
|
|
167
171
|
- lib/kward/cli/compaction.rb
|
|
168
172
|
- lib/kward/cli/doctor.rb
|
|
169
173
|
- lib/kward/cli/git.rb
|
|
174
|
+
- lib/kward/cli/hook_commands.rb
|
|
170
175
|
- lib/kward/cli/interactive_turn.rb
|
|
171
176
|
- lib/kward/cli/memory_commands.rb
|
|
172
177
|
- lib/kward/cli/openrouter_commands.rb
|
|
@@ -184,26 +189,45 @@ files:
|
|
|
184
189
|
- lib/kward/cli_transcript_formatter.rb
|
|
185
190
|
- lib/kward/clipboard.rb
|
|
186
191
|
- lib/kward/compaction/file_operation_tracker.rb
|
|
192
|
+
- lib/kward/compaction/token_estimator.rb
|
|
187
193
|
- lib/kward/compactor.rb
|
|
188
194
|
- lib/kward/config_files.rb
|
|
189
195
|
- lib/kward/context_budget_meter.rb
|
|
190
196
|
- lib/kward/conversation.rb
|
|
197
|
+
- lib/kward/deep_copy.rb
|
|
198
|
+
- lib/kward/diff_view_mode.rb
|
|
191
199
|
- lib/kward/editor_mode.rb
|
|
192
200
|
- lib/kward/ekwsh.rb
|
|
193
201
|
- lib/kward/events.rb
|
|
194
202
|
- lib/kward/export_path.rb
|
|
203
|
+
- lib/kward/frontmatter.rb
|
|
204
|
+
- lib/kward/hooks.rb
|
|
205
|
+
- lib/kward/hooks/audit_log.rb
|
|
206
|
+
- lib/kward/hooks/catalog.rb
|
|
207
|
+
- lib/kward/hooks/command_handler.rb
|
|
208
|
+
- lib/kward/hooks/config_loader.rb
|
|
209
|
+
- lib/kward/hooks/decision.rb
|
|
210
|
+
- lib/kward/hooks/event.rb
|
|
211
|
+
- lib/kward/hooks/http_handler.rb
|
|
212
|
+
- lib/kward/hooks/manager.rb
|
|
213
|
+
- lib/kward/hooks/matcher.rb
|
|
195
214
|
- lib/kward/image_attachments.rb
|
|
196
215
|
- lib/kward/interactive_pty_runner.rb
|
|
197
216
|
- lib/kward/local_command_runner.rb
|
|
198
217
|
- lib/kward/local_pty_command_runner.rb
|
|
199
218
|
- lib/kward/markdown_transcript.rb
|
|
219
|
+
- lib/kward/mcp/client.rb
|
|
220
|
+
- lib/kward/mcp/server_config.rb
|
|
221
|
+
- lib/kward/mcp/stdio_transport.rb
|
|
200
222
|
- lib/kward/memory/manager.rb
|
|
223
|
+
- lib/kward/memory/turn_context.rb
|
|
201
224
|
- lib/kward/message_access.rb
|
|
202
225
|
- lib/kward/message_text.rb
|
|
203
226
|
- lib/kward/model/chat_invocation.rb
|
|
204
227
|
- lib/kward/model/client.rb
|
|
205
228
|
- lib/kward/model/context_overflow.rb
|
|
206
229
|
- lib/kward/model/context_usage.rb
|
|
230
|
+
- lib/kward/model/copilot_models.rb
|
|
207
231
|
- lib/kward/model/model_info.rb
|
|
208
232
|
- lib/kward/model/payloads.rb
|
|
209
233
|
- lib/kward/model/retry_message.rb
|
|
@@ -211,6 +235,7 @@ files:
|
|
|
211
235
|
- lib/kward/openrouter_model_cache.rb
|
|
212
236
|
- lib/kward/pan/index.html.erb
|
|
213
237
|
- lib/kward/pan/server.rb
|
|
238
|
+
- lib/kward/path_guard.rb
|
|
214
239
|
- lib/kward/plugin_registry.rb
|
|
215
240
|
- lib/kward/private_file.rb
|
|
216
241
|
- lib/kward/project_files.rb
|
|
@@ -265,6 +290,7 @@ files:
|
|
|
265
290
|
- lib/kward/rpc/attachment_normalizer.rb
|
|
266
291
|
- lib/kward/rpc/auth_manager.rb
|
|
267
292
|
- lib/kward/rpc/config_manager.rb
|
|
293
|
+
- lib/kward/rpc/mcp_status.rb
|
|
268
294
|
- lib/kward/rpc/memory_methods.rb
|
|
269
295
|
- lib/kward/rpc/prompt_bridge.rb
|
|
270
296
|
- lib/kward/rpc/redactor.rb
|
|
@@ -278,6 +304,7 @@ files:
|
|
|
278
304
|
- lib/kward/rpc/tool_metadata.rb
|
|
279
305
|
- lib/kward/rpc/transcript_normalizer.rb
|
|
280
306
|
- lib/kward/rpc/transport.rb
|
|
307
|
+
- lib/kward/rpc/turn_context.rb
|
|
281
308
|
- lib/kward/scratchpad_runner.rb
|
|
282
309
|
- lib/kward/session_diff.rb
|
|
283
310
|
- lib/kward/session_naming.rb
|
|
@@ -305,6 +332,7 @@ files:
|
|
|
305
332
|
- lib/kward/tools/fetch_content.rb
|
|
306
333
|
- lib/kward/tools/fetch_raw.rb
|
|
307
334
|
- lib/kward/tools/list_directory.rb
|
|
335
|
+
- lib/kward/tools/mcp_tool.rb
|
|
308
336
|
- lib/kward/tools/read_file.rb
|
|
309
337
|
- lib/kward/tools/read_skill.rb
|
|
310
338
|
- lib/kward/tools/registry.rb
|
|
@@ -318,6 +346,7 @@ files:
|
|
|
318
346
|
- lib/kward/tools/web_search.rb
|
|
319
347
|
- lib/kward/tools/write_file.rb
|
|
320
348
|
- lib/kward/transcript_export.rb
|
|
349
|
+
- lib/kward/update_check.rb
|
|
321
350
|
- lib/kward/version.rb
|
|
322
351
|
- lib/kward/workers.rb
|
|
323
352
|
- lib/kward/workers/git_guard.rb
|