kward 0.70.0 → 0.72.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/pages.yml +1 -1
- data/CHANGELOG.md +89 -3
- data/Gemfile +2 -0
- data/Gemfile.lock +90 -2
- data/README.md +34 -6
- data/Rakefile +96 -0
- data/doc/agent-tools.md +52 -0
- data/doc/api.md +92 -0
- data/doc/authentication.md +58 -23
- data/doc/code-search.md +42 -2
- data/doc/configuration.md +102 -13
- data/doc/context-budgeting.md +136 -0
- data/doc/context-tools.md +83 -0
- data/doc/editor.md +394 -0
- data/doc/extensibility.md +16 -7
- data/doc/files.md +100 -0
- data/doc/getting-started.md +25 -18
- data/doc/git.md +122 -0
- data/doc/memory.md +24 -4
- data/doc/personas.md +34 -5
- data/doc/plugins.md +74 -3
- data/doc/releasing.md +45 -8
- data/doc/rpc.md +77 -15
- data/doc/session-management.md +254 -0
- data/doc/shell.md +286 -0
- data/doc/tabs.md +122 -0
- data/doc/troubleshooting.md +77 -1
- data/doc/usage.md +60 -15
- data/doc/web-search.md +12 -4
- data/doc/workspace-tools.md +144 -0
- data/examples/plugins/space_invaders.rb +377 -0
- data/lib/kward/agent.rb +1 -1
- data/lib/kward/cli/commands.rb +41 -2
- data/lib/kward/cli/git.rb +150 -0
- data/lib/kward/cli/interactive_turn.rb +73 -9
- data/lib/kward/cli/openrouter_commands.rb +55 -0
- data/lib/kward/cli/plugins.rb +54 -4
- data/lib/kward/cli/prompt_interface.rb +111 -6
- data/lib/kward/cli/rendering.rb +11 -6
- data/lib/kward/cli/runtime_helpers.rb +133 -3
- data/lib/kward/cli/sessions.rb +262 -13
- data/lib/kward/cli/settings.rb +216 -37
- data/lib/kward/cli/slash_commands.rb +439 -8
- data/lib/kward/cli/tabs.rb +695 -0
- data/lib/kward/cli.rb +171 -26
- data/lib/kward/compactor.rb +4 -1
- data/lib/kward/config_files.rb +125 -5
- data/lib/kward/context_budget_meter.rb +44 -0
- data/lib/kward/conversation.rb +59 -22
- data/lib/kward/editor_mode.rb +25 -0
- data/lib/kward/ekwsh.rb +362 -0
- data/lib/kward/model/client.rb +37 -50
- data/lib/kward/model/context_usage.rb +13 -6
- data/lib/kward/model/model_info.rb +92 -16
- data/lib/kward/model/payloads.rb +2 -0
- data/lib/kward/openrouter_model_cache.rb +120 -0
- data/lib/kward/plugin_registry.rb +108 -1
- data/lib/kward/project_files.rb +52 -0
- data/lib/kward/prompt_history.rb +82 -0
- data/lib/kward/prompt_interface/banner.rb +16 -51
- data/lib/kward/prompt_interface/composer_controller.rb +124 -83
- data/lib/kward/prompt_interface/composer_renderer.rb +116 -14
- 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 +509 -0
- data/lib/kward/prompt_interface/editor/buffer.rb +109 -0
- data/lib/kward/prompt_interface/editor/controller.rb +1018 -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 +353 -0
- data/lib/kward/prompt_interface/editor/modes/vibe.rb +1962 -0
- data/lib/kward/prompt_interface/editor/renderer.rb +243 -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 +1249 -0
- data/lib/kward/prompt_interface/editor/status_text.rb +23 -0
- data/lib/kward/prompt_interface/editor/syntax_highlighter.rb +420 -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 +299 -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 +416 -43
- data/lib/kward/prompt_interface/layout.rb +2 -2
- 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/prompt_renderer.rb +32 -13
- data/lib/kward/prompt_interface/question_prompt.rb +122 -82
- data/lib/kward/prompt_interface/runtime_state.rb +49 -1
- data/lib/kward/prompt_interface/screen.rb +17 -0
- data/lib/kward/prompt_interface/selection_prompt.rb +511 -58
- data/lib/kward/prompt_interface/stream_state.rb +7 -0
- data/lib/kward/prompt_interface/transcript_buffer.rb +13 -16
- data/lib/kward/prompt_interface/transcript_renderer.rb +3 -3
- data/lib/kward/prompt_interface.rb +307 -35
- data/lib/kward/prompts/commands.rb +7 -1
- data/lib/kward/prompts.rb +4 -2
- data/lib/kward/rpc/server.rb +45 -11
- data/lib/kward/rpc/session_manager.rb +52 -53
- data/lib/kward/rpc/session_tree_rows.rb +9 -115
- data/lib/kward/rpc/tool_event_normalizer.rb +1 -1
- data/lib/kward/session_store.rb +67 -4
- 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/telemetry/logger.rb +5 -3
- data/lib/kward/text_boundary.rb +25 -0
- data/lib/kward/tool_output_compactor.rb +127 -0
- data/lib/kward/tools/base.rb +8 -2
- data/lib/kward/tools/context_budget_stats.rb +54 -0
- data/lib/kward/tools/context_for_task.rb +202 -0
- data/lib/kward/tools/read_file.rb +8 -4
- data/lib/kward/tools/registry.rb +92 -15
- data/lib/kward/tools/retrieve_tool_output.rb +71 -0
- data/lib/kward/tools/search/web.rb +2 -2
- data/lib/kward/tools/summarize_file_structure.rb +29 -0
- data/lib/kward/tools/tool_call.rb +12 -0
- data/lib/kward/version.rb +1 -1
- data/lib/kward/workers/git_guard.rb +68 -0
- data/lib/kward/workers/live_view.rb +49 -0
- data/lib/kward/workers/manager.rb +288 -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 +7 -0
- data/lib/kward/workspace.rb +154 -12
- data/templates/default/fulldoc/html/css/kward.css +362 -42
- data/templates/default/fulldoc/html/full_list.erb +107 -0
- data/templates/default/fulldoc/html/js/kward.js +161 -2
- data/templates/default/fulldoc/html/setup.rb +8 -0
- data/templates/default/kward_navigation.rb +102 -0
- data/templates/default/layout/html/layout.erb +43 -10
- data/templates/default/layout/html/setup.rb +39 -38
- metadata +65 -3
- data/lib/kward/resources/avatar_kward_logo.rb +0 -50
- data/lib/kward/resources/pixel_logo.rb +0 -232
|
@@ -5,17 +5,90 @@ const guideLinks = {
|
|
|
5
5
|
'doc/configuration.md': 'file.configuration.html',
|
|
6
6
|
'doc/authentication.md': 'file.authentication.html',
|
|
7
7
|
'doc/troubleshooting.md': 'file.troubleshooting.html',
|
|
8
|
+
'doc/session-management.md': 'file.session-management.html',
|
|
8
9
|
'doc/memory.md': 'file.memory.html',
|
|
9
10
|
'doc/personas.md': 'file.personas.html',
|
|
10
11
|
'doc/extensibility.md': 'file.extensibility.html',
|
|
11
12
|
'doc/plugins.md': 'file.plugins.html',
|
|
13
|
+
'doc/agent-tools.md': 'file.agent-tools.html',
|
|
14
|
+
'doc/workspace-tools.md': 'file.workspace-tools.html',
|
|
12
15
|
'doc/web-search.md': 'file.web-search.html',
|
|
13
16
|
'doc/code-search.md': 'file.code-search.html',
|
|
17
|
+
'doc/context-tools.md': 'file.context-tools.html',
|
|
14
18
|
'doc/rpc.md': 'file.rpc.html',
|
|
15
19
|
'doc/releasing.md': 'file.releasing.html'
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
let pageController = null
|
|
23
|
+
let navigating = false
|
|
24
|
+
|
|
25
|
+
const scrollToCurrentHash = () => {
|
|
26
|
+
if (!window.location.hash) {
|
|
27
|
+
window.scrollTo({ top: 0 })
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const id = decodeURIComponent(window.location.hash.slice(1))
|
|
32
|
+
const target = document.getElementById(id) || document.getElementsByName(id)[0]
|
|
33
|
+
if (target) target.scrollIntoView()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const replacePage = async (url, pushState = true) => {
|
|
37
|
+
if (navigating) return
|
|
38
|
+
navigating = true
|
|
39
|
+
document.documentElement.classList.add('kward-navigating')
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(url, { headers: { 'X-Requested-With': 'Kward-Docs' } })
|
|
43
|
+
if (!response.ok) throw new Error(`Navigation failed with ${response.status}`)
|
|
44
|
+
|
|
45
|
+
const html = await response.text()
|
|
46
|
+
const nextDocument = new DOMParser().parseFromString(html, 'text/html')
|
|
47
|
+
if (!nextDocument.body) throw new Error('Navigation response did not include a body')
|
|
48
|
+
|
|
49
|
+
document.title = nextDocument.title
|
|
50
|
+
document.body.className = nextDocument.body.className
|
|
51
|
+
document.body.innerHTML = nextDocument.body.innerHTML
|
|
52
|
+
|
|
53
|
+
if (pushState) window.history.pushState({ kwardDocs: true }, '', url)
|
|
54
|
+
initializePage()
|
|
55
|
+
scrollToCurrentHash()
|
|
56
|
+
} catch (_error) {
|
|
57
|
+
window.location.href = url
|
|
58
|
+
} finally {
|
|
59
|
+
navigating = false
|
|
60
|
+
document.documentElement.classList.remove('kward-navigating')
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const isNavigableLink = (event, link) => {
|
|
65
|
+
if (event.defaultPrevented || event.button !== 0) return false
|
|
66
|
+
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return false
|
|
67
|
+
if (link.target && link.target !== '_self') return false
|
|
68
|
+
if (link.download || link.dataset.noTurbo) return false
|
|
69
|
+
|
|
70
|
+
const url = new URL(link.href, window.location.href)
|
|
71
|
+
if (url.origin !== window.location.origin) return false
|
|
72
|
+
if (url.pathname === window.location.pathname && url.search === window.location.search) return false
|
|
73
|
+
|
|
74
|
+
return url.pathname === '/' || url.pathname.endsWith('/') || url.pathname.endsWith('.html')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const visitLink = (link) => replacePage(link.href)
|
|
78
|
+
|
|
79
|
+
const setupTurbolinks = (signal) => {
|
|
80
|
+
document.addEventListener('click', (event) => {
|
|
81
|
+
const link = event.target.closest('a[href]')
|
|
82
|
+
if (!link || !isNavigableLink(event, link)) return
|
|
83
|
+
|
|
84
|
+
event.preventDefault()
|
|
85
|
+
visitLink(link)
|
|
86
|
+
}, { signal })
|
|
87
|
+
|
|
88
|
+
window.addEventListener('popstate', () => {
|
|
89
|
+
replacePage(window.location.href, false)
|
|
90
|
+
}, { signal })
|
|
91
|
+
}
|
|
19
92
|
|
|
20
93
|
const setupGuideSearch = (signal) => {
|
|
21
94
|
const form = document.querySelector('.kward-guide-search')
|
|
@@ -151,7 +224,7 @@ const setupGuideSearch = (signal) => {
|
|
|
151
224
|
} else if (event.key === 'Enter') {
|
|
152
225
|
if (selectedIndex >= 0 && items[selectedIndex]) {
|
|
153
226
|
event.preventDefault()
|
|
154
|
-
|
|
227
|
+
visitLink(items[selectedIndex])
|
|
155
228
|
}
|
|
156
229
|
}
|
|
157
230
|
}, { signal })
|
|
@@ -159,7 +232,7 @@ const setupGuideSearch = (signal) => {
|
|
|
159
232
|
form.addEventListener('submit', (event) => {
|
|
160
233
|
event.preventDefault()
|
|
161
234
|
const firstResult = results.querySelector('a')
|
|
162
|
-
if (firstResult)
|
|
235
|
+
if (firstResult) visitLink(firstResult)
|
|
163
236
|
}, { signal })
|
|
164
237
|
|
|
165
238
|
document.addEventListener('click', (event) => {
|
|
@@ -252,6 +325,90 @@ const rewriteGuideLinks = () => {
|
|
|
252
325
|
})
|
|
253
326
|
}
|
|
254
327
|
|
|
328
|
+
const setupTableOfContents = () => {
|
|
329
|
+
const existingToc = document.getElementById('toc')
|
|
330
|
+
if (document.querySelector('.kward-no-toc')) {
|
|
331
|
+
if (existingToc) existingToc.remove()
|
|
332
|
+
return
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const fileContents = document.getElementById('filecontents')
|
|
336
|
+
const content = document.getElementById('content')
|
|
337
|
+
if (!fileContents || !content || content.querySelector('#toc')) return
|
|
338
|
+
|
|
339
|
+
const headingTags = ['h2', 'h3', 'h4', 'h5', 'h6']
|
|
340
|
+
if (fileContents.querySelectorAll('h1').length > 1) headingTags.unshift('h1')
|
|
341
|
+
|
|
342
|
+
const headings = Array.from(fileContents.querySelectorAll(headingTags.join(', ')))
|
|
343
|
+
.filter((heading) => !heading.closest('.method_details .docstring') && heading.id !== 'filecontents')
|
|
344
|
+
if (headings.length === 0) return
|
|
345
|
+
|
|
346
|
+
const topLevel = document.createElement('ol')
|
|
347
|
+
topLevel.className = 'top'
|
|
348
|
+
|
|
349
|
+
let currentList = topLevel
|
|
350
|
+
let currentItem = null
|
|
351
|
+
let counter = 0
|
|
352
|
+
let lastLevel = parseInt(headingTags[0].slice(1), 10)
|
|
353
|
+
|
|
354
|
+
headings.forEach((heading) => {
|
|
355
|
+
const level = parseInt(heading.tagName.slice(1), 10)
|
|
356
|
+
|
|
357
|
+
if (!heading.id) {
|
|
358
|
+
let proposedId = heading.getAttribute('toc-id')
|
|
359
|
+
if (!proposedId) {
|
|
360
|
+
proposedId = heading.textContent.replace(/[^a-z0-9-]/gi, '_')
|
|
361
|
+
if (document.getElementById(proposedId)) {
|
|
362
|
+
proposedId += counter
|
|
363
|
+
counter += 1
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
heading.id = proposedId
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (level > lastLevel) {
|
|
370
|
+
while (level > lastLevel) {
|
|
371
|
+
if (!currentItem) {
|
|
372
|
+
currentItem = document.createElement('li')
|
|
373
|
+
currentList.appendChild(currentItem)
|
|
374
|
+
}
|
|
375
|
+
const nestedList = document.createElement('ol')
|
|
376
|
+
currentItem.appendChild(nestedList)
|
|
377
|
+
currentList = nestedList
|
|
378
|
+
currentItem = null
|
|
379
|
+
lastLevel += 1
|
|
380
|
+
}
|
|
381
|
+
} else if (level < lastLevel) {
|
|
382
|
+
while (level < lastLevel && currentList.parentElement) {
|
|
383
|
+
currentList = currentList.parentElement.parentElement
|
|
384
|
+
lastLevel -= 1
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const title = heading.getAttribute('toc-title') || heading.textContent
|
|
389
|
+
const item = document.createElement('li')
|
|
390
|
+
const link = document.createElement('a')
|
|
391
|
+
link.href = `#${heading.id}`
|
|
392
|
+
link.textContent = title
|
|
393
|
+
item.appendChild(link)
|
|
394
|
+
currentList.appendChild(item)
|
|
395
|
+
currentItem = item
|
|
396
|
+
})
|
|
397
|
+
|
|
398
|
+
const toc = document.createElement('div')
|
|
399
|
+
toc.id = 'toc'
|
|
400
|
+
toc.innerHTML = '<p class="title hide_toc"><a href="#"><strong>Table of Contents</strong></a></p>'
|
|
401
|
+
toc.appendChild(topLevel)
|
|
402
|
+
content.insertBefore(toc, content.firstChild)
|
|
403
|
+
|
|
404
|
+
const hideLink = toc.querySelector('.hide_toc')
|
|
405
|
+
hideLink.addEventListener('click', (event) => {
|
|
406
|
+
event.preventDefault()
|
|
407
|
+
const hidden = toc.classList.toggle('hidden')
|
|
408
|
+
topLevel.style.display = hidden ? 'none' : ''
|
|
409
|
+
})
|
|
410
|
+
}
|
|
411
|
+
|
|
255
412
|
const setupCodeCopy = () => {
|
|
256
413
|
document.querySelectorAll('pre').forEach((block) => {
|
|
257
414
|
if (block.closest('.code-copy-wrapper')) return
|
|
@@ -285,9 +442,11 @@ const initializePage = () => {
|
|
|
285
442
|
if (pageController) pageController.abort()
|
|
286
443
|
pageController = new AbortController()
|
|
287
444
|
|
|
445
|
+
setupTurbolinks(pageController.signal)
|
|
288
446
|
setupGuideSearch(pageController.signal)
|
|
289
447
|
setupNavigation(pageController.signal)
|
|
290
448
|
rewriteGuideLinks()
|
|
449
|
+
setupTableOfContents()
|
|
291
450
|
setupCodeCopy()
|
|
292
451
|
}
|
|
293
452
|
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "../../kward_navigation"
|
|
4
|
+
|
|
5
|
+
include KwardDocsNavigationData
|
|
6
|
+
|
|
3
7
|
def generate_assets
|
|
4
8
|
super
|
|
5
9
|
asset('css/kward.css', file('css/kward.css', true))
|
|
6
10
|
asset('js/kward.js', file('js/kward.js', true))
|
|
7
11
|
asset('images/kward_logo.png', file('images/kward_logo.png', true))
|
|
8
12
|
end
|
|
13
|
+
|
|
14
|
+
def stylesheets_full_list
|
|
15
|
+
super + %w(css/kward.css)
|
|
16
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KwardDocsNavigationData
|
|
4
|
+
GUIDE_GROUPS = [
|
|
5
|
+
[
|
|
6
|
+
"Start here",
|
|
7
|
+
[
|
|
8
|
+
["Getting started", "file.getting-started.html"],
|
|
9
|
+
["Usage", "file.usage.html"],
|
|
10
|
+
["Configuration", "file.configuration.html"],
|
|
11
|
+
["Authentication", "file.authentication.html"],
|
|
12
|
+
["Troubleshooting", "file.troubleshooting.html"]
|
|
13
|
+
]
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
"Feature guides",
|
|
17
|
+
[
|
|
18
|
+
["Sessions", "file.session-management.html"],
|
|
19
|
+
["Tabs", "file.tabs.html"],
|
|
20
|
+
["Memory", "file.memory.html"],
|
|
21
|
+
["Personas", "file.personas.html"]
|
|
22
|
+
]
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
"User Tools",
|
|
26
|
+
[
|
|
27
|
+
["Project files", "file.files.html"],
|
|
28
|
+
["Integrated Editor", "file.editor.html"],
|
|
29
|
+
["Git", "file.git.html"],
|
|
30
|
+
["Shell", "file.shell.html"]
|
|
31
|
+
]
|
|
32
|
+
]
|
|
33
|
+
].freeze
|
|
34
|
+
|
|
35
|
+
EXTENSION_GROUPS = [
|
|
36
|
+
[
|
|
37
|
+
"Customize",
|
|
38
|
+
[
|
|
39
|
+
["Extensibility", "file.extensibility.html"],
|
|
40
|
+
["Plugins", "file.plugins.html"]
|
|
41
|
+
]
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
"Integrate",
|
|
45
|
+
[
|
|
46
|
+
["RPC protocol", "file.rpc.html"],
|
|
47
|
+
["Releasing", "file.releasing.html"]
|
|
48
|
+
]
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"Agent tools",
|
|
52
|
+
[
|
|
53
|
+
["Overview", "file.agent-tools.html"],
|
|
54
|
+
["Workspace tools", "file.workspace-tools.html"],
|
|
55
|
+
["Web search", "file.web-search.html"],
|
|
56
|
+
["Code search", "file.code-search.html"],
|
|
57
|
+
["Context tools", "file.context-tools.html"],
|
|
58
|
+
["Context budgeting", "file.context-budgeting.html"]
|
|
59
|
+
]
|
|
60
|
+
]
|
|
61
|
+
].freeze
|
|
62
|
+
|
|
63
|
+
API_OVERVIEW = "file.api.html"
|
|
64
|
+
API_GROUPS = [
|
|
65
|
+
[
|
|
66
|
+
"Reference",
|
|
67
|
+
[
|
|
68
|
+
["Overview", API_OVERVIEW],
|
|
69
|
+
["Classes & Modules", "class_list.html"],
|
|
70
|
+
["Methods", "method_list.html"],
|
|
71
|
+
["Files", "file_list.html"]
|
|
72
|
+
]
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
"Key namespaces",
|
|
76
|
+
[
|
|
77
|
+
["Kward", "Kward.html"],
|
|
78
|
+
["Tools", "Kward/Tools.html"],
|
|
79
|
+
["RPC", "Kward/RPC.html"],
|
|
80
|
+
["CLI", "Kward/CLI.html"],
|
|
81
|
+
["Prompts", "Kward/Prompts.html"],
|
|
82
|
+
["Skills", "Kward/Skills.html"]
|
|
83
|
+
]
|
|
84
|
+
]
|
|
85
|
+
].freeze
|
|
86
|
+
|
|
87
|
+
def guide_groups
|
|
88
|
+
GUIDE_GROUPS
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def extension_groups
|
|
92
|
+
EXTENSION_GROUPS
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def api_groups
|
|
96
|
+
API_GROUPS
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def api_overview
|
|
100
|
+
API_OVERVIEW
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
<nav id="kward-primary-nav" class="kward-topnav" aria-label="Primary navigation">
|
|
23
23
|
<a href="<%= url_for('index.html') %>" class="<%= 'active' if home_page? %>">Home</a>
|
|
24
24
|
<div class="kward-nav-menu <%= 'active' if guide_page? %>">
|
|
25
|
-
<a class="kward-nav-menu-link" href="<%= url_for(
|
|
26
|
-
<button class="kward-nav-menu-button" type="button" aria-label="Expand
|
|
25
|
+
<a class="kward-nav-menu-link" href="<%= url_for(guide_overview) %>">Guides</a>
|
|
26
|
+
<button class="kward-nav-menu-button" type="button" aria-label="Expand guides" aria-expanded="false">⌄</button>
|
|
27
27
|
<div class="kward-nav-dropdown">
|
|
28
28
|
<% guide_groups.each do |title, items| %>
|
|
29
29
|
<section>
|
|
@@ -35,13 +35,44 @@
|
|
|
35
35
|
<% end %>
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
38
|
-
<
|
|
38
|
+
<div class="kward-nav-menu <%= 'active' if extension_page? %>">
|
|
39
|
+
<a class="kward-nav-menu-link" href="<%= url_for(extension_overview) %>">Advanced</a>
|
|
40
|
+
<button class="kward-nav-menu-button" type="button" aria-label="Expand advanced guides" aria-expanded="false">⌄</button>
|
|
41
|
+
<div class="kward-nav-dropdown kward-advanced-nav-dropdown">
|
|
42
|
+
<% extension_groups.each do |title, items| %>
|
|
43
|
+
<section>
|
|
44
|
+
<h2><%= h title %></h2>
|
|
45
|
+
<% items.each do |label, link| %>
|
|
46
|
+
<a href="<%= url_for(link) %>"><%= h label %></a>
|
|
47
|
+
<% end %>
|
|
48
|
+
</section>
|
|
49
|
+
<% end %>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="kward-nav-menu <%= 'active' if api_page? %>">
|
|
53
|
+
<a class="kward-nav-menu-link" href="<%= url_for(api_overview) %>">API Docs</a>
|
|
54
|
+
<button class="kward-nav-menu-button" type="button" aria-label="Expand API docs" aria-expanded="false">⌄</button>
|
|
55
|
+
<div class="kward-nav-dropdown kward-api-nav-dropdown">
|
|
56
|
+
<% api_groups.each do |title, items| %>
|
|
57
|
+
<section>
|
|
58
|
+
<h2><%= h title %></h2>
|
|
59
|
+
<% items.each do |label, link| %>
|
|
60
|
+
<a href="<%= url_for(link) %>"><%= h label %></a>
|
|
61
|
+
<% end %>
|
|
62
|
+
</section>
|
|
63
|
+
<% end %>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
39
66
|
</nav>
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
67
|
+
<% if api_page? %>
|
|
68
|
+
<a class="kward-api-index-link" href="<%= url_for('class_list.html') %>">Search API index</a>
|
|
69
|
+
<% else %>
|
|
70
|
+
<form class="kward-guide-search" role="search">
|
|
71
|
+
<label class="kward-sr-only" for="kward-guide-search-input">Search user guides</label>
|
|
72
|
+
<input id="kward-guide-search-input" type="search" placeholder="Search guides" autocomplete="off" aria-label="Search user guides" aria-controls="kward-guide-search-results">
|
|
73
|
+
<div id="kward-guide-search-results" class="kward-guide-search-results" role="listbox" aria-label="Search results"></div>
|
|
74
|
+
</form>
|
|
75
|
+
<% end %>
|
|
45
76
|
<script type="application/json" id="kward-guide-search-index"><%= guide_search_index_json %></script>
|
|
46
77
|
</header>
|
|
47
78
|
|
|
@@ -51,14 +82,16 @@
|
|
|
51
82
|
<div class="kward-hero-copy">
|
|
52
83
|
<p class="kward-eyebrow">⌘ Ruby CLI Coding Agent</p>
|
|
53
84
|
<h1>
|
|
54
|
-
<span class="kward-swosh" aria-label="Your terminal.">
|
|
85
|
+
<span class="kward-swosh" aria-label="Your terminal. Your RPC frontend. Your workflow.">
|
|
55
86
|
<span class="kward-swosh-text kward-swosh-text-a" aria-hidden="true">Your terminal.</span>
|
|
56
87
|
<span class="kward-swosh-text kward-swosh-text-b" aria-hidden="true">Your RPC frontend.</span>
|
|
88
|
+
<span class="kward-swosh-text kward-swosh-text-e" aria-hidden="true">Your workflow.</span>
|
|
57
89
|
</span>
|
|
58
90
|
<br>
|
|
59
|
-
<span class="kward-swosh" aria-label="Your agent.">
|
|
91
|
+
<span class="kward-swosh" aria-label="Your agent. Your LLM engine. Your harness.">
|
|
60
92
|
<span class="kward-swosh-text kward-swosh-text-c" aria-hidden="true">Your agent.</span>
|
|
61
93
|
<span class="kward-swosh-text kward-swosh-text-d" aria-hidden="true">Your LLM engine.</span>
|
|
94
|
+
<span class="kward-swosh-text kward-swosh-text-f" aria-hidden="true">Your harness.</span>
|
|
62
95
|
</span>
|
|
63
96
|
</h1>
|
|
64
97
|
<p class="kward-lede">Kward is an extendable Ruby CLI coding agent that helps you understand your project, edit files, run commands, search the web, and automate workflows—right from your terminal.</p>
|
|
@@ -1,44 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "json"
|
|
4
|
+
require_relative "../../kward_navigation"
|
|
4
5
|
|
|
5
6
|
module KwardDocsNavigation
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
["Troubleshooting", "file.troubleshooting.html"]
|
|
15
|
-
]
|
|
16
|
-
],
|
|
17
|
-
[
|
|
18
|
-
"Feature guides",
|
|
19
|
-
[
|
|
20
|
-
["Memory", "file.memory.html"],
|
|
21
|
-
["Personas", "file.personas.html"],
|
|
22
|
-
["Extensibility", "file.extensibility.html"],
|
|
23
|
-
["Plugins", "file.plugins.html"],
|
|
24
|
-
["Web search", "file.web-search.html"],
|
|
25
|
-
["Code search", "file.code-search.html"]
|
|
26
|
-
]
|
|
27
|
-
],
|
|
28
|
-
[
|
|
29
|
-
"Advanced/reference",
|
|
30
|
-
[
|
|
31
|
-
["RPC protocol", "file.rpc.html"],
|
|
32
|
-
["Releasing", "file.releasing.html"]
|
|
33
|
-
]
|
|
34
|
-
]
|
|
35
|
-
].freeze
|
|
7
|
+
include KwardDocsNavigationData
|
|
8
|
+
API_FILE_LINKS = {
|
|
9
|
+
"doc/api.md" => API_OVERVIEW
|
|
10
|
+
}.freeze
|
|
11
|
+
API_LINKS = ([API_OVERVIEW] + API_GROUPS.flat_map { |_title, items| items.map(&:last) }).freeze
|
|
12
|
+
|
|
13
|
+
EXTENSION_OVERVIEW = "file.extensibility.html"
|
|
14
|
+
EXTENSION_LINKS = ([EXTENSION_OVERVIEW] + EXTENSION_GROUPS.flat_map { |_title, items| items.map(&:last) }).uniq.freeze
|
|
36
15
|
|
|
37
16
|
GUIDE_OVERVIEW = "file.README.html"
|
|
38
17
|
GUIDE_LINKS = ([GUIDE_OVERVIEW] + GUIDE_GROUPS.flat_map { |_title, items| items.map(&:last) }).freeze
|
|
39
18
|
GUIDE_SEARCH_FILES = [
|
|
40
19
|
["Overview", "README.md", GUIDE_OVERVIEW],
|
|
41
|
-
*GUIDE_GROUPS.flat_map do |_title, items|
|
|
20
|
+
*(GUIDE_GROUPS + EXTENSION_GROUPS).flat_map do |_title, items|
|
|
42
21
|
items.map do |label, link|
|
|
43
22
|
source = "doc/#{link.delete_prefix("file.").delete_suffix(".html")}.md"
|
|
44
23
|
[label, source, link]
|
|
@@ -51,24 +30,34 @@ module KwardDocsNavigation
|
|
|
51
30
|
"doc/configuration.md" => "file.configuration.html",
|
|
52
31
|
"doc/authentication.md" => "file.authentication.html",
|
|
53
32
|
"doc/troubleshooting.md" => "file.troubleshooting.html",
|
|
33
|
+
"doc/session-management.md" => "file.session-management.html",
|
|
34
|
+
"doc/tabs.md" => "file.tabs.html",
|
|
35
|
+
"doc/files.md" => "file.files.html",
|
|
36
|
+
"doc/editor.md" => "file.editor.html",
|
|
37
|
+
"doc/git.md" => "file.git.html",
|
|
38
|
+
"doc/shell.md" => "file.shell.html",
|
|
54
39
|
"doc/memory.md" => "file.memory.html",
|
|
55
40
|
"doc/personas.md" => "file.personas.html",
|
|
56
41
|
"doc/extensibility.md" => "file.extensibility.html",
|
|
57
42
|
"doc/plugins.md" => "file.plugins.html",
|
|
43
|
+
"doc/agent-tools.md" => "file.agent-tools.html",
|
|
44
|
+
"doc/workspace-tools.md" => "file.workspace-tools.html",
|
|
45
|
+
"doc/context-budgeting.md" => "file.context-budgeting.html",
|
|
58
46
|
"doc/web-search.md" => "file.web-search.html",
|
|
59
47
|
"doc/code-search.md" => "file.code-search.html",
|
|
48
|
+
"doc/context-tools.md" => "file.context-tools.html",
|
|
60
49
|
"doc/rpc.md" => "file.rpc.html",
|
|
61
50
|
"doc/releasing.md" => "file.releasing.html"
|
|
62
51
|
}.freeze
|
|
63
52
|
|
|
64
|
-
def guide_groups
|
|
65
|
-
GUIDE_GROUPS
|
|
66
|
-
end
|
|
67
|
-
|
|
68
53
|
def guide_overview
|
|
69
54
|
GUIDE_OVERVIEW
|
|
70
55
|
end
|
|
71
56
|
|
|
57
|
+
def extension_overview
|
|
58
|
+
EXTENSION_OVERVIEW
|
|
59
|
+
end
|
|
60
|
+
|
|
72
61
|
def guide_search_index_json
|
|
73
62
|
JSON.generate(guide_search_index).gsub("</", "<\\/")
|
|
74
63
|
end
|
|
@@ -99,7 +88,15 @@ module KwardDocsNavigation
|
|
|
99
88
|
end
|
|
100
89
|
|
|
101
90
|
def guide_file?
|
|
102
|
-
defined?(@file) &&
|
|
91
|
+
defined?(@file) && GUIDE_LINKS.include?(GUIDE_FILE_LINKS[@file&.filename.to_s])
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def extension_file?
|
|
95
|
+
defined?(@file) && EXTENSION_LINKS.include?(GUIDE_FILE_LINKS[@file&.filename.to_s])
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def api_file?
|
|
99
|
+
defined?(@file) && API_FILE_LINKS.key?(@file&.filename.to_s)
|
|
103
100
|
end
|
|
104
101
|
|
|
105
102
|
def home_page?
|
|
@@ -110,8 +107,12 @@ module KwardDocsNavigation
|
|
|
110
107
|
(readme_file? && !options.index) || guide_file? || GUIDE_LINKS.include?(current_docs_path)
|
|
111
108
|
end
|
|
112
109
|
|
|
110
|
+
def extension_page?
|
|
111
|
+
extension_file? || EXTENSION_LINKS.include?(current_docs_path)
|
|
112
|
+
end
|
|
113
|
+
|
|
113
114
|
def api_page?
|
|
114
|
-
!home_page? && !guide_page?
|
|
115
|
+
api_file? || API_LINKS.include?(current_docs_path) || (!home_page? && !guide_page? && !extension_page?)
|
|
115
116
|
end
|
|
116
117
|
|
|
117
118
|
def diskfile
|
|
@@ -121,7 +122,7 @@ module KwardDocsNavigation
|
|
|
121
122
|
end
|
|
122
123
|
|
|
123
124
|
def rewrite_guide_links(html)
|
|
124
|
-
GUIDE_FILE_LINKS.each do |source, target|
|
|
125
|
+
GUIDE_FILE_LINKS.merge(API_FILE_LINKS).each do |source, target|
|
|
125
126
|
html = html.gsub(%(href="#{source}"), %(href="#{target}"))
|
|
126
127
|
end
|
|
127
128
|
html
|