@yr-kits/dev-copilot 0.1.1 → 0.1.2

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.
Files changed (33) hide show
  1. package/dist/app/index.d.mts +2 -0
  2. package/dist/app/index.mjs +4 -0
  3. package/dist/bin/bridge.mjs +4 -916
  4. package/dist/bin/bridge.mjs.map +1 -1
  5. package/dist/bin/dev-copilot.mjs +13 -3
  6. package/dist/bin/dev-copilot.mjs.map +1 -1
  7. package/dist/bridge/app/index.d.mts +24 -0
  8. package/dist/bridge/app/index.d.mts.map +1 -0
  9. package/dist/bridge/app/index.mjs +3 -0
  10. package/dist/{types/index.d.mts → copilot-D8--qKgC.d.mts} +3 -3
  11. package/dist/copilot-D8--qKgC.d.mts.map +1 -0
  12. package/dist/copilot-overlay-ClRoIHew.mjs +1129 -0
  13. package/dist/copilot-overlay-ClRoIHew.mjs.map +1 -0
  14. package/dist/copilot-overlay-NlUgrMjy.d.mts +7 -0
  15. package/dist/copilot-overlay-NlUgrMjy.d.mts.map +1 -0
  16. package/dist/dev-copilot-context-CA9bqV_U.mjs +35 -0
  17. package/dist/dev-copilot-context-CA9bqV_U.mjs.map +1 -0
  18. package/dist/dev-copilot-provider-CP_gJvWG.d.mts +22 -0
  19. package/dist/dev-copilot-provider-CP_gJvWG.d.mts.map +1 -0
  20. package/dist/dev-copilot-provider-D0_wEEem.mjs +14 -0
  21. package/dist/dev-copilot-provider-D0_wEEem.mjs.map +1 -0
  22. package/dist/index.d.mts +5 -33
  23. package/dist/index.mjs +6 -863
  24. package/dist/run-bridge-cli-DVLGcVgq.mjs +1510 -0
  25. package/dist/run-bridge-cli-DVLGcVgq.mjs.map +1 -0
  26. package/dist/types.d.mts +2 -0
  27. package/dist/widgets/copilot-overlay/index.d.mts +2 -0
  28. package/dist/widgets/copilot-overlay/index.mjs +4 -0
  29. package/package.json +25 -7
  30. package/dist/index.d.mts.map +0 -1
  31. package/dist/index.mjs.map +0 -1
  32. package/dist/types/index.d.mts.map +0 -1
  33. /package/dist/{types/index.mjs → types.mjs} +0 -0
@@ -0,0 +1,1129 @@
1
+ import { n as useDevCopilotConfig } from "./dev-copilot-context-CA9bqV_U.mjs";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { createEnterKeySubmitHandler } from "@yr-kits/cli/utils/ime-enter-handler";
5
+
6
+ //#region src/shared/api/create-copilot-api-client.ts
7
+ const DEFAULT_BASE_URL = "http://127.0.0.1:3339";
8
+ const BRIDGE_CONNECTION_ERROR_MESSAGE = "브릿지 서버에 연결하지 못했습니다. 브릿지 서버를 켜주세요.";
9
+ const parseResponse = async (response) => {
10
+ const payload = await response.json();
11
+ if (!response.ok) {
12
+ const errorMessage = typeof payload === "object" && payload && "error" in payload ? payload.error : "요청 처리 중 오류가 발생했습니다.";
13
+ throw new Error(errorMessage);
14
+ }
15
+ return payload;
16
+ };
17
+ const normalizeNetworkError = (error) => {
18
+ if (error instanceof TypeError && error.message.toLowerCase().includes("failed to fetch")) return new Error(BRIDGE_CONNECTION_ERROR_MESSAGE);
19
+ if (error instanceof Error) return error;
20
+ return /* @__PURE__ */ new Error("요청 처리 중 오류가 발생했습니다.");
21
+ };
22
+ const createCopilotApiClient = (options = {}) => {
23
+ const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
24
+ const fetcher = options.fetcher ?? fetch;
25
+ const post = async (path, body) => {
26
+ try {
27
+ return parseResponse(await fetcher(`${baseUrl}${path}`, {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/json" },
30
+ body: JSON.stringify(body)
31
+ }));
32
+ } catch (error) {
33
+ throw normalizeNetworkError(error);
34
+ }
35
+ };
36
+ return {
37
+ status: async (agent) => {
38
+ const query = agent ? `?agent=${agent}` : "";
39
+ try {
40
+ return parseResponse(await fetcher(`${baseUrl}/status${query}`));
41
+ } catch (error) {
42
+ throw normalizeNetworkError(error);
43
+ }
44
+ },
45
+ chat: (payload) => post("/chat", payload),
46
+ apply: (payload) => post("/apply", payload)
47
+ };
48
+ };
49
+
50
+ //#endregion
51
+ //#region src/features/apply-copilot-patch/model/apply-copilot-patch.ts
52
+ const applyCopilotPatch = async (patchId, baseUrl) => {
53
+ return createCopilotApiClient({ baseUrl }).apply({
54
+ patchId,
55
+ approvalToken: `approve:${patchId}`
56
+ });
57
+ };
58
+
59
+ //#endregion
60
+ //#region src/features/copilot-session/model/use-copilot-session.ts
61
+ const useCopilotSession = () => {
62
+ const [open, setOpen] = useState(false);
63
+ const [prompt, setPrompt] = useState("");
64
+ const [busy, setBusy] = useState(false);
65
+ const [applying, setApplying] = useState(false);
66
+ const [error, setError] = useState(null);
67
+ const [chatResult, setChatResult] = useState(null);
68
+ const [toastMessage, setToastMessage] = useState(null);
69
+ const [selectedAgent, setSelectedAgent] = useState("codex");
70
+ const [showResponsePanel, setShowResponsePanel] = useState(false);
71
+ const closePanel = useCallback(() => {
72
+ setOpen(false);
73
+ setShowResponsePanel(false);
74
+ }, []);
75
+ const togglePanel = useCallback(() => {
76
+ setOpen((prev) => !prev);
77
+ }, []);
78
+ return {
79
+ open,
80
+ prompt,
81
+ setPrompt,
82
+ busy,
83
+ applying,
84
+ error,
85
+ chatResult,
86
+ toastMessage,
87
+ selectedAgent,
88
+ setSelectedAgent,
89
+ showResponsePanel,
90
+ setError,
91
+ closePanel,
92
+ openPanel: useCallback(() => {
93
+ setOpen(true);
94
+ }, []),
95
+ togglePanel,
96
+ toggleResponsePanel: useCallback(() => {
97
+ setShowResponsePanel((prev) => !prev);
98
+ }, []),
99
+ startRequest: useCallback(() => {
100
+ setBusy(true);
101
+ setError(null);
102
+ setShowResponsePanel(true);
103
+ }, []),
104
+ finishRequest: useCallback((result) => {
105
+ setChatResult(result);
106
+ setBusy(false);
107
+ }, []),
108
+ failRequest: useCallback((message) => {
109
+ setError(message);
110
+ setBusy(false);
111
+ }, []),
112
+ startApply: useCallback(() => {
113
+ setApplying(true);
114
+ setError(null);
115
+ }, []),
116
+ finishApply: useCallback(() => {
117
+ setApplying(false);
118
+ }, []),
119
+ failApply: useCallback((message) => {
120
+ setError(message);
121
+ setApplying(false);
122
+ }, []),
123
+ showToast: useCallback((message) => {
124
+ setToastMessage(message);
125
+ }, []),
126
+ clearToast: useCallback(() => {
127
+ setToastMessage(null);
128
+ }, [])
129
+ };
130
+ };
131
+
132
+ //#endregion
133
+ //#region src/features/select-agent/model/use-agent-status-polling.ts
134
+ const useAgentStatusPolling = (open, selectedAgent, baseUrl) => {
135
+ const [agentStatus, setAgentStatus] = useState(null);
136
+ useEffect(() => {
137
+ if (!open) return;
138
+ let ignore = false;
139
+ createCopilotApiClient({ baseUrl }).status(selectedAgent).then((status) => {
140
+ if (!ignore) setAgentStatus(status);
141
+ }).catch((caughtError) => {
142
+ if (!ignore) setAgentStatus({
143
+ available: false,
144
+ authenticated: false,
145
+ agent: selectedAgent,
146
+ message: caughtError instanceof Error ? caughtError.message : "로컬 에이전트 상태 확인에 실패했습니다."
147
+ });
148
+ });
149
+ return () => {
150
+ ignore = true;
151
+ };
152
+ }, [
153
+ open,
154
+ selectedAgent,
155
+ baseUrl
156
+ ]);
157
+ return {
158
+ agentStatus,
159
+ setAgentStatus
160
+ };
161
+ };
162
+
163
+ //#endregion
164
+ //#region src/features/submit-copilot-request/model/submit-copilot-request.ts
165
+ const submitCopilotRequest = async (input) => {
166
+ return createCopilotApiClient({ baseUrl: input.baseUrl }).chat({
167
+ selectedText: input.selectedText,
168
+ prompt: input.prompt,
169
+ mode: input.mode,
170
+ context: {
171
+ route: input.route,
172
+ fileHints: input.allowedPaths,
173
+ previousResponse: input.previousResponse,
174
+ agent: input.selectedAgent
175
+ }
176
+ });
177
+ };
178
+
179
+ //#endregion
180
+ //#region src/entities/agent/model.ts
181
+ const AGENT_LABELS = {
182
+ codex: "Codex CLI",
183
+ claude: "Claude Code CLI"
184
+ };
185
+ const isAgentReady = (status) => {
186
+ if (!status) return true;
187
+ return status.available && status.authenticated;
188
+ };
189
+
190
+ //#endregion
191
+ //#region src/entities/patch/model.ts
192
+ const hasApplicablePatch = (chatResult) => {
193
+ return Boolean(chatResult?.patchId);
194
+ };
195
+
196
+ //#endregion
197
+ //#region src/entities/session/model.ts
198
+ const toPreviousResponse = (chatResult) => {
199
+ if (!chatResult) return;
200
+ return [`message:\n${chatResult.message}`, chatResult.patchPreview ? `patchPreview:\n${chatResult.patchPreview}` : ""].filter(Boolean).join("\n\n");
201
+ };
202
+
203
+ //#endregion
204
+ //#region src/shared/lib/error.ts
205
+ const toErrorMessage = (error, fallbackMessage) => {
206
+ return error instanceof Error ? error.message : fallbackMessage;
207
+ };
208
+
209
+ //#endregion
210
+ //#region src/shared/ui/use-selection-capture.ts
211
+ const OVERLAY_ATTRIBUTE = "data-dev-copilot-overlay";
212
+ const toSelectionText = () => {
213
+ return window.getSelection()?.toString().trim() ?? "";
214
+ };
215
+ const isNodeInsideOverlay = (node) => {
216
+ if (!node) return false;
217
+ const element = node instanceof Element ? node : node.parentElement;
218
+ return Boolean(element?.closest(`[${OVERLAY_ATTRIBUTE}]`));
219
+ };
220
+ const isInsideOverlay = (target) => {
221
+ return target instanceof Element && Boolean(target.closest(`[${OVERLAY_ATTRIBUTE}]`));
222
+ };
223
+ const useSelectionCapture = () => {
224
+ const [selectedText, setSelectedText] = useState("");
225
+ const syncSelection = useCallback((event) => {
226
+ const selection = window.getSelection();
227
+ const startedInsideOverlay = isNodeInsideOverlay(selection?.anchorNode ?? null);
228
+ const endedInsideOverlay = isNodeInsideOverlay(selection?.focusNode ?? null);
229
+ if (isInsideOverlay(event.target) || startedInsideOverlay || endedInsideOverlay) return;
230
+ const nextSelectedText = selection?.toString().trim() ?? toSelectionText();
231
+ if (!nextSelectedText) return;
232
+ setSelectedText(nextSelectedText);
233
+ }, []);
234
+ useEffect(() => {
235
+ document.addEventListener("mouseup", syncSelection);
236
+ document.addEventListener("keyup", syncSelection);
237
+ return () => {
238
+ document.removeEventListener("mouseup", syncSelection);
239
+ document.removeEventListener("keyup", syncSelection);
240
+ };
241
+ }, [syncSelection]);
242
+ return {
243
+ selectedText,
244
+ setSelectedText
245
+ };
246
+ };
247
+
248
+ //#endregion
249
+ //#region src/widgets/copilot-overlay/model/use-draggable-fab.ts
250
+ const FLOATING_BUTTON_SIZE = 48;
251
+ const DRAG_CLICK_THRESHOLD = 4;
252
+ const DEFAULT_FLOATING_OFFSET = 24;
253
+ const FLOATING_Z_INDEX = 2147483e3;
254
+ const clampPosition = (value, max) => {
255
+ return Math.min(Math.max(value, 0), Math.max(0, max - FLOATING_BUTTON_SIZE));
256
+ };
257
+ const useDraggableFab = () => {
258
+ const [position, setPosition] = useState(null);
259
+ const dragStateRef = useRef(null);
260
+ const suppressMainToggleClickRef = useRef(false);
261
+ useEffect(() => {
262
+ const onResize = () => {
263
+ setPosition((prev) => {
264
+ if (!prev) return prev;
265
+ return {
266
+ x: clampPosition(prev.x, window.innerWidth),
267
+ y: clampPosition(prev.y, window.innerHeight)
268
+ };
269
+ });
270
+ };
271
+ window.addEventListener("resize", onResize);
272
+ return () => window.removeEventListener("resize", onResize);
273
+ }, []);
274
+ const onPointerDown = useCallback((event, origin) => {
275
+ if (event.button !== 0) return;
276
+ event.currentTarget.setPointerCapture(event.pointerId);
277
+ dragStateRef.current = {
278
+ pointerId: event.pointerId,
279
+ startX: event.clientX,
280
+ startY: event.clientY,
281
+ originX: origin?.x ?? 0,
282
+ originY: origin?.y ?? 0,
283
+ moved: false
284
+ };
285
+ }, []);
286
+ const onPointerMove = useCallback((event) => {
287
+ const dragState = dragStateRef.current;
288
+ if (!dragState || dragState.pointerId !== event.pointerId) return;
289
+ const deltaX = event.clientX - dragState.startX;
290
+ const deltaY = event.clientY - dragState.startY;
291
+ if (!(Math.abs(deltaX) > DRAG_CLICK_THRESHOLD || Math.abs(deltaY) > DRAG_CLICK_THRESHOLD) && !dragState.moved) return;
292
+ dragState.moved = true;
293
+ setPosition({
294
+ x: clampPosition(dragState.originX + deltaX, window.innerWidth),
295
+ y: clampPosition(dragState.originY + deltaY, window.innerHeight)
296
+ });
297
+ }, []);
298
+ const onPointerEnd = useCallback((event) => {
299
+ if (dragStateRef.current?.pointerId !== event.pointerId) return;
300
+ suppressMainToggleClickRef.current = dragStateRef.current.moved;
301
+ dragStateRef.current = null;
302
+ event.currentTarget.releasePointerCapture(event.pointerId);
303
+ }, []);
304
+ const consumeToggleSuppression = useCallback(() => {
305
+ if (suppressMainToggleClickRef.current) {
306
+ suppressMainToggleClickRef.current = false;
307
+ return true;
308
+ }
309
+ return false;
310
+ }, []);
311
+ const resetDragState = useCallback(() => {
312
+ dragStateRef.current = null;
313
+ suppressMainToggleClickRef.current = false;
314
+ setPosition(null);
315
+ }, []);
316
+ return {
317
+ position,
318
+ floatingWrapperStyle: useMemo(() => {
319
+ if (position) return {
320
+ position: "fixed",
321
+ zIndex: FLOATING_Z_INDEX,
322
+ left: `${position.x}px`,
323
+ top: `${position.y}px`
324
+ };
325
+ return {
326
+ position: "fixed",
327
+ right: DEFAULT_FLOATING_OFFSET,
328
+ bottom: DEFAULT_FLOATING_OFFSET,
329
+ zIndex: FLOATING_Z_INDEX
330
+ };
331
+ }, [position]),
332
+ onPointerDown,
333
+ onPointerMove,
334
+ onPointerEnd,
335
+ consumeToggleSuppression,
336
+ resetDragState
337
+ };
338
+ };
339
+
340
+ //#endregion
341
+ //#region src/widgets/copilot-overlay/ui/tokens.ts
342
+ const OVERLAY_TOKENS = {
343
+ floatingButtonSize: 48,
344
+ panelWidth: "min(1028px, calc(100vw - 48px))",
345
+ inputPanelWidth: 420,
346
+ railWidth: 36
347
+ };
348
+ const OVERLAY_FONT = {
349
+ sans: "Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
350
+ mono: "ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Consolas, monospace"
351
+ };
352
+ const OVERLAY_COLOR = {
353
+ textPrimary: "#111827",
354
+ textSecondary: "#6b7280",
355
+ textMuted: "#64748b",
356
+ textDark: "#0f172a",
357
+ border: "#e5e7eb",
358
+ borderSoft: "#d1d5db",
359
+ backgroundBase: "#f8fafc",
360
+ backgroundWhite: "#ffffff",
361
+ brandButtonBg: "#fff4b8",
362
+ brandButtonBorder: "#f2d675",
363
+ brandButtonText: "#ffb03d",
364
+ primaryActionBg: "#111827",
365
+ secondaryActionBg: "#2563eb",
366
+ successText: "#15803d",
367
+ successBorder: "#bbf7d0",
368
+ successBackground: "#f0fdf4",
369
+ dangerText: "#dc2626",
370
+ dangerBorder: "#fca5a5",
371
+ dangerBackground: "#fef2f2",
372
+ spinnerTop: "#2563eb"
373
+ };
374
+ const OVERLAY_LABELS = {
375
+ title: "Dev Copilot",
376
+ subtitle: "텍스트를 드래그한 뒤 Command+F(또는 Ctrl+F)로 Copilot을 열어 주세요.",
377
+ promptPlaceholder: "무엇을 도와드릴까요?",
378
+ askButton: "질문",
379
+ editButton: "코드 수정 제안",
380
+ applyButton: "미리보기 적용",
381
+ applyingButton: "적용 중..."
382
+ };
383
+ const OVERLAY_STYLE_TEXT = `
384
+ .yrdc-trigger{transition:transform 150ms ease-out, box-shadow 150ms ease-out}
385
+ .yrdc-trigger:hover{transform:scale(1.05)}
386
+ .yrdc-pressable{transition:transform 150ms ease-out, background-color 150ms ease-out, opacity 150ms ease-out}
387
+ .yrdc-pressable:hover{transform:translateY(-1px)}
388
+ .yrdc-spinner{animation:yrdc-spin 1s linear infinite}
389
+ .yrdc-field:focus{outline:none;box-shadow:0 0 0 3px rgba(59,130,246,.14);border-color:#93c5fd}
390
+ @keyframes yrdc-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
391
+ `;
392
+
393
+ //#endregion
394
+ //#region src/widgets/copilot-overlay/ui/styles.ts
395
+ const createPanelStyle = (showResponsePanel) => ({
396
+ position: "relative",
397
+ marginTop: 12,
398
+ display: "grid",
399
+ gridTemplateColumns: showResponsePanel ? `${OVERLAY_TOKENS.inputPanelWidth}px ${OVERLAY_TOKENS.railWidth}px minmax(0, 1fr)` : `${OVERLAY_TOKENS.inputPanelWidth}px ${OVERLAY_TOKENS.railWidth}px`,
400
+ width: showResponsePanel ? OVERLAY_TOKENS.panelWidth : OVERLAY_TOKENS.inputPanelWidth + OVERLAY_TOKENS.railWidth,
401
+ maxHeight: "calc(100vh - 96px)",
402
+ overflow: "hidden",
403
+ border: `1px solid ${OVERLAY_COLOR.border}`,
404
+ borderRadius: 24,
405
+ background: OVERLAY_COLOR.backgroundBase,
406
+ boxShadow: "0 18px 60px rgba(15, 23, 42, 0.16)",
407
+ color: OVERLAY_COLOR.textDark,
408
+ fontFamily: OVERLAY_FONT.sans,
409
+ textAlign: "left"
410
+ });
411
+ const triggerButtonStyle = {
412
+ display: "flex",
413
+ width: OVERLAY_TOKENS.floatingButtonSize,
414
+ height: OVERLAY_TOKENS.floatingButtonSize,
415
+ borderRadius: 9999,
416
+ border: `1px solid ${OVERLAY_COLOR.brandButtonBorder}`,
417
+ background: OVERLAY_COLOR.brandButtonBg,
418
+ color: OVERLAY_COLOR.brandButtonText,
419
+ alignItems: "center",
420
+ justifyContent: "center",
421
+ boxShadow: "0 12px 28px rgba(15, 23, 42, 0.18)",
422
+ cursor: "grab"
423
+ };
424
+ const railStyle = {
425
+ display: "flex",
426
+ minHeight: 320,
427
+ alignItems: "center",
428
+ justifyContent: "center",
429
+ borderLeft: `1px solid ${OVERLAY_COLOR.border}`,
430
+ background: OVERLAY_COLOR.backgroundBase
431
+ };
432
+ const railToggleStyle = {
433
+ display: "flex",
434
+ width: 24,
435
+ height: 24,
436
+ border: "0",
437
+ background: "transparent",
438
+ color: OVERLAY_COLOR.textMuted,
439
+ cursor: "pointer",
440
+ alignItems: "center",
441
+ justifyContent: "center"
442
+ };
443
+ const inputPanelStyle = {
444
+ padding: 16,
445
+ minHeight: 0,
446
+ overflowY: "auto",
447
+ background: OVERLAY_COLOR.backgroundWhite
448
+ };
449
+ const responsePanelStyle = {
450
+ minHeight: 0,
451
+ overflow: "hidden",
452
+ padding: 16,
453
+ borderLeft: `1px solid ${OVERLAY_COLOR.border}`,
454
+ background: OVERLAY_COLOR.backgroundBase
455
+ };
456
+ const titleStyle = {
457
+ margin: 0,
458
+ fontSize: 18,
459
+ fontWeight: 700,
460
+ lineHeight: 1.4,
461
+ color: OVERLAY_COLOR.textPrimary
462
+ };
463
+ const subtitleStyle = {
464
+ margin: "4px 0 0",
465
+ fontSize: 14,
466
+ lineHeight: 1.5,
467
+ color: OVERLAY_COLOR.textSecondary,
468
+ wordBreak: "keep-all"
469
+ };
470
+ const statusBoxStyle = {
471
+ marginTop: 12,
472
+ border: `1px solid ${OVERLAY_COLOR.border}`,
473
+ borderRadius: 16,
474
+ background: OVERLAY_COLOR.backgroundWhite,
475
+ padding: "12px 14px",
476
+ fontSize: 14,
477
+ lineHeight: 1.6,
478
+ color: OVERLAY_COLOR.textSecondary
479
+ };
480
+ const statusLineStyle = { margin: 0 };
481
+ const labelStyle = {
482
+ display: "block",
483
+ marginTop: 16,
484
+ fontSize: 14,
485
+ lineHeight: 1.5,
486
+ color: OVERLAY_COLOR.textSecondary
487
+ };
488
+ const textareaStyle = {
489
+ width: "100%",
490
+ resize: "vertical",
491
+ borderRadius: 16,
492
+ border: `1px solid ${OVERLAY_COLOR.border}`,
493
+ background: OVERLAY_COLOR.backgroundWhite,
494
+ padding: "12px 14px",
495
+ marginTop: 6,
496
+ fontSize: 15,
497
+ lineHeight: 1.7,
498
+ color: OVERLAY_COLOR.textPrimary,
499
+ boxSizing: "border-box",
500
+ minHeight: 132
501
+ };
502
+ const agentToggleRowStyle = {
503
+ display: "flex",
504
+ gap: 8,
505
+ marginTop: 6
506
+ };
507
+ const agentToggleButtonStyle = {
508
+ border: 0,
509
+ borderRadius: 10,
510
+ padding: "8px 12px",
511
+ fontSize: 13,
512
+ fontWeight: 600,
513
+ lineHeight: 1.2,
514
+ cursor: "pointer"
515
+ };
516
+ const buttonRowStyle = {
517
+ display: "flex",
518
+ alignItems: "center",
519
+ gap: 8,
520
+ marginTop: 16
521
+ };
522
+ const buttonStyle = {
523
+ border: 0,
524
+ borderRadius: 12,
525
+ padding: "10px 14px",
526
+ fontSize: 14,
527
+ fontWeight: 600,
528
+ lineHeight: 1,
529
+ cursor: "pointer"
530
+ };
531
+ const responseCardStyle = {
532
+ marginTop: 12,
533
+ minHeight: 0,
534
+ flex: 1,
535
+ overflowY: "auto",
536
+ borderRadius: 18,
537
+ border: `1px solid ${OVERLAY_COLOR.border}`,
538
+ background: OVERLAY_COLOR.backgroundWhite,
539
+ padding: 16
540
+ };
541
+ const busyContainerStyle = {
542
+ display: "flex",
543
+ height: "100%",
544
+ minHeight: 192,
545
+ alignItems: "center",
546
+ justifyContent: "center",
547
+ gap: 12,
548
+ color: OVERLAY_COLOR.textSecondary,
549
+ fontSize: 14
550
+ };
551
+ const spinnerStyle = {
552
+ display: "inline-block",
553
+ width: 18,
554
+ height: 18,
555
+ borderRadius: 9999,
556
+ border: `2px solid ${OVERLAY_COLOR.borderSoft}`,
557
+ borderTopColor: OVERLAY_COLOR.spinnerTop
558
+ };
559
+ const articleStyle = {
560
+ display: "flex",
561
+ flexDirection: "column",
562
+ gap: 12
563
+ };
564
+ const errorBoxStyle = {
565
+ margin: 0,
566
+ border: `1px solid ${OVERLAY_COLOR.dangerBorder}`,
567
+ borderRadius: 12,
568
+ background: OVERLAY_COLOR.dangerBackground,
569
+ padding: "10px 12px",
570
+ fontSize: 14,
571
+ lineHeight: 1.6,
572
+ color: OVERLAY_COLOR.dangerText,
573
+ whiteSpace: "pre-wrap",
574
+ wordBreak: "break-word",
575
+ overflowWrap: "anywhere"
576
+ };
577
+ const warningBoxStyle = {
578
+ display: "flex",
579
+ flexDirection: "column",
580
+ gap: 6,
581
+ border: `1px solid ${OVERLAY_COLOR.dangerBorder}`,
582
+ borderRadius: 12,
583
+ background: OVERLAY_COLOR.dangerBackground,
584
+ padding: "10px 12px",
585
+ fontSize: 14,
586
+ lineHeight: 1.6,
587
+ color: OVERLAY_COLOR.dangerText,
588
+ wordBreak: "break-word",
589
+ overflowWrap: "anywhere"
590
+ };
591
+ const messageStyle = {
592
+ margin: 0,
593
+ whiteSpace: "pre-wrap",
594
+ wordBreak: "break-word",
595
+ overflowWrap: "anywhere",
596
+ fontSize: 15,
597
+ lineHeight: 1.7,
598
+ color: OVERLAY_COLOR.textPrimary
599
+ };
600
+ const patchPreviewStyle = {
601
+ margin: 0,
602
+ maxHeight: 288,
603
+ overflow: "auto",
604
+ borderRadius: 12,
605
+ border: `1px solid ${OVERLAY_COLOR.border}`,
606
+ background: OVERLAY_COLOR.backgroundBase,
607
+ padding: 12,
608
+ fontSize: 13,
609
+ lineHeight: 1.6,
610
+ color: OVERLAY_COLOR.textPrimary,
611
+ fontFamily: OVERLAY_FONT.mono,
612
+ whiteSpace: "pre-wrap",
613
+ wordBreak: "break-word"
614
+ };
615
+ const placeholderStyle = {
616
+ margin: 0,
617
+ fontSize: 14,
618
+ lineHeight: 1.6,
619
+ color: OVERLAY_COLOR.textSecondary
620
+ };
621
+ const toastStyle = {
622
+ position: "fixed",
623
+ top: 16,
624
+ right: 16,
625
+ zIndex: 2147483600,
626
+ maxWidth: 360,
627
+ borderRadius: 16,
628
+ border: `1px solid ${OVERLAY_COLOR.successBorder}`,
629
+ background: OVERLAY_COLOR.successBackground,
630
+ color: OVERLAY_COLOR.successText,
631
+ padding: "12px 14px",
632
+ boxShadow: "0 12px 28px rgba(15, 23, 42, 0.12)",
633
+ fontFamily: OVERLAY_FONT.sans,
634
+ fontSize: 14,
635
+ lineHeight: 1.6
636
+ };
637
+
638
+ //#endregion
639
+ //#region src/widgets/copilot-overlay/ui/agent-selector.tsx
640
+ function AgentSelector({ selectedAgent, disabled, onSelect }) {
641
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("label", {
642
+ style: labelStyle,
643
+ children: "에이전트"
644
+ }), /* @__PURE__ */ jsx("div", {
645
+ style: agentToggleRowStyle,
646
+ children: ["codex", "claude"].map((agent) => {
647
+ const active = selectedAgent === agent;
648
+ return /* @__PURE__ */ jsx("button", {
649
+ type: "button",
650
+ className: "yrdc-pressable",
651
+ onClick: () => onSelect(agent),
652
+ disabled,
653
+ style: {
654
+ ...agentToggleButtonStyle,
655
+ background: active ? "#111827" : "#e2e8f0",
656
+ color: active ? "#ffffff" : "#1e293b",
657
+ opacity: disabled ? .6 : 1
658
+ },
659
+ children: AGENT_LABELS[agent]
660
+ }, agent);
661
+ })
662
+ })] });
663
+ }
664
+
665
+ //#endregion
666
+ //#region src/widgets/copilot-overlay/ui/agent-status-card.tsx
667
+ function AgentStatusCard({ selectedAgent, agentStatus }) {
668
+ return /* @__PURE__ */ jsxs("div", {
669
+ style: statusBoxStyle,
670
+ children: [
671
+ /* @__PURE__ */ jsxs("p", {
672
+ style: statusLineStyle,
673
+ children: ["로컬 에이전트: ", AGENT_LABELS[selectedAgent]]
674
+ }),
675
+ agentStatus?.model ? /* @__PURE__ */ jsxs("p", {
676
+ style: statusLineStyle,
677
+ children: ["모델: ", agentStatus.model]
678
+ }) : null,
679
+ agentStatus ? /* @__PURE__ */ jsxs("p", {
680
+ style: {
681
+ ...statusLineStyle,
682
+ color: agentStatus.authenticated ? "#15803d" : "#dc2626"
683
+ },
684
+ children: [agentStatus.message, agentStatus.loginCommand && !agentStatus.message.includes(agentStatus.loginCommand) ? ` 터미널에서 ${agentStatus.loginCommand} 실행` : ""]
685
+ }) : null
686
+ ]
687
+ });
688
+ }
689
+
690
+ //#endregion
691
+ //#region src/widgets/copilot-overlay/ui/button-style.ts
692
+ const BUTTON_COLORS = {
693
+ primary: {
694
+ background: "#2563eb",
695
+ color: "#ffffff"
696
+ },
697
+ secondary: {
698
+ background: "#111827",
699
+ color: "#ffffff"
700
+ },
701
+ success: {
702
+ background: "#15803d",
703
+ color: "#ffffff"
704
+ }
705
+ };
706
+ const createActionButtonStyle = (variant, disabled = false, overrides = {}) => ({
707
+ ...buttonStyle,
708
+ ...BUTTON_COLORS[variant],
709
+ opacity: disabled ? .55 : 1,
710
+ ...overrides
711
+ });
712
+
713
+ //#endregion
714
+ //#region src/widgets/copilot-overlay/ui/copilot-request-form.tsx
715
+ function CopilotRequestForm({ selectedText, prompt, busy, selectedAgent, agentStatus, onSelectedTextChange, onPromptChange, onAgentChange, onSubmit }) {
716
+ const submitDisabled = busy || !isAgentReady(agentStatus);
717
+ const handlePromptKeyDown = createEnterKeySubmitHandler(() => onSubmit("edit"));
718
+ return /* @__PURE__ */ jsxs("div", {
719
+ style: inputPanelStyle,
720
+ children: [
721
+ /* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsx("p", {
722
+ style: titleStyle,
723
+ children: OVERLAY_LABELS.title
724
+ }), /* @__PURE__ */ jsx("p", {
725
+ style: subtitleStyle,
726
+ children: OVERLAY_LABELS.subtitle
727
+ })] }),
728
+ /* @__PURE__ */ jsx(AgentStatusCard, {
729
+ selectedAgent,
730
+ agentStatus
731
+ }),
732
+ /* @__PURE__ */ jsx(AgentSelector, {
733
+ selectedAgent,
734
+ disabled: busy,
735
+ onSelect: onAgentChange
736
+ }),
737
+ /* @__PURE__ */ jsx("label", {
738
+ style: labelStyle,
739
+ children: "선택 텍스트"
740
+ }),
741
+ /* @__PURE__ */ jsx("textarea", {
742
+ value: selectedText,
743
+ onChange: (event) => onSelectedTextChange(event.target.value),
744
+ rows: 5,
745
+ className: "yrdc-field",
746
+ style: textareaStyle
747
+ }),
748
+ /* @__PURE__ */ jsx("label", {
749
+ style: labelStyle,
750
+ children: "프롬프트"
751
+ }),
752
+ /* @__PURE__ */ jsx("textarea", {
753
+ value: prompt,
754
+ onChange: (event) => onPromptChange(event.target.value),
755
+ onKeyDown: handlePromptKeyDown,
756
+ rows: 4,
757
+ placeholder: OVERLAY_LABELS.promptPlaceholder,
758
+ className: "yrdc-field",
759
+ style: textareaStyle
760
+ }),
761
+ /* @__PURE__ */ jsxs("div", {
762
+ style: buttonRowStyle,
763
+ children: [/* @__PURE__ */ jsx("button", {
764
+ type: "button",
765
+ className: "yrdc-pressable",
766
+ onClick: () => onSubmit("answer"),
767
+ disabled: submitDisabled,
768
+ style: createActionButtonStyle("secondary", submitDisabled),
769
+ children: OVERLAY_LABELS.askButton
770
+ }), /* @__PURE__ */ jsx("button", {
771
+ type: "button",
772
+ className: "yrdc-pressable",
773
+ onClick: () => onSubmit("edit"),
774
+ disabled: submitDisabled,
775
+ style: createActionButtonStyle("primary", submitDisabled),
776
+ children: OVERLAY_LABELS.editButton
777
+ })]
778
+ })
779
+ ]
780
+ });
781
+ }
782
+
783
+ //#endregion
784
+ //#region src/widgets/copilot-overlay/ui/copilot-response-panel.tsx
785
+ function CopilotResponsePanel({ busy, applying, error, chatResult, selectedAgent, onApply }) {
786
+ return /* @__PURE__ */ jsx("aside", {
787
+ style: responsePanelStyle,
788
+ children: /* @__PURE__ */ jsxs("div", {
789
+ style: {
790
+ display: "flex",
791
+ flexDirection: "column",
792
+ minHeight: 320,
793
+ height: "100%"
794
+ },
795
+ children: [/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", {
796
+ style: titleStyle,
797
+ children: "응답"
798
+ }) }), /* @__PURE__ */ jsx("div", {
799
+ style: responseCardStyle,
800
+ children: busy ? /* @__PURE__ */ jsxs("div", {
801
+ style: busyContainerStyle,
802
+ children: [/* @__PURE__ */ jsx("span", {
803
+ className: "yrdc-spinner",
804
+ style: spinnerStyle
805
+ }), /* @__PURE__ */ jsxs("span", { children: [AGENT_LABELS[selectedAgent], " 응답을 기다리는 중입니다."] })]
806
+ }) : chatResult ? /* @__PURE__ */ jsxs("article", {
807
+ style: articleStyle,
808
+ children: [
809
+ error ? /* @__PURE__ */ jsx("p", {
810
+ style: errorBoxStyle,
811
+ children: error
812
+ }) : null,
813
+ chatResult.warnings.length ? /* @__PURE__ */ jsx("div", {
814
+ style: warningBoxStyle,
815
+ children: chatResult.warnings.map((warning) => /* @__PURE__ */ jsx("p", {
816
+ style: { margin: 0 },
817
+ children: warning
818
+ }, warning))
819
+ }) : null,
820
+ /* @__PURE__ */ jsx("p", {
821
+ style: messageStyle,
822
+ children: chatResult.message
823
+ }),
824
+ chatResult.patchPreview ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("pre", {
825
+ style: patchPreviewStyle,
826
+ children: chatResult.patchPreview
827
+ }), chatResult.patchId ? /* @__PURE__ */ jsx("button", {
828
+ type: "button",
829
+ className: "yrdc-pressable",
830
+ onClick: onApply,
831
+ disabled: applying,
832
+ style: createActionButtonStyle("success", applying, { alignSelf: "flex-start" }),
833
+ children: applying ? OVERLAY_LABELS.applyingButton : OVERLAY_LABELS.applyButton
834
+ }) : null] }) : null
835
+ ]
836
+ }) : error ? /* @__PURE__ */ jsx("p", {
837
+ style: errorBoxStyle,
838
+ children: error
839
+ }) : /* @__PURE__ */ jsx("p", {
840
+ style: placeholderStyle,
841
+ children: "질문 또는 코드 수정 제안을 실행하면 이 영역에 결과가 표시됩니다."
842
+ })
843
+ })]
844
+ })
845
+ });
846
+ }
847
+
848
+ //#endregion
849
+ //#region src/widgets/copilot-overlay/ui/constants.ts
850
+ const TOAST_DURATION_MS = 3e3;
851
+
852
+ //#endregion
853
+ //#region src/widgets/copilot-overlay/ui/overlay-toast.tsx
854
+ function OverlayToast({ message }) {
855
+ if (!message) return null;
856
+ return /* @__PURE__ */ jsx("div", {
857
+ style: toastStyle,
858
+ children: /* @__PURE__ */ jsx("p", {
859
+ "aria-live": "polite",
860
+ style: { margin: 0 },
861
+ children: message
862
+ })
863
+ });
864
+ }
865
+
866
+ //#endregion
867
+ //#region src/widgets/copilot-overlay/ui/icons.tsx
868
+ const SparklesIcon = (props) => {
869
+ return /* @__PURE__ */ jsxs("svg", {
870
+ viewBox: "0 0 24 24",
871
+ fill: "none",
872
+ stroke: "currentColor",
873
+ strokeWidth: "1.8",
874
+ strokeLinecap: "round",
875
+ strokeLinejoin: "round",
876
+ ...props,
877
+ children: [
878
+ /* @__PURE__ */ jsx("path", { d: "M12 3.75 13.68 8.32 18.25 10 13.68 11.68 12 16.25 10.32 11.68 5.75 10 10.32 8.32 12 3.75Z" }),
879
+ /* @__PURE__ */ jsx("path", { d: "M18.5 3.75 19.08 5.42 20.75 6 19.08 6.58 18.5 8.25 17.92 6.58 16.25 6 17.92 5.42 18.5 3.75Z" }),
880
+ /* @__PURE__ */ jsx("path", { d: "M6 15.5 7 18.25 9.75 19.25 7 20.25 6 23 5 20.25 2.25 19.25 5 18.25 6 15.5Z" })
881
+ ]
882
+ });
883
+ };
884
+ const PanelRightOpenIcon = (props) => {
885
+ return /* @__PURE__ */ jsxs("svg", {
886
+ viewBox: "0 0 24 24",
887
+ fill: "none",
888
+ stroke: "currentColor",
889
+ strokeWidth: "1.8",
890
+ strokeLinecap: "round",
891
+ strokeLinejoin: "round",
892
+ ...props,
893
+ children: [
894
+ /* @__PURE__ */ jsx("rect", {
895
+ x: "3.75",
896
+ y: "4.75",
897
+ width: "16.5",
898
+ height: "14.5",
899
+ rx: "2.25"
900
+ }),
901
+ /* @__PURE__ */ jsx("path", { d: "M8.75 4.75v14.5" }),
902
+ /* @__PURE__ */ jsx("path", { d: "m13 9.25 3 2.75-3 2.75" })
903
+ ]
904
+ });
905
+ };
906
+ const PanelRightCloseIcon = (props) => {
907
+ return /* @__PURE__ */ jsxs("svg", {
908
+ viewBox: "0 0 24 24",
909
+ fill: "none",
910
+ stroke: "currentColor",
911
+ strokeWidth: "1.8",
912
+ strokeLinecap: "round",
913
+ strokeLinejoin: "round",
914
+ ...props,
915
+ children: [
916
+ /* @__PURE__ */ jsx("rect", {
917
+ x: "3.75",
918
+ y: "4.75",
919
+ width: "16.5",
920
+ height: "14.5",
921
+ rx: "2.25"
922
+ }),
923
+ /* @__PURE__ */ jsx("path", { d: "M15.25 4.75v14.5" }),
924
+ /* @__PURE__ */ jsx("path", { d: "m11 9.25-3 2.75 3 2.75" })
925
+ ]
926
+ });
927
+ };
928
+
929
+ //#endregion
930
+ //#region src/widgets/copilot-overlay/ui/overlay-trigger.tsx
931
+ function OverlayTrigger({ onClick, onPointerDown, onPointerMove, onPointerEnd }) {
932
+ return /* @__PURE__ */ jsx("button", {
933
+ type: "button",
934
+ className: "yrdc-trigger",
935
+ style: triggerButtonStyle,
936
+ onClick,
937
+ onPointerDown,
938
+ onPointerMove,
939
+ onPointerUp: onPointerEnd,
940
+ onPointerCancel: onPointerEnd,
941
+ "aria-label": "Dev Copilot 열기",
942
+ title: "Dev Copilot 열기/닫기 / 드래그해서 이동",
943
+ children: /* @__PURE__ */ jsx(SparklesIcon, {
944
+ "aria-hidden": true,
945
+ style: {
946
+ width: 16,
947
+ height: 16
948
+ }
949
+ })
950
+ });
951
+ }
952
+
953
+ //#endregion
954
+ //#region src/widgets/copilot-overlay/ui/response-panel-rail.tsx
955
+ function ResponsePanelRail({ showResponsePanel, onToggle }) {
956
+ return /* @__PURE__ */ jsx("div", {
957
+ style: railStyle,
958
+ children: /* @__PURE__ */ jsx("button", {
959
+ type: "button",
960
+ className: "yrdc-pressable",
961
+ style: railToggleStyle,
962
+ onClick: onToggle,
963
+ "aria-label": showResponsePanel ? "응답 패널 닫기" : "응답 패널 열기",
964
+ title: showResponsePanel ? "응답 패널 닫기" : "응답 패널 열기",
965
+ children: showResponsePanel ? /* @__PURE__ */ jsx(PanelRightCloseIcon, {
966
+ "aria-hidden": true,
967
+ style: {
968
+ width: 14,
969
+ height: 14
970
+ }
971
+ }) : /* @__PURE__ */ jsx(PanelRightOpenIcon, {
972
+ "aria-hidden": true,
973
+ style: {
974
+ width: 14,
975
+ height: 14
976
+ }
977
+ })
978
+ })
979
+ });
980
+ }
981
+
982
+ //#endregion
983
+ //#region src/widgets/copilot-overlay/ui/copilot-overlay.tsx
984
+ function CopilotOverlayWidget() {
985
+ const config = useDevCopilotConfig();
986
+ const { selectedText, setSelectedText } = useSelectionCapture();
987
+ const session = useCopilotSession();
988
+ const { agentStatus } = useAgentStatusPolling(session.open, session.selectedAgent, config.bridgeBaseUrl);
989
+ const draggable = useDraggableFab();
990
+ const containerRef = useRef(null);
991
+ useEffect(() => {
992
+ if (!session.open) return;
993
+ const onPointerDownOutside = (event) => {
994
+ const target = event.target;
995
+ if (!(target instanceof Node)) return;
996
+ if (containerRef.current?.contains(target)) return;
997
+ session.closePanel();
998
+ draggable.resetDragState();
999
+ };
1000
+ document.addEventListener("pointerdown", onPointerDownOutside);
1001
+ return () => document.removeEventListener("pointerdown", onPointerDownOutside);
1002
+ }, [
1003
+ session.open,
1004
+ session.closePanel,
1005
+ draggable.resetDragState
1006
+ ]);
1007
+ useEffect(() => {
1008
+ const onKeyDown = (event) => {
1009
+ if (!(event.key.toLowerCase() === "f" && (event.metaKey || event.ctrlKey))) return;
1010
+ const target = event.target;
1011
+ if (target instanceof Element && target.closest(`[${OVERLAY_ATTRIBUTE}]`)) return;
1012
+ const nextSelectedText = (window.getSelection()?.toString().trim() ?? "") || selectedText.trim();
1013
+ if (!nextSelectedText) return;
1014
+ event.preventDefault();
1015
+ setSelectedText(nextSelectedText);
1016
+ session.openPanel();
1017
+ };
1018
+ document.addEventListener("keydown", onKeyDown);
1019
+ return () => document.removeEventListener("keydown", onKeyDown);
1020
+ }, [
1021
+ selectedText,
1022
+ setSelectedText,
1023
+ session.openPanel
1024
+ ]);
1025
+ if (!config.enabled) return null;
1026
+ const onSubmit = async (mode) => {
1027
+ if (!isAgentReady(agentStatus)) {
1028
+ session.setError(agentStatus?.message ?? "에이전트 상태를 확인할 수 없습니다.");
1029
+ return;
1030
+ }
1031
+ if (!session.prompt.trim()) {
1032
+ session.setError("프롬프트를 입력해 주세요.");
1033
+ return;
1034
+ }
1035
+ session.startRequest();
1036
+ try {
1037
+ const route = typeof window !== "undefined" ? window.location.pathname : void 0;
1038
+ const result = await submitCopilotRequest({
1039
+ selectedText,
1040
+ prompt: session.prompt,
1041
+ mode,
1042
+ allowedPaths: config.allowedPaths,
1043
+ previousResponse: toPreviousResponse(session.chatResult),
1044
+ selectedAgent: session.selectedAgent,
1045
+ route,
1046
+ baseUrl: config.bridgeBaseUrl
1047
+ });
1048
+ session.finishRequest(result);
1049
+ } catch (error) {
1050
+ session.failRequest(toErrorMessage(error, "요청 처리 중 오류가 발생했습니다."));
1051
+ }
1052
+ };
1053
+ const onApply = async () => {
1054
+ if (!hasApplicablePatch(session.chatResult)) {
1055
+ session.setError("적용 가능한 패치가 없습니다.");
1056
+ return;
1057
+ }
1058
+ session.startApply();
1059
+ try {
1060
+ const result = await applyCopilotPatch(session.chatResult.patchId, config.bridgeBaseUrl);
1061
+ if (result.applied) {
1062
+ session.showToast(result.summary);
1063
+ window.setTimeout(session.clearToast, TOAST_DURATION_MS);
1064
+ }
1065
+ session.finishApply();
1066
+ } catch (error) {
1067
+ session.failApply(toErrorMessage(error, "패치 적용 중 오류가 발생했습니다."));
1068
+ }
1069
+ };
1070
+ const onMainToggleClick = () => {
1071
+ if (draggable.consumeToggleSuppression()) return;
1072
+ if (session.open) draggable.resetDragState();
1073
+ session.togglePanel();
1074
+ };
1075
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1076
+ /* @__PURE__ */ jsx("style", { children: OVERLAY_STYLE_TEXT }),
1077
+ /* @__PURE__ */ jsx(OverlayToast, { message: session.toastMessage }),
1078
+ /* @__PURE__ */ jsxs("div", {
1079
+ ref: containerRef,
1080
+ style: draggable.floatingWrapperStyle,
1081
+ [OVERLAY_ATTRIBUTE]: "",
1082
+ children: [/* @__PURE__ */ jsx(OverlayTrigger, {
1083
+ onClick: onMainToggleClick,
1084
+ onPointerDown: (event) => {
1085
+ const wrapperRect = containerRef.current?.getBoundingClientRect();
1086
+ const originX = draggable.position?.x ?? wrapperRect?.left ?? 0;
1087
+ const originY = draggable.position?.y ?? wrapperRect?.top ?? 0;
1088
+ draggable.onPointerDown(event, {
1089
+ x: originX,
1090
+ y: originY
1091
+ });
1092
+ },
1093
+ onPointerMove: draggable.onPointerMove,
1094
+ onPointerEnd: draggable.onPointerEnd
1095
+ }), session.open ? /* @__PURE__ */ jsxs("section", {
1096
+ style: createPanelStyle(session.showResponsePanel),
1097
+ children: [
1098
+ /* @__PURE__ */ jsx(CopilotRequestForm, {
1099
+ selectedText,
1100
+ prompt: session.prompt,
1101
+ busy: session.busy || session.applying,
1102
+ selectedAgent: session.selectedAgent,
1103
+ agentStatus,
1104
+ onSelectedTextChange: setSelectedText,
1105
+ onPromptChange: session.setPrompt,
1106
+ onAgentChange: session.setSelectedAgent,
1107
+ onSubmit
1108
+ }),
1109
+ /* @__PURE__ */ jsx(ResponsePanelRail, {
1110
+ showResponsePanel: session.showResponsePanel,
1111
+ onToggle: session.toggleResponsePanel
1112
+ }),
1113
+ session.showResponsePanel ? /* @__PURE__ */ jsx(CopilotResponsePanel, {
1114
+ busy: session.busy,
1115
+ applying: session.applying,
1116
+ error: session.error,
1117
+ chatResult: session.chatResult,
1118
+ selectedAgent: session.selectedAgent,
1119
+ onApply
1120
+ }) : null
1121
+ ]
1122
+ }) : null]
1123
+ })
1124
+ ] });
1125
+ }
1126
+
1127
+ //#endregion
1128
+ export { CopilotOverlayWidget as t };
1129
+ //# sourceMappingURL=copilot-overlay-ClRoIHew.mjs.map