jamdesk 1.1.27 → 1.1.29

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <a href="https://www.jamdesk.com">
3
- <img src="https://www.jamdesk.com/logo-light.png" width="280" alt="Jamdesk" />
3
+ <img src="https://www.jamdesk.com/logo-universal.png" width="280" alt="Jamdesk" />
4
4
  </a>
5
5
  </p>
6
6
 
@@ -435,6 +435,7 @@ See the [docs.json reference](https://www.jamdesk.com/docs/config/docs-json-refe
435
435
 
436
436
  - Node.js v20.0.0+
437
437
  - npm v8+ (recommended)
438
+ - macOS, Linux, or Windows (all tested in CI)
438
439
 
439
440
  ## Learn More
440
441
 
@@ -446,6 +447,7 @@ See the [docs.json reference](https://www.jamdesk.com/docs/config/docs-json-refe
446
447
  - [OpenAPI](https://www.jamdesk.com/docs/api-reference/openapi-setup)
447
448
  - [Deployment](https://www.jamdesk.com/docs/deploy)
448
449
  - [npm Package](https://www.npmjs.com/package/jamdesk)
450
+ - [Release History](https://www.npmjs.com/package/jamdesk?activeTab=versions)
449
451
  - [Homepage](https://www.jamdesk.com)
450
452
  - [Pricing](https://www.jamdesk.com/pricing)
451
453
 
package/dist/lib/deps.js CHANGED
@@ -23,13 +23,13 @@ const JAMDESK_DIR = path.join(homedir(), '.jamdesk');
23
23
  // compiled dist/lib/deps.js instead of re-parsing the TypeScript source.
24
24
  export const REQUIRED_DEPS = {
25
25
  // Next.js and React
26
- 'next': '16.2.3',
26
+ 'next': '^16.2.4',
27
27
  // OpenAPI validation (for API reference docs)
28
28
  '@apidevtools/swagger-parser': '^12.1.0',
29
29
  'openapi-types': '^12.1.3',
30
30
  'react': '^19.2.4',
31
31
  'react-dom': '^19.2.4',
32
- '@next/mdx': '16.2.3',
32
+ '@next/mdx': '^16.2.4',
33
33
  'next-mdx-remote': '^6.0.0',
34
34
  'next-themes': '^0.4.6',
35
35
  // Icons
@@ -76,7 +76,7 @@ export const REQUIRED_DEPS = {
76
76
  'tailwindcss': '^4.2.2',
77
77
  '@tailwindcss/postcss': '^4.2.2',
78
78
  '@tailwindcss/typography': '^0.5.10',
79
- 'postcss': '^8.5.9',
79
+ 'postcss': '^8.5.10',
80
80
  'autoprefixer': '^10.4.24',
81
81
  // Script dependencies (for vendored scripts)
82
82
  'fs-extra': '^11.3.3',
@@ -87,7 +87,7 @@ export const REQUIRED_DEPS = {
87
87
  '@types/node': '^25.5.2',
88
88
  '@types/react': '^19.2.14',
89
89
  '@types/react-dom': '^19.0.0',
90
- '@next/third-parties': '16.2.3',
90
+ '@next/third-parties': '^16.2.4',
91
91
  };
92
92
  /**
93
93
  * Generate a hash of REQUIRED_DEPS to detect when dependencies change.
@@ -1 +1 @@
1
- {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/lib/deps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/lib/deps.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jamdesk",
3
- "version": "1.1.27",
3
+ "version": "1.1.29",
4
4
  "description": "CLI for Jamdesk — build, preview, and deploy documentation sites from MDX. Dev server with hot reload, 50+ components, OpenAPI support, AI search, and Mintlify migration",
5
5
  "keywords": [
6
6
  "jamdesk",
@@ -22,10 +22,14 @@
22
22
  */
23
23
  import { NextRequest } from 'next/server';
24
24
  import { querySimilarChunks } from '@/lib/vector-store';
25
- import { buildSystemPrompt } from '@/lib/chat-prompt';
25
+ import { buildSystemPrompt, isCannedIdentityReply, resolveSiteName } from '@/lib/chat-prompt';
26
26
  import { getDocsPath, getBaseUrl, trackChatAnalytics } from '@/lib/route-helpers';
27
27
  import { getAnthropicClient } from '@/lib/anthropic-client';
28
+ import { rewriteQueryForSearch } from '@/lib/query-rewriter';
29
+ import { fetchDocsConfig } from '@/lib/r2-content';
28
30
  import { redis } from '@/lib/redis';
31
+ import { CHAT_TOOLS } from '@/lib/chat-tools';
32
+ import { log } from '@/lib/logger';
29
33
 
30
34
  export const runtime = 'nodejs';
31
35
  export const maxDuration = 30;
@@ -36,113 +40,6 @@ const RATE_WINDOW_SECONDS = 60;
36
40
  const MAX_HISTORY = 10;
37
41
  const VALID_ROLES = new Set<string>(['user', 'assistant']);
38
42
 
39
- /**
40
- * Extract citations from Claude's response by matching [Title] references
41
- * against the vector search chunks. Deduplicates by page slug.
42
- * Falls back to top 2 unique pages by score if Claude didn't cite anything.
43
- */
44
- type Citation = { title: string; slug: string; section?: string };
45
- type ScoredChunk = { pageSlug: string; pageTitle: string; sectionHeading: string; score: number };
46
-
47
- function extractCitations(
48
- responseText: string,
49
- chunks: ScoredChunk[],
50
- ): { sources: Citation[]; hadExplicitCitations: boolean } {
51
- // Match [Title] but not markdown links [text](url)
52
- const referencedTitles = new Set(
53
- Array.from(responseText.matchAll(/\[([^\]]+)\](?!\()/g), (m) => m[1]),
54
- );
55
-
56
- const seen = new Set<string>();
57
- const sources: Citation[] = [];
58
-
59
- function addUniqueChunk(c: (typeof chunks)[number]): void {
60
- if (seen.has(c.pageSlug)) return;
61
- seen.add(c.pageSlug);
62
- sources.push({ title: c.pageTitle, slug: c.pageSlug, section: c.sectionHeading });
63
- }
64
-
65
- // Filter chunks to only those Claude referenced, deduplicate by slug
66
- for (const c of chunks) {
67
- if (referencedTitles.has(c.pageTitle)) addUniqueChunk(c);
68
- }
69
-
70
- // Record whether Claude explicitly cited sources before the fallback
71
- const hadExplicitCitations = sources.length > 0;
72
-
73
- // Fallback: if Claude didn't cite anything explicitly, show top 2 unique pages by score
74
- if (sources.length === 0) {
75
- for (const c of chunks) {
76
- addUniqueChunk(c);
77
- if (sources.length >= 2) break;
78
- }
79
- }
80
-
81
- return { sources, hadExplicitCitations };
82
- }
83
-
84
- /**
85
- * Detect option lists in Claude's response that indicate a clarification question.
86
- * Returns extracted option strings, or null if the response is a normal answer.
87
- *
88
- * Heuristic guards to avoid false positives on instructional lists:
89
- * - Response must contain a question mark or colon (clarification Qs ask something)
90
- * - Response must be short (< 500 chars — clarification Qs are brief)
91
- * - Must be 2-3 items (instructional lists tend to be longer)
92
- * - List must be at the END of the response
93
- *
94
- * Supports numbered (1. 2. 3.) and unnumbered (plain lines) formats.
95
- * Strips markdown formatting (bold, backticks) from option text.
96
- */
97
- export function extractClarificationOptions(responseText: string): string[] | null {
98
- // Trim trailing whitespace/newlines so the $ anchor in option-list regexes
99
- // matches reliably — SSE text deltas can include trailing newlines.
100
- const text = responseText.trimEnd();
101
-
102
- // Must indicate a question. A `?` always qualifies. A `:` only qualifies when
103
- // the preamble contains clarification words (to avoid false positives on
104
- // instructional lists like "To enable dark mode:\n\n1. Open Settings").
105
- const hasQuestion = text.includes('?');
106
- const hasClarificationColon = !hasQuestion
107
- && text.includes(':')
108
- && /\b(which|what|clarify|interested|looking for|asking|type of|kind of)\b/i.test(text);
109
- if (!hasQuestion && !hasClarificationColon) return null;
110
-
111
- // Only short responses are likely clarification questions
112
- if (text.length > 500) return null;
113
-
114
- // Strip markdown formatting (bold, italic, backticks) from option labels
115
- function cleanOption(text: string): string {
116
- return text.trim().replace(/[*`]/g, '');
117
- }
118
-
119
- // Primary: numbered list (1. 2. 3.) at the end
120
- const numbered = text.match(
121
- /\n\n1\.\s+(.+)\n2\.\s+(.+)(?:\n3\.\s+(.+))?$/,
122
- );
123
- if (numbered) {
124
- const options = [cleanOption(numbered[1]), cleanOption(numbered[2])];
125
- if (numbered[3]) options.push(cleanOption(numbered[3]));
126
- return options;
127
- }
128
-
129
- // Fallback: unnumbered list (2-3 short lines at the end, after a blank line)
130
- // Each line must be short (< 80 chars) and non-empty to distinguish from paragraphs
131
- const unnumbered = text.match(
132
- /\n\n([^\n]{2,80})\n([^\n]{2,80})(?:\n([^\n]{2,80}))?$/,
133
- );
134
- if (unnumbered) {
135
- // Extra guard: lines must NOT look like sentences (no periods at end)
136
- const lines = [unnumbered[1], unnumbered[2], unnumbered[3]].filter(Boolean) as string[];
137
- const looksLikeOptions = lines.every(l => !l.trim().endsWith('.') && l.trim().length < 80);
138
- if (looksLikeOptions && lines.length >= 2) {
139
- return lines.map(cleanOption);
140
- }
141
- }
142
-
143
- return null;
144
- }
145
-
146
43
  export async function POST(
147
44
  request: NextRequest,
148
45
  context: { params: Promise<{ project: string }> },
@@ -209,10 +106,45 @@ export async function POST(
209
106
  }
210
107
  }
211
108
 
212
- // Query Upstash Vector for relevant chunks
213
- let chunks: Awaited<ReturnType<typeof querySimilarChunks>>;
109
+ // Kick off docsPath (Redis) + config (R2) lookups in parallel with the
110
+ // vector search below. Per-promise .catch prevents unhandled rejections
111
+ // if an early return (vector error, empty chunks, missing client) leaves
112
+ // sideWork un-awaited.
113
+ const originalHost = request.headers.get('x-jamdesk-forwarded-host')
114
+ || request.headers.get('x-original-host') || '';
115
+ const sideWork = Promise.all([
116
+ getDocsPath(project, originalHost).catch(() => ''),
117
+ fetchDocsConfig(project).catch(() => null),
118
+ ]);
119
+
120
+ // Fully parallel retrieval:
121
+ // - Original vector query runs immediately.
122
+ // - Rewriter + rewritten-query vector search are chained into ONE promise,
123
+ // then Promise.all'd with the original. Critical path is
124
+ // max(original_query_time, rewriter_time + rewritten_query_time), not
125
+ // max(original, rewriter) + rewritten_query_time.
126
+ // Any failure in the rewrite path resolves to an empty chunk list — the
127
+ // original query still returns results so chat doesn't fail.
128
+ const originalQueryPromise = querySimilarChunks(project, searchQuery, 15);
129
+
130
+ const rewrittenPathPromise: Promise<Awaited<ReturnType<typeof querySimilarChunks>>> =
131
+ rewriteQueryForSearch(message, history)
132
+ .catch(() => null)
133
+ .then(rewritten => {
134
+ // Compare against `message` (the rewriter's input), not `searchQuery`
135
+ // (which is enriched with prior-turn context for short follow-ups).
136
+ // The rewriter only sees `message`, so a no-op rewrite equals `message`.
137
+ if (!rewritten || rewritten === message) return [];
138
+ return querySimilarChunks(project, rewritten, 15).catch(() => []);
139
+ });
140
+
141
+ let originalChunks: Awaited<ReturnType<typeof querySimilarChunks>>;
142
+ let rewrittenChunks: Awaited<ReturnType<typeof querySimilarChunks>>;
214
143
  try {
215
- chunks = await querySimilarChunks(project, searchQuery, 8);
144
+ [originalChunks, rewrittenChunks] = await Promise.all([
145
+ originalQueryPromise,
146
+ rewrittenPathPromise,
147
+ ]);
216
148
  } catch {
217
149
  return Response.json(
218
150
  { error: 'AI chat is not available for this project.' },
@@ -220,6 +152,21 @@ export async function POST(
220
152
  );
221
153
  }
222
154
 
155
+ // Merge: original chunks first (they match the user's literal phrasing),
156
+ // then unique chunks from the rewritten query. Dedup by pageSlug +
157
+ // sectionHeading — chunks with the same identity are interchangeable across
158
+ // queries.
159
+ const seenKeys = new Set(originalChunks.map(c => `${c.pageSlug}#${c.sectionHeading}`));
160
+ const chunks = [
161
+ ...originalChunks,
162
+ ...rewrittenChunks.filter(c => {
163
+ const key = `${c.pageSlug}#${c.sectionHeading}`;
164
+ if (seenKeys.has(key)) return false;
165
+ seenKeys.add(key);
166
+ return true;
167
+ }),
168
+ ];
169
+
223
170
  if (chunks.length === 0) {
224
171
  return Response.json(
225
172
  { error: 'No documentation content found for this project.' },
@@ -235,25 +182,19 @@ export async function POST(
235
182
  );
236
183
  }
237
184
 
238
- // Resolve project URLs falls back to defaults if R2/config unavailable
239
- const originalHost = request.headers.get('x-jamdesk-forwarded-host')
240
- || request.headers.get('x-original-host') || '';
185
+ const [docsPath, config] = await sideWork;
241
186
  const baseUrl = getBaseUrl(project, originalHost);
242
- let docsPath: string;
243
- try {
244
- docsPath = await getDocsPath(project, originalHost);
245
- } catch {
246
- docsPath = '';
247
- }
187
+ const siteName = resolveSiteName(config);
248
188
 
249
- // Build system prompt with retrieved context
250
- const systemPrompt = buildSystemPrompt(project, chunks, baseUrl, docsPath);
189
+ const systemPrompt = buildSystemPrompt(siteName, chunks, baseUrl, docsPath);
251
190
 
252
191
  const stream = anthropic.messages.stream({
253
192
  model: CHAT_MODEL,
254
193
  max_tokens: 2048,
255
194
  temperature: 0.3,
256
195
  system: systemPrompt,
196
+ tools: CHAT_TOOLS,
197
+ tool_choice: { type: 'any' },
257
198
  messages: [
258
199
  ...history.slice(-MAX_HISTORY),
259
200
  { role: 'user', content: message },
@@ -265,35 +206,127 @@ export async function POST(
265
206
  return encoder.encode(`data: ${JSON.stringify(data)}\n\n`);
266
207
  }
267
208
 
209
+ type Citation = { title: string; slug: string; section?: string };
210
+ type AnswerInput = { markdown?: string; cited_page_slugs?: string[] };
211
+ type ClarificationInput = { question?: string; options?: string[] };
212
+
213
+ function topChunksAsCitations(limit = 2, skip?: Set<string>): Citation[] {
214
+ const out: Citation[] = [];
215
+ const seen = new Set<string>(skip);
216
+ for (const c of chunks) {
217
+ if (seen.has(c.pageSlug)) continue;
218
+ seen.add(c.pageSlug);
219
+ out.push({ title: c.pageTitle, slug: c.pageSlug, section: c.sectionHeading });
220
+ if (out.length >= limit) break;
221
+ }
222
+ return out;
223
+ }
224
+
268
225
  const readable = new ReadableStream({
269
226
  async start(controller) {
270
- let fullText = '';
227
+ let toolName: string | null = null;
228
+ let emittedMarkdownLength = 0;
229
+ let emittedQuestionLength = 0;
230
+
231
+ stream.on('inputJson', (_partialJson, jsonSnapshot) => {
232
+ if (!jsonSnapshot || typeof jsonSnapshot !== 'object') return;
233
+
234
+ // Gate on toolName — emitting before content_block_start resolves
235
+ // would leak clarification JSON into the answer text channel.
236
+ if (toolName === 'answer') {
237
+ const snap = jsonSnapshot as AnswerInput;
238
+ if (typeof snap.markdown === 'string' && snap.markdown.length > emittedMarkdownLength) {
239
+ const newContent = snap.markdown.slice(emittedMarkdownLength);
240
+ emittedMarkdownLength = snap.markdown.length;
241
+ controller.enqueue(sendEvent({ type: 'text', content: newContent }));
242
+ }
243
+ } else if (toolName === 'ask_clarification') {
244
+ const snap = jsonSnapshot as ClarificationInput;
245
+ if (typeof snap.question === 'string' && snap.question.length > emittedQuestionLength) {
246
+ const newContent = snap.question.slice(emittedQuestionLength);
247
+ emittedQuestionLength = snap.question.length;
248
+ controller.enqueue(sendEvent({ type: 'text', content: newContent }));
249
+ }
250
+ }
251
+ });
271
252
 
272
253
  try {
254
+ // Watch for content_block_start to learn which tool Claude picked.
273
255
  for await (const event of stream) {
274
- if (event.type === 'content_block_delta' && event.delta.type === 'text_delta') {
275
- fullText += event.delta.text;
276
- controller.enqueue(sendEvent({ type: 'text', content: event.delta.text }));
256
+ if (event.type === 'content_block_start' && event.content_block.type === 'tool_use') {
257
+ toolName = event.content_block.name;
277
258
  }
278
259
  }
279
260
 
280
- // After streaming completes, get token usage
281
261
  const finalMessage = await stream.finalMessage();
282
262
  const inputTokens = finalMessage.usage?.input_tokens ?? 0;
283
263
  const outputTokens = finalMessage.usage?.output_tokens ?? 0;
284
264
 
285
- // Extract clarification options (if Claude asked a disambiguation question)
286
- const options = extractClarificationOptions(fullText);
287
- if (options) {
265
+ // With tool_choice: 'any' there is exactly one tool_use block.
266
+ const toolUse = finalMessage.content.find(c => c.type === 'tool_use');
267
+ if (!toolUse || toolUse.type !== 'tool_use') {
268
+ throw new Error('Expected tool_use block in final message');
269
+ }
270
+
271
+ let sources: Citation[];
272
+ let hadExplicitCitations: boolean;
273
+ const hasClarification = toolUse.name === 'ask_clarification';
274
+
275
+ if (toolUse.name === 'answer') {
276
+ const input = toolUse.input as AnswerInput;
277
+ const slugs = Array.isArray(input.cited_page_slugs) ? input.cited_page_slugs : [];
278
+ const markdownText = typeof input.markdown === 'string' ? input.markdown : '';
279
+ // Suppress citations on the canned identity reply — otherwise the
280
+ // top-2 fallback would attach unrelated docs under "I'm the
281
+ // documentation assistant for …".
282
+ const isIdentityReply = isCannedIdentityReply(markdownText, siteName);
283
+
284
+ const seen = new Set<string>();
285
+ const explicitSources: Citation[] = [];
286
+ if (!isIdentityReply) {
287
+ for (const slug of slugs) {
288
+ const chunk = chunks.find(c => c.pageSlug === slug);
289
+ if (chunk && !seen.has(chunk.pageSlug)) {
290
+ seen.add(chunk.pageSlug);
291
+ explicitSources.push({
292
+ title: chunk.pageTitle,
293
+ slug: chunk.pageSlug,
294
+ section: chunk.sectionHeading,
295
+ });
296
+ }
297
+ }
298
+ }
299
+ // Identity replies set hadExplicitCitations=true to mark intentional
300
+ // no-cite; non-identity answers fall back to top-2 when Claude omits slugs.
301
+ hadExplicitCitations = isIdentityReply || explicitSources.length > 0;
302
+ sources = isIdentityReply
303
+ ? []
304
+ : explicitSources.length > 0
305
+ ? explicitSources
306
+ : topChunksAsCitations(2, seen);
307
+ } else if (toolUse.name === 'ask_clarification') {
308
+ const input = toolUse.input as ClarificationInput;
309
+ const options = Array.isArray(input.options) ? input.options : [];
310
+ const question = typeof input.question === 'string' ? input.question.trim() : '';
311
+ // Missing question → UI shows buttons with no prompt.
312
+ // <2 options → dead-end UI. Interrupt so the user can retry.
313
+ if (!question) {
314
+ throw new Error('ask_clarification returned no question');
315
+ }
316
+ if (options.length < 2) {
317
+ throw new Error(`ask_clarification returned ${options.length} options; minimum is 2`);
318
+ }
288
319
  controller.enqueue(sendEvent({ type: 'clarification', options }));
320
+ // Surface top chunks so users see where the disambiguation candidates come from.
321
+ sources = topChunksAsCitations();
322
+ hadExplicitCitations = false;
323
+ } else {
324
+ throw new Error(`Unexpected tool name: ${toolUse.name}`);
289
325
  }
290
326
 
291
- // Extract [Title] references from Claude's response (skip markdown links [text](url))
292
- const { sources, hadExplicitCitations } = extractCitations(fullText, chunks);
293
327
  controller.enqueue(sendEvent({ type: 'citations', sources }));
294
328
  controller.enqueue(sendEvent({ type: 'done' }));
295
329
 
296
- // Fire-and-forget analytics — only on success (finalMessage unreliable on error)
297
330
  trackChatAnalytics({
298
331
  projectSlug: project,
299
332
  query: message,
@@ -302,11 +335,16 @@ export async function POST(
302
335
  outputTokens,
303
336
  model: CHAT_MODEL,
304
337
  hadExplicitCitations,
305
- hasClarification: options !== null,
338
+ hasClarification,
306
339
  durationMs: Date.now() - startTime,
307
340
  userAgent: request.headers.get('user-agent') || undefined,
308
341
  }).catch(() => {});
309
- } catch {
342
+ } catch (err) {
343
+ log('warn', 'chat: stream interrupted', {
344
+ projectSlug: project,
345
+ toolName,
346
+ error: err instanceof Error ? err.message : String(err),
347
+ });
310
348
  controller.enqueue(sendEvent({ type: 'error', message: 'The response was interrupted. Please try again.' }));
311
349
  }
312
350
  controller.close();
@@ -5,6 +5,9 @@ import { memo, useMemo, useState, useCallback } from 'react';
5
5
  interface ChatEmptyStateProps {
6
6
  starterQuestions?: string[];
7
7
  onSelectQuestion: (question: string) => void;
8
+ /** Escape-hatch to hand the visitor off to Crisp. Omit to hide the button
9
+ * (e.g. when Crisp isn't loaded). Detection happens in ChatPanel. */
10
+ onTalkToHuman?: () => void;
8
11
  }
9
12
 
10
13
  const STARTER_BASE = 'w-full text-left px-4 py-3 rounded-xl border text-sm transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-accent)]';
@@ -25,7 +28,7 @@ function starterButtonClass(question: string, selectedQuestion: string | null):
25
28
  * Starter questions are auto-generated by Haiku during builds when not
26
29
  * defined in docs.json — see lib/generate-starter-questions.ts.
27
30
  */
28
- export const ChatEmptyState = memo(function ChatEmptyState({ starterQuestions, onSelectQuestion }: ChatEmptyStateProps) {
31
+ export const ChatEmptyState = memo(function ChatEmptyState({ starterQuestions, onSelectQuestion, onTalkToHuman }: ChatEmptyStateProps) {
29
32
  const shortcutKey = useMemo(
30
33
  () => typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.userAgent) ? '⌘' : 'Ctrl+',
31
34
  [],
@@ -74,6 +77,15 @@ export const ChatEmptyState = memo(function ChatEmptyState({ starterQuestions, o
74
77
  ))}
75
78
  </div>
76
79
  )}
80
+ {onTalkToHuman && (
81
+ <button
82
+ type="button"
83
+ onClick={onTalkToHuman}
84
+ className="mt-6 text-xs text-[var(--color-text-secondary)] hover:text-[var(--color-accent)] transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--color-accent)] rounded-md"
85
+ >
86
+ Need to talk to a human? <span className="font-medium text-[var(--color-accent)]">Start a chat →</span>
87
+ </button>
88
+ )}
77
89
  </div>
78
90
  );
79
91
  });
@@ -1,11 +1,12 @@
1
1
  'use client';
2
2
 
3
- import { useRef, useEffect, useLayoutEffect, useCallback } from 'react';
3
+ import { useRef, useEffect, useLayoutEffect, useCallback, useState } from 'react';
4
4
  import { useChat } from '@/hooks/useChat';
5
5
  import { useBodyScrollLock } from '@/hooks/useBodyScrollLock';
6
6
  import { ChatMessage } from './ChatMessage';
7
7
  import { ChatInput } from './ChatInput';
8
8
  import { ChatEmptyState } from './ChatEmptyState';
9
+ import { crispAvailable, hideCrispLauncher, openCrispChat, showCrispLauncher } from '../../lib/crisp-bridge';
9
10
 
10
11
  const SOMETHING_ELSE_PATTERNS = ['something else', 'none of the above', 'none of these'];
11
12
 
@@ -41,6 +42,15 @@ interface ChatPanelProps {
41
42
  */
42
43
  export function ChatPanel({ isOpen, onClose, starterQuestions, chatEndpoint, mode = 'overlay' }: ChatPanelProps) {
43
44
  const { messages, sendMessage, isLoading, abort, retry, clearChat, error, markClarificationSelected } = useChat(chatEndpoint);
45
+
46
+ const [hasCrisp, setHasCrisp] = useState(false);
47
+ useEffect(() => { setHasCrisp(crispAvailable()); }, []);
48
+
49
+ const handleTalkToHuman = useCallback(() => {
50
+ onClose();
51
+ openCrispChat();
52
+ }, [onClose]);
53
+
44
54
  const messagesContainerRef = useRef<HTMLDivElement>(null);
45
55
  const inputRef = useRef<HTMLDivElement>(null);
46
56
  const overlayPanelRef = useRef<HTMLDivElement>(null);
@@ -50,6 +60,17 @@ export function ChatPanel({ isOpen, onClose, starterQuestions, chatEndpoint, mod
50
60
  // Lock body scroll when mobile overlay is open
51
61
  useBodyScrollLock(!isInline && isOpen);
52
62
 
63
+ // Coordinate visibility with Crisp so the two chats don't overlap in the
64
+ // bottom-right corner. Applies to both modes — Crisp's fixed launcher sits
65
+ // behind the inline chat column's send button on desktop too.
66
+ useEffect(() => {
67
+ if (!isOpen) return;
68
+ hideCrispLauncher();
69
+ return () => {
70
+ showCrispLauncher();
71
+ };
72
+ }, [isOpen]);
73
+
53
74
  // On iOS, the virtual keyboard doesn't resize the layout viewport, so the
54
75
  // panel's max-h-[80dvh] can extend behind the keyboard. When the user taps the
55
76
  // textarea, iOS scrolls the page to reveal it — pushing the fixed panel off-screen.
@@ -171,6 +192,7 @@ export function ChatPanel({ isOpen, onClose, starterQuestions, chatEndpoint, mod
171
192
  <ChatEmptyState
172
193
  starterQuestions={starterQuestions}
173
194
  onSelectQuestion={sendMessage}
195
+ onTalkToHuman={hasCrisp ? handleTalkToHuman : undefined}
174
196
  />
175
197
  )}
176
198
  </div>
@@ -181,12 +203,24 @@ export function ChatPanel({ isOpen, onClose, starterQuestions, chatEndpoint, mod
181
203
  <p className="text-xs text-red-600 dark:text-red-400">
182
204
  {error}
183
205
  </p>
184
- <button
185
- onClick={retry}
186
- className="text-xs font-medium text-red-600 dark:text-red-400 hover:underline flex-shrink-0 cursor-pointer"
187
- >
188
- Try again
189
- </button>
206
+ <div className="flex items-center gap-3 flex-shrink-0">
207
+ {hasCrisp && (
208
+ <button
209
+ type="button"
210
+ onClick={handleTalkToHuman}
211
+ className="text-xs font-medium text-red-600 dark:text-red-400 hover:underline cursor-pointer"
212
+ >
213
+ Talk to a human
214
+ </button>
215
+ )}
216
+ <button
217
+ type="button"
218
+ onClick={retry}
219
+ className="text-xs font-medium text-red-600 dark:text-red-400 hover:underline cursor-pointer"
220
+ >
221
+ Try again
222
+ </button>
223
+ </div>
190
224
  </div>
191
225
  )}
192
226
 
@@ -220,7 +254,7 @@ export function ChatPanel({ isOpen, onClose, starterQuestions, chatEndpoint, mod
220
254
  {/* Mobile backdrop (<lg) */}
221
255
  {isOpen && (
222
256
  <div
223
- className="fixed inset-0 bg-black/50 backdrop-blur-sm z-[54] lg:hidden"
257
+ className="fixed inset-0 bg-black/50 backdrop-blur-sm z-[1000003] lg:hidden"
224
258
  onClick={onClose}
225
259
  aria-hidden="true"
226
260
  />
@@ -236,7 +270,7 @@ export function ChatPanel({ isOpen, onClose, starterQuestions, chatEndpoint, mod
236
270
  data-open={isOpen}
237
271
  data-chat-panel
238
272
  className={`
239
- fixed z-[55] flex flex-col overflow-hidden
273
+ fixed z-[1000004] flex flex-col overflow-hidden
240
274
  transition-all duration-200
241
275
  inset-x-2 top-4 max-h-[80dvh] rounded-2xl shadow-xl border border-[var(--color-border)]
242
276
  lg:inset-x-auto lg:top-0 lg:max-h-none lg:rounded-none lg:shadow-none lg:border-0
@@ -408,7 +408,7 @@ export function SearchModal({ isOpen, onClose, popularPages, onNavigate }: Searc
408
408
  placeholder="Search documentation…"
409
409
  value={query}
410
410
  onChange={(e) => setQuery(e.target.value)}
411
- className="flex-1 bg-transparent text-[var(--color-text-primary)] placeholder-[var(--color-text-muted)] outline-none text-sm"
411
+ className="flex-1 bg-transparent text-[var(--color-text-primary)] placeholder-[var(--color-text-muted)] outline-none text-base"
412
412
  autoComplete="off"
413
413
  autoFocus
414
414
  aria-label="Search documentation"