kash-shell 0.3.15__py3-none-any.whl → 0.3.17__py3-none-any.whl

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.
@@ -1,24 +1,552 @@
1
1
  {% extends "base_webpage.html.jinja" %}
2
2
 
3
- <!-- simple_webpage begin main_content block -->
3
+ {% block custom_styles %}
4
+ {{ super() }}
5
+ <style>
6
+ /* Override Tailwind's bg-white in dark mode */
7
+ [data-theme="dark"] .bg-white {
8
+ background-color: var(--color-bg-alt-solid) !important;
9
+ }
10
+ .long-text {
11
+ transition: background 0.4s ease-in-out, color 0.4s ease-in-out;
12
+ }
13
+
14
+ /* Ensure long-text containers respect theme */
15
+ [data-theme="dark"] .long-text {
16
+ background-color: var(--color-bg-alt-solid);
17
+ color: var(--color-text);
18
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 -2px 6px -1px rgba(0, 0, 0, 0.2);
19
+ }
20
+
21
+ /* Table of Contents Styles */
22
+ :root {
23
+ --toc-width: max(21vw, 15rem);
24
+ --toc-breakpoint: {{ toc_breakpoint | default(1200) }}px;
25
+ }
26
+
27
+ @media (min-width: 1536px) {
28
+ :root {
29
+ --toc-width: min(21vw, 30rem);
30
+ }
31
+ }
32
+
33
+ /* Desktop: Always use grid layout, adjust TOC column width */
34
+ @media (min-width: {{ toc_breakpoint | default(1200) }}px) {
35
+ .content-with-toc {
36
+ display: grid;
37
+ grid-template-columns: calc(var(--toc-width) + 4rem) 1fr;
38
+ max-width: none;
39
+ min-height: 100vh;
40
+ }
41
+
42
+ .content-with-toc.has-toc {
43
+ grid-template-columns: calc(var(--toc-width) + 4rem) 1fr;
44
+ }
45
+
46
+ /* Content goes in the second column (right side) */
47
+ .content-with-toc .long-text {
48
+ max-width: 48rem;
49
+ margin: 0 auto;
50
+ order: 2;
51
+ grid-column: 2;
52
+ }
53
+
54
+ /* TOC goes in the first column (left side) */
55
+ .toc-container {
56
+ order: 1;
57
+ grid-column: 1;
58
+ align-self: start;
59
+ width: var(--toc-width);
60
+ position: sticky;
61
+ top: 2rem;
62
+ max-height: calc(100vh - 4rem);
63
+ overflow-y: auto;
64
+ padding: 1rem 0.7rem;
65
+ margin: 0 0 0 2rem;
66
+ border: 1px solid var(--color-border-hint);
67
+ opacity: 0;
68
+ transform: translateX(-100%);
69
+ }
70
+
71
+ .content-with-toc.has-toc .toc-container {
72
+ transform: translateX(0);
73
+ opacity: 1;
74
+ }
75
+
76
+ /* Hide mobile toggle on desktop */
77
+ .toc-toggle {
78
+ display: none !important;
79
+ }
80
+
81
+ /* More minimal TOC scrollbar */
82
+ .toc-container::-webkit-scrollbar {
83
+ width: 2px;
84
+ }
85
+ .toc-container::-webkit-scrollbar-track {
86
+ background: transparent; /* Invisible track */
87
+ }
88
+ .toc-container::-webkit-scrollbar-thumb {
89
+ background: var(--color-hint-gentle);
90
+ border-radius: 2px;
91
+ opacity: 0.1;
92
+ }
93
+ .toc-container::-webkit-scrollbar-thumb:hover {
94
+ opacity: 0.2;
95
+ }
96
+ .toc-container {
97
+ /* For Firefox */
98
+ scrollbar-width: thin;
99
+ scrollbar-color: var(--color-hint-gentle) transparent;
100
+ }
101
+ }
102
+
103
+ /* TOC Styling */
104
+ .toc {
105
+ font-family: var(--font-sans);
106
+ color: var(--color-tertiary);
107
+ font-variant-numeric: tabular-nums;
108
+ }
109
+
110
+ .toc-title {
111
+ font-size: var(--font-size-small);
112
+ font-weight: 550;
113
+ text-transform: uppercase;
114
+ letter-spacing: 0.025em;
115
+ margin: 0 0 0.5rem 0.3rem;
116
+ padding-bottom: 0.5rem;
117
+ border-bottom: 1px solid var(--color-border-hint);
118
+ transition: color 0.4s ease-in-out, border-bottom-color 0.4s ease-in-out;
119
+ }
120
+
121
+ .toc-list {
122
+ list-style: none;
123
+ margin: 0;
124
+ padding: 0;
125
+ font-size: var(--font-size-small);
126
+ line-height: 1.2;
127
+ }
128
+
129
+ .toc-list li {
130
+ margin: 0;
131
+ padding: 0 0.3rem 0 0;
132
+ }
133
+
134
+ .toc-list li::before {
135
+ display: none; /* Remove custom bullet points */
136
+ }
137
+
138
+ .toc-link {
139
+ display: block;
140
+ color: var(--color-tertiary);
141
+ text-decoration: none;
142
+ padding: 0.2rem 0;
143
+ transition: background 0.4s ease-in-out, all 0.15s ease-in-out;
144
+ border-left: 2px solid transparent;
145
+ }
146
+
147
+ .toc-link:hover {
148
+ color: var(--color-secondary);
149
+ background-color: var(--color-hover-bg);
150
+ text-decoration: none;
151
+ }
152
+
153
+ .toc-link.active {
154
+ color: var(--color-secondary);
155
+ border-left: 2px solid var(--color-primary);
156
+ background-color: var(--color-hover-bg);
157
+ }
158
+
159
+ /* Hanging indent and styles for each TOC heading */
160
+ .toc-h1 {
161
+ padding-left: 1.3rem;
162
+ text-indent: -1em;
163
+ font-weight: 550;
164
+ }
165
+ .toc-h2 {
166
+ padding-left: 2.0rem;
167
+ text-indent: -1em;
168
+ font-weight: 550;
169
+ }
170
+ .toc-h3 {
171
+ padding-left: 2.7rem;
172
+ text-indent: -1em;
173
+ font-weight: 380;
174
+ }
175
+ .toc-h4 {
176
+ padding-left: 3.4rem;
177
+ text-indent: -1em;
178
+ font-weight: 380;
179
+ }
180
+
181
+ /* Prevent body scroll when TOC is open */
182
+ body.toc-open {
183
+ overflow: hidden;
184
+ position: fixed;
185
+ width: 100%;
186
+ }
187
+
188
+ /* Mobile TOC Layout */
189
+ @media (max-width: {{ toc_breakpoint | default(1200) - 1 }}px) {
190
+ /* Specific positioning and z-index for TOC toggle */
191
+ .toc-toggle {
192
+ left: 1rem;
193
+ z-index: 101;
194
+ opacity: 0; /* Hidden by default */
195
+ visibility: hidden; /* Start hidden for FOUC prevention on mobile */
196
+ transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;
197
+ }
198
+
199
+ /* Show TOC toggle when user has scrolled past top */
200
+ .toc-toggle.show-toggle {
201
+ opacity: 1;
202
+ visibility: visible;
203
+ }
204
+
205
+ /* Show backdrop when visible */
206
+ .toc-backdrop.visible {
207
+ opacity: 1;
208
+ visibility: visible;
209
+ pointer-events: auto;
210
+ }
211
+
212
+ /* Mobile TOC state: always rendered but hidden by default */
213
+ .toc-container {
214
+ display: block !important; /* Override base rule and any JS inline styles */
215
+ position: fixed;
216
+ top: 4rem;
217
+ left: 1rem;
218
+ width: calc(100vw - 2rem);
219
+ max-height: calc(100vh - 5rem);
220
+ /* Keep background and darker text on mobile since it's primary UI */
221
+ color: var(--color-text);
222
+ background: var(--color-bg-alt-solid);
223
+ border: 1px solid var(--color-border-hint);
224
+ padding: 1rem 0.7rem;
225
+ z-index: 200;
226
+
227
+ /* Ensure TOC itself is scrollable */
228
+ overflow-y: auto;
229
+ -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */
230
+ overscroll-behavior: contain; /* Prevent scroll chaining */
231
+
232
+ /* Initial hidden state for mobile FOUC and animation */
233
+ opacity: 0;
234
+ transform: translateY(-0.5rem);
235
+ visibility: hidden;
236
+ pointer-events: none; /* Prevent interaction when hidden */
237
+
238
+ transition: opacity 0.3s ease-in-out,
239
+ transform 0.3s ease-in-out,
240
+ visibility 0.3s ease-in-out,
241
+ pointer-events 0.3s ease-in-out,
242
+ background-color 0.4s ease-in-out,
243
+ border-color 0.4s ease-in-out,
244
+ box-shadow 0.4s ease-in-out;
245
+ }
246
+
247
+ /* Darker text on mobile */
248
+ .toc {
249
+ color: var(--color-secondary);
250
+ }
251
+ .toc-link {
252
+ color: var(--color-secondary);
253
+ }
254
+ .toc-link:hover {
255
+ color: var(--color-text);
256
+ }
257
+
258
+ .toc-link.active {
259
+ color: var(--color-text);
260
+ }
261
+
262
+ .toc-container.mobile-visible {
263
+ /* Visible state */
264
+ opacity: 1;
265
+ transform: translateY(0);
266
+ visibility: visible;
267
+ pointer-events: auto; /* Re-enable interaction */
268
+ }
269
+ }
270
+ </style>
271
+ {% endblock custom_styles %}
272
+
4
273
  {% block main_content %}
5
- <div class="long-text container max-w-3xl mx-auto bg-white py-4 px-6 md:px-16">
6
- {% block page_title %}
7
- {% if title and add_title_h1 %}
8
- <h1 class="text-center text-4xl mt-6 mb-6">{{ title }}</h1>
9
- {% endif %}
10
- {% endblock page_title %}
11
-
12
- <div>
13
- {% block page_content %}
14
- {% if thumbnail_url %}
15
- <img class="thumbnail" src="{{ thumbnail_url }}" alt="{{ title }}" />
274
+ <!-- simple_webpage begin main_content block -->
275
+ <div class="content-with-toc" id="content-container">
276
+ <div class="long-text container max-w-3xl mx-auto bg-white py-4 px-6 md:px-16" id="main-content">
277
+ {% block page_title %}
278
+ {% if title and add_title_h1 %}
279
+ <h1 class="text-center text-4xl mt-6 mb-6">{{ title }}</h1>
16
280
  {% endif %}
17
- <div class="content">
18
- {{ content_html | safe }}
281
+ {% endblock page_title %}
282
+
283
+ <div>
284
+ {% block page_content %}
285
+ {% if thumbnail_url %}
286
+ <img class="thumbnail" src="{{ thumbnail_url }}" alt="{{ title }}" />
287
+ {% endif %}
288
+ <div class="content">
289
+ {{ content_html | safe }}
290
+ </div>
291
+ {% endblock page_content %}
19
292
  </div>
20
- {% endblock page_content %}
21
293
  </div>
294
+
295
+ <!-- Mobile TOC toggle -->
296
+ <button class="button fixed-button toc-toggle" id="toc-toggle" aria-label="Toggle table of contents" style="display: none;">
297
+ <i data-feather="list"></i>
298
+ </button>
299
+
300
+ <!-- Mobile TOC Backdrop -->
301
+ <div class="toc-backdrop" id="toc-backdrop"></div>
302
+
303
+ <!-- TOC Container -->
304
+ <aside class="toc-container" id="toc-container" aria-label="Table of contents">
305
+ <div class="toc">
306
+ <h2 class="toc-title">Contents</h2>
307
+ <ul class="toc-list" id="toc-list">
308
+ <!-- TOC items will be populated by JavaScript -->
309
+ </ul>
310
+ </div>
311
+ </aside>
22
312
  </div>
313
+ <!-- simple_webpage end main_content block -->
23
314
  {% endblock main_content %}
24
- <!-- simple_webpage end main_content block -->
315
+
316
+
317
+ {% block scripts_extra %}
318
+ {{ super() }}
319
+ <!-- simple_webpage begin scripts_extra block -->
320
+ <script>
321
+ // Table of Contents functionality
322
+ function initTOC() {
323
+ const tocContainer = document.getElementById('toc-container');
324
+ const tocList = document.getElementById('toc-list');
325
+ const tocToggle = document.getElementById('toc-toggle');
326
+ const contentContainer = document.getElementById('content-container');
327
+ const mainContent = document.getElementById('main-content');
328
+
329
+ if (!tocContainer || !tocList || !mainContent) {
330
+ console.debug("TOC not initialized: missing elements");
331
+ return;
332
+ }
333
+
334
+ const tocBreakpoint = parseInt(
335
+ getComputedStyle(document.documentElement)
336
+ .getPropertyValue('--toc-breakpoint')
337
+ .replace('px', '')
338
+ );
339
+
340
+ // Find all headings in the main content
341
+ const headings = mainContent.querySelectorAll('{{ toc_headings | default("h1, h2, h3") }}');
342
+ // Only show TOC if we have toc_min_headings (default 10) or more headings
343
+ const tocThreshold = {{ toc_min_headings | default(10) }};
344
+
345
+ if (headings.length < tocThreshold) {
346
+ // TOC is disabled
347
+ if (tocToggle) {
348
+ tocToggle.style.display = 'none';
349
+ }
350
+ console.debug("TOC hidden: not enough headings");
351
+ return;
352
+ }
353
+
354
+ // TOC is enabled
355
+ contentContainer.classList.add('has-toc'); // This triggers grid layout
356
+ mainContent.classList.add('with-toc');
357
+ document.body.classList.add('page-has-toc');
358
+
359
+ if (tocToggle) {
360
+ tocToggle.style.display = 'flex';
361
+ // Ensure feather icon is rendered after making visible
362
+ if (typeof feather !== 'undefined') {
363
+ feather.replace();
364
+ }
365
+ }
366
+
367
+ // Generate TOC items
368
+ tocList.innerHTML = '';
369
+
370
+ // If there is only one h1, skip it as it is the title of the page.
371
+ let filteredHeadings = Array.from(headings);
372
+ if (headings.length > 0) {
373
+ const firstHeading = headings[0];
374
+ const h1Count = filteredHeadings.filter(h => h.tagName.toLowerCase() === 'h1').length;
375
+
376
+ if (firstHeading.tagName.toLowerCase() === 'h1' && h1Count === 1) {
377
+ filteredHeadings = filteredHeadings.slice(1);
378
+ }
379
+ }
380
+
381
+ filteredHeadings.forEach((heading, index) => {
382
+ // Ensure heading has an ID
383
+ if (!heading.id) {
384
+ const text = heading.textContent.trim().toLowerCase()
385
+ .replace(/[^\w\s-]/g, '')
386
+ .replace(/\s+/g, '-')
387
+ .replace(/-+/g, '-')
388
+ .replace(/^-|-$/g, '');
389
+ heading.id = text || `heading-${index}`;
390
+ }
391
+
392
+ const level = heading.tagName.toLowerCase();
393
+ const text = heading.textContent.trim();
394
+
395
+ const li = document.createElement('li');
396
+ const a = document.createElement('a');
397
+ a.href = `#${heading.id}`;
398
+ a.textContent = text;
399
+ a.className = `toc-link toc-${level}`;
400
+
401
+ li.appendChild(a);
402
+ tocList.appendChild(li);
403
+ });
404
+
405
+ // Mobile TOC toggle functionality
406
+ if (tocToggle) {
407
+ const tocBackdrop = document.getElementById('toc-backdrop');
408
+ let scrollPosition = 0;
409
+
410
+ const openTOC = () => {
411
+ // Save current scroll position
412
+ scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
413
+
414
+ // Add classes to show TOC and prevent body scroll
415
+ tocContainer.classList.add('mobile-visible');
416
+ if (tocBackdrop) tocBackdrop.classList.add('visible');
417
+ document.body.classList.add('toc-open');
418
+
419
+ // Set body position to maintain scroll position while fixed
420
+ document.body.style.top = `-${scrollPosition}px`;
421
+ };
422
+
423
+ const closeTOC = () => {
424
+ // Remove classes
425
+ tocContainer.classList.remove('mobile-visible');
426
+ if (tocBackdrop) tocBackdrop.classList.remove('visible');
427
+ document.body.classList.remove('toc-open');
428
+
429
+ // Restore body position and scroll
430
+ document.body.style.top = '';
431
+ window.scrollTo(0, scrollPosition);
432
+ };
433
+
434
+ tocToggle.addEventListener('click', () => {
435
+ if (tocContainer.classList.contains('mobile-visible')) {
436
+ closeTOC();
437
+ } else {
438
+ openTOC();
439
+ }
440
+ });
441
+
442
+ // Close TOC when clicking backdrop
443
+ if (tocBackdrop) {
444
+ tocBackdrop.addEventListener('click', closeTOC);
445
+ }
446
+
447
+ // Update the existing click handler to use closeTOC
448
+ document.addEventListener('click', (e) => {
449
+ if (window.innerWidth < tocBreakpoint &&
450
+ tocContainer.classList.contains('mobile-visible') &&
451
+ !tocContainer.contains(e.target) &&
452
+ !tocToggle.contains(e.target)) {
453
+ closeTOC();
454
+ }
455
+ });
456
+
457
+ // Prevent touch events from propagating through TOC
458
+ tocContainer.addEventListener('touchmove', (e) => {
459
+ e.stopPropagation();
460
+ }, { passive: false });
461
+ }
462
+
463
+ // Add smooth scrolling and active state management
464
+ const tocLinks = tocList.querySelectorAll('.toc-link');
465
+ tocLinks.forEach(link => {
466
+ link.addEventListener('click', (e) => {
467
+ e.preventDefault();
468
+ const targetId = link.getAttribute('href').substring(1);
469
+ const target = document.getElementById(targetId);
470
+
471
+ if (target) {
472
+ // Close TOC first on mobile
473
+ if (window.innerWidth < tocBreakpoint) {
474
+ tocContainer.classList.remove('mobile-visible');
475
+ document.getElementById('toc-backdrop')?.classList.remove('visible');
476
+ document.body.classList.remove('toc-open');
477
+ document.body.style.top = '';
478
+ }
479
+
480
+ target.scrollIntoView({
481
+ behavior: 'smooth',
482
+ block: 'start'
483
+ });
484
+ tocLinks.forEach(l => l.classList.remove('active'));
485
+ link.classList.add('active');
486
+
487
+ }
488
+ });
489
+ });
490
+
491
+ // Helper function to check if TOC toggle should be visible
492
+ const updateTocToggleVisibility = () => {
493
+ if (tocToggle && tocLinks.length > 0) {
494
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
495
+ const activeLink = tocList.querySelector('.toc-link.active');
496
+ const firstTocLink = tocLinks[0];
497
+
498
+ // Only show toggle if:
499
+ // 1. We've scrolled down at least 100px from the top, AND
500
+ // 2. We're past the first section (activeLink exists and is not the first)
501
+ const hasScrolled = scrollTop > 100;
502
+ const isPastFirstSection = activeLink && activeLink !== firstTocLink;
503
+ const showToggle = hasScrolled && isPastFirstSection;
504
+
505
+ tocToggle.classList.toggle('show-toggle', showToggle);
506
+ }
507
+ };
508
+
509
+ // Intersection Observer for active state
510
+ const observerOptions = {
511
+ rootMargin: '-20% 0% -70% 0%',
512
+ threshold: 0
513
+ };
514
+ const observer = new IntersectionObserver((entries) => {
515
+ entries.forEach(entry => {
516
+ if (entry.isIntersecting) {
517
+ tocLinks.forEach(link => link.classList.remove('active'));
518
+ const activeLink = tocList.querySelector(`a[href="#${entry.target.id}"]`);
519
+ if (activeLink) {
520
+ activeLink.classList.add('active');
521
+ }
522
+ }
523
+ });
524
+
525
+ // Update toggle visibility after intersection changes
526
+ updateTocToggleVisibility();
527
+ }, observerOptions);
528
+
529
+ filteredHeadings.forEach(heading => observer.observe(heading));
530
+
531
+ // Update toggle visibility on scroll
532
+ let scrollTimeout;
533
+ window.addEventListener('scroll', () => {
534
+ // Throttle scroll events for performance
535
+ clearTimeout(scrollTimeout);
536
+ scrollTimeout = setTimeout(updateTocToggleVisibility, 16); // ~60fps
537
+ });
538
+
539
+ // Initial check
540
+ updateTocToggleVisibility();
541
+ }
542
+
543
+ // Initialize immediately, no setTimeout
544
+ document.addEventListener('DOMContentLoaded', () => {
545
+ initTOC();
546
+ if (typeof feather !== 'undefined') {
547
+ feather.replace();
548
+ }
549
+ });
550
+ </script>
551
+ <!-- simple_webpage end scripts_extra block -->
552
+ {% endblock scripts_extra %}
@@ -40,8 +40,9 @@
40
40
  {% endblock page_content %}
41
41
  <!-- tabbed_webpage end page_content block -->
42
42
 
43
- <!-- tabbed_webpage begin scripts_extra block -->
44
43
  {% block scripts_extra %}
44
+ <!-- tabbed_webpage begin scripts_extra block -->
45
+ <script>
45
46
  function showTab(tabId, element) {
46
47
  document.querySelectorAll(".tab-pane").forEach((tab) => {
47
48
  tab.classList.add("hidden");
@@ -54,5 +55,6 @@
54
55
  element.classList.add("tab-button-active");
55
56
  element.classList.remove("tab-button-inactive");
56
57
  }
58
+ </script>
59
+ <!-- tabbed_webpage end scripts_extra block -->
57
60
  {% endblock scripts_extra %}
58
- <!-- tabbed_webpage end scripts_extra block -->
@@ -12,7 +12,6 @@ Can run from the custom kash shell (main.py) or from a regular xonsh shell.
12
12
  import kash.exec.command_registry
13
13
  import kash.xonsh_custom.load_into_xonsh
14
14
  import kash.xonsh_custom.xonsh_env
15
- from kash.config.logger import get_logger
16
15
 
17
16
 
18
17
  # We add action loading here directly in the xontrib so we expose `load` and
@@ -55,6 +54,8 @@ kash.xonsh_custom.xonsh_env.set_alias("load", load)
55
54
  try:
56
55
  kash.xonsh_custom.load_into_xonsh.load_into_xonsh()
57
56
  except Exception as e:
57
+ from kash.config.logger import get_logger
58
+
58
59
  log = get_logger(__name__)
59
- log.error("Could not initialize kash: %s", e)
60
+ log.error("Could not initialize kash: %s", e, exc_info=True)
60
61
  raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.15
3
+ Version: 0.3.17
4
4
  Summary: The knowledge agent shell (core)
5
5
  Project-URL: Repository, https://github.com/jlevy/kash-shell
6
6
  Author-email: Joshua Levy <joshua@cal.berkeley.edu>