Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
18e7ccf
Add custom Kapa handoff ticket flow for docs chat
dannyneira Jul 23, 2026
939c966
Fix PR preview build for Kapa handoff API route
dannyneira Jul 23, 2026
6c0eb87
Fix preview build by moving handoff endpoint off /api
dannyneira Jul 23, 2026
5a22dc9
docs: document MCP OAuth workarounds (#422)
dannyneira Jul 30, 2026
4a9c518
Replace custom Kapa chat with website widget
dannyneira Jul 30, 2026
b5ebf2e
Tweak Ask AI widget title and panel behavior
dannyneira Jul 30, 2026
a6048d3
Hide Ask tooltip while Kapa panel is open
dannyneira Jul 30, 2026
c805b22
Move Ask tooltip above the panel
dannyneira Jul 30, 2026
93f73dd
Suppress clipped Kapa attachment tooltip artifact
dannyneira Jul 30, 2026
fd762df
Broaden Kapa tooltip suppression for portal tooltips
dannyneira Jul 30, 2026
05d2674
Revert "Broaden Kapa tooltip suppression for portal tooltips"
dannyneira Jul 30, 2026
cfdf79e
Revert "Suppress clipped Kapa attachment tooltip artifact"
dannyneira Jul 30, 2026
7e955bc
Revert "Move Ask tooltip above the panel"
dannyneira Jul 30, 2026
6a5cef3
Revert "Hide Ask tooltip while Kapa panel is open"
dannyneira Jul 30, 2026
1e12da1
Allow Vercel live feedback script in CSP
dannyneira Jul 30, 2026
97b247d
Stabilize Kapa preview CORS and CSP allowances
dannyneira Jul 30, 2026
05572a2
Adjust Kapa answer bubble padding
dannyneira Jul 30, 2026
c8c6a12
Add focus dim effect behind Kapa sidebar
dannyneira Jul 30, 2026
60edc9a
Remove Kapa sidebar focus blur overlay
dannyneira Jul 30, 2026
98b7933
Add spacing between Kapa question and answer bubbles
dannyneira Jul 30, 2026
8a85cc6
Tune Kapa handoff trigger conditions
dannyneira Jul 30, 2026
57e560b
Disable Kapa feedback survey prompts
dannyneira Jul 31, 2026
875f234
Restore custom Kapa chat with trigger-based support handoff
dannyneira Aug 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@
# Values below are PUBLIC (they're shipped to the browser by Astro's
# `envField`, and live behind rate limiting / allow-lists on the vendor side).

# Kapa Custom Frontend integration ID for the "Ask AI" button in the header.
# If unset, the Ask AI button is hidden and the site still runs normally.
# Get yours at: https://app.kapa.ai/admin
# Kapa Website Widget integration ID for the "Ask AI" button in the sidebar.
# If unset, docs falls back to the shared widget integration ID used in preview/prod.
# Get yours at: https://app.kapa.ai/admin (Integrations → Widget → Copy integration ID).
# The same value is passed to the widget as `data-website-id`.
# PUBLIC_KAPA_INTEGRATION_ID=f31c5644-dd65-4f49-9762-bf580062afa8
PUBLIC_KAPA_INTEGRATION_ID=

# Optional Kapa project ID used to build internal conversation links in
# "Create ticket" email drafts:
# https://app.kapa.ai/<PROJECT_ID>/conversations/<THREAD_ID>
# You can find this in the Kapa dashboard URL while viewing the project.
PUBLIC_KAPA_PROJECT_ID=

# RudderStack analytics — required for docs_404 event tracking and page analytics.
# Without these, no analytics events are sent and the weekly 404 monitor will
# report zero data. Set both in the Vercel project environment (all environments).
Expand Down
5 changes: 5 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export default defineConfig({
access: 'public',
optional: true,
}),
PUBLIC_KAPA_PROJECT_ID: envField.string({
context: 'client',
access: 'public',
optional: true,
}),
PUBLIC_RUDDERSTACK_WRITE_KEY: envField.string({
context: 'client',
access: 'public',
Expand Down
1,542 changes: 797 additions & 745 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"overrides": {
"path-to-regexp": "^6.3.0",
"esbuild": "^0.28.1",
"vite": "7.3.5",
"vite": "^8.0.13",
"@babel/core": ">=7.29.6",
"@astrojs/markdown-remark": "^7.2.0",
"tar": "^7.5.16"
Expand Down
12 changes: 6 additions & 6 deletions src/components/CustomSidebar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ import KapaLauncher from './KapaLauncher.astro';
'api': 'API',
};

// Detect Apple platforms once so the Ask AI kbd reads ⌘+I on Macs and
// Ctrl+I elsewhere. Mirrors KapaChatLauncher.tsx which binds the same
// shortcut via keymatch's `CmdOrCtrl+I`.
// Detect Apple platforms once so the Ask AI kbd reads ⌘+I on Macs and
// Ctrl+I elsewhere. Mirrors KapaLauncher.astro which binds the same
// shortcut for opening the Kapa Website Widget.
var isMac = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform || '');
var modKey = isMac ? '\u2318' : 'Ctrl';

Expand Down Expand Up @@ -143,9 +143,9 @@ import KapaLauncher from './KapaLauncher.astro';
+ '</svg>'
+ '<span class="warp-search-ask-ai-row__label">Ask AI</span>'
+ '<kbd class="warp-search-ask-ai-row__kbd" aria-hidden="true">' + modKey + '<span class="warp-search-ask-ai-row__kbd-plus">+</span>I</kbd>';
askAi.addEventListener('click', function () {
// openPanel() in KapaChatLauncher reads the live search input and
// closes the search dialog itself, so we just route the click.
askAi.addEventListener('click', function () {
// KapaLauncher reads the live search input and closes the search
// dialog itself, then opens the widget with that query prefilled.
var kapaBtn = document.querySelector('.warp-kapa-button');
if (kapaBtn) kapaBtn.click();
});
Expand Down
172 changes: 172 additions & 0 deletions src/components/KapaChatLauncher.css
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,41 @@

.sl-kapa-feedback {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
margin-top: 0.875rem;
}
.sl-kapa-feedback__handoff {
display: inline-flex;
align-items: center;
justify-content: center;
height: 2.25rem;
padding: 0 0.75rem;
border: 1px solid var(--sl-color-gray-5);
border-radius: var(--sl-radius-sm);
background: var(--sl-color-black);
color: var(--sl-color-gray-1);
font: inherit;
font-size: var(--sl-text-xs);
font-weight: 500;
cursor: pointer;
transition:
border-color 0.15s ease,
background-color 0.15s ease,
color 0.15s ease;
}

.sl-kapa-feedback__handoff:hover {
border-color: var(--warp-control-border-hover);
background: var(--warp-control-bg-hover);
color: var(--sl-color-white);
}

.sl-kapa-feedback__handoff:focus-visible {
outline: 2px solid var(--sl-color-accent-high);
outline-offset: 2px;
}

.sl-kapa-error {
border: 1px solid color-mix(in srgb, #ef4444, var(--sl-color-black) 35%);
Expand Down Expand Up @@ -338,6 +370,146 @@
cursor: not-allowed;
}

.sl-kapa-handoff {
margin-top: 0.75rem;
display: flex;
flex-direction: column;
gap: 0.625rem;
}

.sl-kapa-handoff__toggle {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
width: 100%;
height: 2.5rem;
padding: 0 0.875rem;
border: 1px solid var(--sl-color-gray-5);
border-radius: var(--sl-radius-sm);
background: var(--sl-color-black);
color: var(--sl-color-gray-1);
font: inherit;
font-size: var(--sl-text-sm);
font-weight: 500;
cursor: pointer;
transition:
border-color 0.15s ease,
background-color 0.15s ease,
color 0.15s ease;
}

.sl-kapa-handoff__toggle svg {
width: 0.95rem;
height: 0.95rem;
flex: none;
}

.sl-kapa-handoff__toggle:hover {
border-color: var(--warp-control-border-hover);
background: var(--warp-control-bg-hover);
color: var(--sl-color-white);
}

.sl-kapa-handoff__toggle:focus-visible {
outline: 2px solid var(--sl-color-accent-high);
outline-offset: 2px;
}

.sl-kapa-handoff__form {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.75rem;
border: 1px solid var(--sl-color-gray-5);
border-radius: var(--sl-radius-lg);
background: color-mix(in srgb, var(--sl-color-black), var(--sl-color-gray-6) 28%);
}

.sl-kapa-handoff__form label {
display: flex;
flex-direction: column;
gap: 0.25rem;
}

.sl-kapa-handoff__form label span {
font-size: var(--sl-text-2xs);
color: var(--sl-color-gray-3);
}

.sl-kapa-handoff__form input,
.sl-kapa-handoff__form textarea {
width: 100%;
border: 1px solid var(--sl-color-gray-5);
border-radius: var(--sl-radius-sm);
background: var(--sl-color-black);
color: var(--sl-color-white);
padding: 0.5rem 0.625rem;
font: inherit;
font-size: var(--sl-text-sm);
}

.sl-kapa-handoff__form textarea {
resize: vertical;
min-height: 4rem;
}

.sl-kapa-handoff__form input::placeholder,
.sl-kapa-handoff__form textarea::placeholder {
color: var(--sl-color-gray-3);
}

.sl-kapa-handoff__form input:focus-visible,
.sl-kapa-handoff__form textarea:focus-visible {
outline: 2px solid var(--sl-color-accent-high);
outline-offset: 2px;
}

.sl-kapa-handoff__submit {
margin-top: 0.25rem;
height: 2.5rem;
border: 1px solid var(--sl-color-text-accent);
border-radius: var(--sl-radius-sm);
background: var(--sl-color-text-accent);
color: var(--sl-color-black);
font: inherit;
font-size: var(--sl-text-sm);
font-weight: 600;
cursor: pointer;
transition:
border-color 0.15s ease,
background-color 0.15s ease;
}

.sl-kapa-handoff__submit:hover:not(:disabled) {
border-color: color-mix(in srgb, var(--sl-color-text-accent), var(--sl-color-white) 18%);
background: color-mix(in srgb, var(--sl-color-text-accent), var(--sl-color-white) 8%);
}

.sl-kapa-handoff__submit:focus-visible {
outline: 2px solid var(--sl-color-accent-high);
outline-offset: 2px;
}

.sl-kapa-handoff__submit:disabled {
opacity: 0.55;
cursor: not-allowed;
}

.sl-kapa-handoff__status {
margin: 0;
font-size: var(--sl-text-xs);
line-height: 1.4;
}

.sl-kapa-handoff__status--success {
color: #86efac;
}

.sl-kapa-handoff__status--error {
color: #fecaca;
}

/* Hide the reCAPTCHA badge */
.grecaptcha-badge {
visibility: hidden;
Expand Down
Empty file.
Loading