@nextop-os/workspace-issue-manager 0.0.17 → 0.0.19

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 (36) hide show
  1. package/dist/{chunk-5YEGAJKA.js → chunk-5Y5GVLKU.js} +38 -4
  2. package/dist/chunk-5Y5GVLKU.js.map +1 -0
  3. package/dist/chunk-LEL6VWU4.js +1 -0
  4. package/dist/chunk-V75TAM27.js +209 -0
  5. package/dist/chunk-V75TAM27.js.map +1 -0
  6. package/dist/chunk-WSFC2COJ.js +4329 -0
  7. package/dist/chunk-WSFC2COJ.js.map +1 -0
  8. package/dist/chunk-ZWDF5XA7.js +735 -0
  9. package/dist/chunk-ZWDF5XA7.js.map +1 -0
  10. package/dist/contracts/index.d.ts +62 -33
  11. package/dist/core/index.d.ts +44 -0
  12. package/dist/core/index.js +60 -0
  13. package/dist/core/index.js.map +1 -0
  14. package/dist/{feature-B6_wXych.d.ts → feature-2zhsUF_g.d.ts} +11 -1
  15. package/dist/i18n/index.js +1 -1
  16. package/dist/index.d.ts +8 -34
  17. package/dist/index.js +47 -4
  18. package/dist/issueManagerControllerService.interface-B_Jr7Xw_.d.ts +101 -0
  19. package/dist/services/index.d.ts +11 -0
  20. package/dist/services/index.js +24 -0
  21. package/dist/services/index.js.map +1 -0
  22. package/dist/ui/index.d.ts +37 -0
  23. package/dist/ui/index.js +12 -0
  24. package/dist/ui/index.js.map +1 -0
  25. package/dist/workbench/index.d.ts +9 -2
  26. package/dist/workbench/index.js +88 -4
  27. package/dist/workbench/index.js.map +1 -1
  28. package/package.json +20 -8
  29. package/dist/chunk-5YEGAJKA.js.map +0 -1
  30. package/dist/chunk-LYYOPZIJ.js +0 -308
  31. package/dist/chunk-LYYOPZIJ.js.map +0 -1
  32. package/dist/chunk-RX6P2DPR.js +0 -3316
  33. package/dist/chunk-RX6P2DPR.js.map +0 -1
  34. package/dist/react/index.d.ts +0 -17
  35. package/dist/react/index.js +0 -11
  36. /package/dist/{react/index.js.map → chunk-LEL6VWU4.js.map} +0 -0
@@ -0,0 +1,4329 @@
1
+ import {
2
+ applyIssueManagerIssueDeleted,
3
+ applyIssueManagerIssueEditorModeToNodeState,
4
+ applyIssueManagerIssueSaved,
5
+ applyIssueManagerIssueSelection,
6
+ applyIssueManagerSelectedAgentProvider,
7
+ applyIssueManagerTaskDeleted,
8
+ applyIssueManagerTaskEditorModeToNodeState,
9
+ applyIssueManagerTaskSaved,
10
+ applyIssueManagerTaskSelection,
11
+ confirmIssueManagerMessage,
12
+ createIssueManagerControllerService,
13
+ createIssueManagerIssueDraftFromNodeState,
14
+ createIssueManagerTaskDraftFromNodeState,
15
+ defaultTaskPriority,
16
+ formatIssueManagerDate,
17
+ formatIssueManagerTimestamp,
18
+ persistIssueManagerIssueDraftContent,
19
+ persistIssueManagerIssueDraftTitle,
20
+ persistIssueManagerTaskDraftContent,
21
+ persistIssueManagerTaskDraftTitle,
22
+ resolveIssueManagerErrorMessage,
23
+ resolveIssueManagerPriorityLabel,
24
+ resolveIssueManagerStatusLabel,
25
+ toContextRefInput,
26
+ toIssueManagerWorkspaceFileLinkInput,
27
+ uniqueIssueManagerFileReferences
28
+ } from "./chunk-ZWDF5XA7.js";
29
+ import {
30
+ appendIssueManagerWorkspaceFileLinksToContent,
31
+ clampIssueManagerSidebarWidth,
32
+ extractIssueManagerPlainTextFromContent,
33
+ extractIssueManagerWorkspaceFileLinksFromContent,
34
+ issueManagerSidebarDefaultWidth,
35
+ issueManagerSidebarMaxWidth,
36
+ issueManagerSidebarMinWidth,
37
+ normalizeIssueManagerContent,
38
+ shouldAutoCollapseIssueManagerSidebar
39
+ } from "./chunk-V75TAM27.js";
40
+
41
+ // src/ui/internal/IssueManagerNodeState.ts
42
+ import { useEffect, useEffectEvent, useState } from "react";
43
+ var issueManagerTaskListCollapsedEvent = "nextop:issue-manager-task-list-collapsed";
44
+ function dispatchIssueManagerTaskListCollapsed(input) {
45
+ if (typeof window === "undefined") {
46
+ return;
47
+ }
48
+ window.dispatchEvent(
49
+ new CustomEvent(
50
+ issueManagerTaskListCollapsedEvent,
51
+ {
52
+ detail: input
53
+ }
54
+ )
55
+ );
56
+ }
57
+ function useIssueManagerTaskListCollapsedSync(input) {
58
+ const onCollapsedChange = useEffectEvent(input.onCollapsedChange);
59
+ useEffect(() => {
60
+ if (typeof window === "undefined") {
61
+ return void 0;
62
+ }
63
+ const handleTaskListCollapsedChange = (event) => {
64
+ const detail = event.detail;
65
+ if (detail?.nodeId !== input.nodeId) {
66
+ return;
67
+ }
68
+ onCollapsedChange(detail.collapsed);
69
+ };
70
+ window.addEventListener(
71
+ issueManagerTaskListCollapsedEvent,
72
+ handleTaskListCollapsedChange
73
+ );
74
+ return () => {
75
+ window.removeEventListener(
76
+ issueManagerTaskListCollapsedEvent,
77
+ handleTaskListCollapsedChange
78
+ );
79
+ };
80
+ }, [input.nodeId, onCollapsedChange]);
81
+ }
82
+ function useIssueManagerNodeHeaderView(input) {
83
+ const [manualCollapsed, setManualCollapsed] = useState(
84
+ input.isSidebarCollapsed
85
+ );
86
+ useEffect(() => {
87
+ setManualCollapsed(input.isSidebarCollapsed);
88
+ }, [input.isSidebarCollapsed]);
89
+ useIssueManagerTaskListCollapsedSync({
90
+ nodeId: input.nodeId,
91
+ onCollapsedChange: setManualCollapsed
92
+ });
93
+ const effectiveCollapsed = input.isSidebarAutoCollapsed || manualCollapsed;
94
+ return {
95
+ effectiveCollapsed,
96
+ toggleLabel: effectiveCollapsed ? input.copy.t("actions.expandIssueList") : input.copy.t("actions.collapseIssueList"),
97
+ toggleSidebar: () => {
98
+ input.onToggleSidebar(!effectiveCollapsed);
99
+ }
100
+ };
101
+ }
102
+ function resolveIssueManagerSelectedIssue(input) {
103
+ if (!input.selectedIssueId) {
104
+ return null;
105
+ }
106
+ return input.issueDetail ?? input.issues.find((issue) => issue.issueId === input.selectedIssueId) ?? null;
107
+ }
108
+ function resolveIssueManagerSelectedTask(input) {
109
+ if (!input.selectedTaskId) {
110
+ return null;
111
+ }
112
+ return input.taskDetail ?? input.tasks.find((task) => task.taskId === input.selectedTaskId) ?? null;
113
+ }
114
+
115
+ // src/ui/IssueManagerNode.tsx
116
+ import { Button as Button14, PanelIcon, cn as cn10 } from "@nextop-os/ui-system";
117
+
118
+ // src/ui/internal/IssueManagerReferencePicker.tsx
119
+ import { useEffect as useEffect2, useEffectEvent as useEffectEvent2, useMemo, useState as useState2 } from "react";
120
+ import { createPortal } from "react-dom";
121
+ import {
122
+ Button as Button3,
123
+ Card,
124
+ CardContent,
125
+ CardDescription,
126
+ CardHeader,
127
+ CardTitle,
128
+ CloseIcon
129
+ } from "@nextop-os/ui-system";
130
+
131
+ // src/ui/internal/IssueManagerReferencePickerState.ts
132
+ function normalizeDirectoryPath(path) {
133
+ if (!path || path === "/") {
134
+ return "/";
135
+ }
136
+ return path.replace(/\/+$/, "") || "/";
137
+ }
138
+ function collectVisibleTreeEntries(entries, directoryStateByPath, expandedFolderPaths) {
139
+ const collected = [];
140
+ for (const entry of entries) {
141
+ collected.push(entry);
142
+ if (entry.kind !== "folder") {
143
+ continue;
144
+ }
145
+ const folderKey = normalizeDirectoryPath(entry.path);
146
+ if (!expandedFolderPaths[folderKey]) {
147
+ continue;
148
+ }
149
+ const childEntries = directoryStateByPath[folderKey]?.entries ?? [];
150
+ if (childEntries.length === 0) {
151
+ continue;
152
+ }
153
+ collected.push(
154
+ ...collectVisibleTreeEntries(
155
+ childEntries,
156
+ directoryStateByPath,
157
+ expandedFolderPaths
158
+ )
159
+ );
160
+ }
161
+ return collected;
162
+ }
163
+ function createReferenceDirectoryStateFromSnapshot(snapshot) {
164
+ const stateByPath = {};
165
+ addReferenceDirectoryStateFromSnapshot(stateByPath, snapshot.directory);
166
+ return stateByPath;
167
+ }
168
+ function addReferenceDirectoryStateFromSnapshot(stateByPath, directory) {
169
+ const normalizedPath = normalizeDirectoryPath(directory.directoryPath);
170
+ stateByPath[normalizedPath] = {
171
+ displayPath: directory.directoryPath,
172
+ entries: directory.entries.map((entry) => ({
173
+ displayName: entry.displayName,
174
+ kind: entry.kind,
175
+ path: entry.path
176
+ })),
177
+ loaded: true,
178
+ loading: false,
179
+ prefetchReason: directory.prefetchReason,
180
+ prefetchState: directory.prefetchState
181
+ };
182
+ for (const entry of directory.entries) {
183
+ if (entry.kind !== "folder") {
184
+ continue;
185
+ }
186
+ const folderKey = normalizeDirectoryPath(entry.path);
187
+ if (entry.prefetchedDirectory) {
188
+ addReferenceDirectoryStateFromSnapshot(
189
+ stateByPath,
190
+ entry.prefetchedDirectory
191
+ );
192
+ continue;
193
+ }
194
+ if (entry.prefetchState) {
195
+ stateByPath[folderKey] = {
196
+ displayPath: entry.path,
197
+ entries: [],
198
+ loaded: false,
199
+ loading: false,
200
+ prefetchReason: entry.prefetchReason,
201
+ prefetchState: entry.prefetchState
202
+ };
203
+ }
204
+ }
205
+ }
206
+
207
+ // src/ui/internal/IssueManagerReferencePickerSections.tsx
208
+ import { Badge, Button as Button2, DirectoryIcon as DirectoryIcon2, FileIcon as FileIcon2 } from "@nextop-os/ui-system";
209
+
210
+ // src/ui/internal/IssueManagerReferencePickerTree.tsx
211
+ import {
212
+ ArrowRightIcon,
213
+ Button,
214
+ CheckIcon,
215
+ DirectoryIcon,
216
+ FileIcon,
217
+ Input,
218
+ LoadingIcon,
219
+ ScrollArea,
220
+ SearchIcon,
221
+ cn
222
+ } from "@nextop-os/ui-system";
223
+ import { jsx, jsxs } from "react/jsx-runtime";
224
+ var issueManagerReferenceTreeIndent = 20;
225
+ function IssueManagerReferencePickerBrowserPane({
226
+ browseRootEntries,
227
+ copy,
228
+ directoryStateByPath,
229
+ expandedFolderPaths,
230
+ focusedPath,
231
+ isLoading,
232
+ mode,
233
+ searchQuery,
234
+ selectedRefs,
235
+ setSearchQuery,
236
+ visibleEntries,
237
+ onFocusPath,
238
+ onToggleFolder,
239
+ onToggleRef
240
+ }) {
241
+ return /* @__PURE__ */ jsxs("section", { className: "flex min-h-0 flex-col border-b border-border/70 lg:border-r lg:border-b-0", children: [
242
+ /* @__PURE__ */ jsx("div", { className: "space-y-3 border-b border-border/70 px-4 py-4 sm:px-5", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
243
+ /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }),
244
+ /* @__PURE__ */ jsx(
245
+ Input,
246
+ {
247
+ className: "pl-9",
248
+ placeholder: copy.t("referencePicker.searchPlaceholder"),
249
+ value: searchQuery,
250
+ onChange: (event) => setSearchQuery(event.target.value)
251
+ }
252
+ )
253
+ ] }) }),
254
+ /* @__PURE__ */ jsx(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 p-3", children: isLoading ? /* @__PURE__ */ jsx(IssueManagerReferencePickerFeedback, { children: /* @__PURE__ */ jsx(LoadingIcon, { className: "size-4 animate-spin" }) }) : visibleEntries.length === 0 ? /* @__PURE__ */ jsx(IssueManagerReferencePickerFeedback, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) : mode === "browse" ? /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: browseRootEntries.map((entry) => /* @__PURE__ */ jsx(
255
+ IssueManagerReferencePickerTreeEntry,
256
+ {
257
+ childDepth: 1,
258
+ copy,
259
+ directoryStateByPath,
260
+ entry,
261
+ expandedFolderPaths,
262
+ focusedPath,
263
+ selectedRefs,
264
+ onFocusPath,
265
+ onToggleFolder,
266
+ onToggleRef
267
+ },
268
+ entry.path
269
+ )) }) : visibleEntries.map((entry) => /* @__PURE__ */ jsx(
270
+ IssueManagerReferencePickerSearchEntry,
271
+ {
272
+ entry,
273
+ focused: focusedPath === entry.path,
274
+ selected: selectedRefs.some((item) => item.path === entry.path),
275
+ onFocusPath,
276
+ onToggleRef
277
+ },
278
+ entry.path
279
+ )) }) })
280
+ ] });
281
+ }
282
+ function IssueManagerReferencePickerTreeEntry({
283
+ childDepth,
284
+ copy,
285
+ directoryStateByPath,
286
+ entry,
287
+ expandedFolderPaths,
288
+ focusedPath,
289
+ selectedRefs,
290
+ onFocusPath,
291
+ onToggleFolder,
292
+ onToggleRef
293
+ }) {
294
+ const selected = selectedRefs.some((item) => item.path === entry.path);
295
+ const focused = focusedPath === entry.path;
296
+ const isFolder = entry.kind === "folder";
297
+ const folderKey = normalizeDirectoryPath(entry.path);
298
+ const expanded = expandedFolderPaths[folderKey] ?? false;
299
+ const childState = directoryStateByPath[folderKey];
300
+ const childEntries = childState?.entries ?? [];
301
+ return /* @__PURE__ */ jsxs("div", { children: [
302
+ /* @__PURE__ */ jsxs(
303
+ "div",
304
+ {
305
+ className: cn(
306
+ "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-lg px-2 py-1.5 transition-colors",
307
+ focused || selected ? "bg-transparency-block" : "hover:bg-transparency-block/60"
308
+ ),
309
+ style: {
310
+ paddingLeft: `${(childDepth - 1) * issueManagerReferenceTreeIndent + 8}px`
311
+ },
312
+ children: [
313
+ isFolder ? /* @__PURE__ */ jsx(
314
+ "button",
315
+ {
316
+ "aria-label": resolveIssueManagerReferenceLabel(entry),
317
+ className: "grid size-5 shrink-0 place-items-center rounded-sm text-muted-foreground hover:bg-background/80",
318
+ type: "button",
319
+ onClick: () => onToggleFolder(entry),
320
+ children: /* @__PURE__ */ jsx(
321
+ ArrowRightIcon,
322
+ {
323
+ className: cn(
324
+ "size-3.5 transition-transform",
325
+ expanded && "rotate-90"
326
+ )
327
+ }
328
+ )
329
+ }
330
+ ) : /* @__PURE__ */ jsx("span", { className: "block size-5 shrink-0" }),
331
+ /* @__PURE__ */ jsxs(
332
+ "button",
333
+ {
334
+ className: "flex min-w-0 items-center gap-2 text-left",
335
+ type: "button",
336
+ onClick: () => {
337
+ onFocusPath(entry.path);
338
+ if (entry.kind === "folder") {
339
+ onToggleFolder(entry);
340
+ }
341
+ },
342
+ children: [
343
+ isFolder ? /* @__PURE__ */ jsx(DirectoryIcon, { className: "size-4 shrink-0 text-muted-foreground" }) : /* @__PURE__ */ jsx(FileIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
344
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm text-foreground", children: resolveIssueManagerReferenceLabel(entry) })
345
+ ]
346
+ }
347
+ ),
348
+ /* @__PURE__ */ jsx(
349
+ Button,
350
+ {
351
+ size: "xs",
352
+ type: "button",
353
+ variant: selected ? "secondary" : "outline",
354
+ onClick: () => {
355
+ onFocusPath(entry.path);
356
+ onToggleRef(entry);
357
+ },
358
+ children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : "+"
359
+ }
360
+ )
361
+ ]
362
+ }
363
+ ),
364
+ isFolder && expanded ? childState?.loading ? /* @__PURE__ */ jsxs(
365
+ "div",
366
+ {
367
+ className: "flex items-center gap-2 px-2 py-2 text-xs text-muted-foreground",
368
+ style: {
369
+ paddingLeft: `${childDepth * issueManagerReferenceTreeIndent + 12}px`
370
+ },
371
+ children: [
372
+ /* @__PURE__ */ jsx(LoadingIcon, { className: "size-3.5 animate-spin" }),
373
+ /* @__PURE__ */ jsx("span", { children: copy.t("referencePicker.loading") })
374
+ ]
375
+ }
376
+ ) : childEntries.length > 0 ? childEntries.map((childEntry) => /* @__PURE__ */ jsx(
377
+ IssueManagerReferencePickerTreeEntry,
378
+ {
379
+ childDepth: childDepth + 1,
380
+ copy,
381
+ directoryStateByPath,
382
+ entry: childEntry,
383
+ expandedFolderPaths,
384
+ focusedPath,
385
+ selectedRefs,
386
+ onFocusPath,
387
+ onToggleFolder,
388
+ onToggleRef
389
+ },
390
+ childEntry.path
391
+ )) : childState?.loaded ? /* @__PURE__ */ jsx(
392
+ "div",
393
+ {
394
+ className: "px-2 py-2 text-xs text-muted-foreground",
395
+ style: {
396
+ paddingLeft: `${childDepth * issueManagerReferenceTreeIndent + 12}px`
397
+ },
398
+ children: copy.t("referencePicker.emptyDirectory")
399
+ }
400
+ ) : null : null
401
+ ] });
402
+ }
403
+ function IssueManagerReferencePickerSearchEntry({
404
+ entry,
405
+ focused,
406
+ selected,
407
+ onFocusPath,
408
+ onToggleRef
409
+ }) {
410
+ const isFolder = entry.kind === "folder";
411
+ return /* @__PURE__ */ jsxs(
412
+ "div",
413
+ {
414
+ className: cn(
415
+ "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-xl border px-3 py-2.5 transition-colors",
416
+ focused || selected ? "border-border bg-transparency-block" : "border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block/60"
417
+ ),
418
+ children: [
419
+ /* @__PURE__ */ jsxs(
420
+ "button",
421
+ {
422
+ className: "flex min-w-0 items-center gap-3 text-left",
423
+ type: "button",
424
+ onClick: () => onFocusPath(entry.path),
425
+ children: [
426
+ /* @__PURE__ */ jsx("span", { className: "grid size-9 shrink-0 place-items-center rounded-lg bg-background/90 text-muted-foreground", children: isFolder ? /* @__PURE__ */ jsx(DirectoryIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(FileIcon, { className: "size-4" }) }),
427
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
428
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: resolveIssueManagerReferenceLabel(entry) }),
429
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: entry.path })
430
+ ] })
431
+ ]
432
+ }
433
+ ),
434
+ /* @__PURE__ */ jsx(
435
+ Button,
436
+ {
437
+ size: "xs",
438
+ type: "button",
439
+ variant: selected ? "secondary" : "outline",
440
+ onClick: () => {
441
+ onFocusPath(entry.path);
442
+ onToggleRef(entry);
443
+ },
444
+ children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : "+"
445
+ }
446
+ )
447
+ ]
448
+ }
449
+ );
450
+ }
451
+ function IssueManagerReferencePickerFeedback({
452
+ children
453
+ }) {
454
+ return /* @__PURE__ */ jsx("div", { className: "grid min-h-[10rem] place-items-center px-4 text-center text-sm text-muted-foreground", children });
455
+ }
456
+ function resolveIssueManagerReferenceLabel(ref) {
457
+ return ref.displayName || ref.path.split("/").filter(Boolean).at(-1) || ref.path;
458
+ }
459
+
460
+ // src/ui/internal/IssueManagerReferencePickerSections.tsx
461
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
462
+ function IssueManagerReferencePickerPreviewPane({
463
+ copy,
464
+ focusedEntry,
465
+ mode
466
+ }) {
467
+ return /* @__PURE__ */ jsx2("aside", { className: "flex shrink-0 flex-col border-t border-border/70 bg-panel/40 lg:min-h-0 lg:flex-1 lg:border-t-0", children: /* @__PURE__ */ jsx2("div", { className: "flex min-h-0 flex-1 flex-col px-4 py-4 sm:px-5 lg:py-5", children: focusedEntry ? /* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-col gap-4 lg:flex-1 lg:gap-5", children: [
468
+ /* @__PURE__ */ jsx2("div", { className: "flex h-32 min-h-32 items-center justify-center rounded-2xl border border-border/70 bg-background/72 p-5 sm:h-40 sm:min-h-40 lg:h-56 lg:min-h-56 lg:p-6", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-4 text-center", children: [
469
+ /* @__PURE__ */ jsx2("span", { className: "mx-auto grid size-14 place-items-center rounded-2xl bg-transparency-block text-muted-foreground", children: focusedEntry.kind === "folder" ? /* @__PURE__ */ jsx2(DirectoryIcon2, { className: "size-7" }) : /* @__PURE__ */ jsx2(FileIcon2, { className: "size-7" }) }),
470
+ /* @__PURE__ */ jsx2("p", { className: "max-w-[24ch] text-sm leading-5 text-muted-foreground [overflow-wrap:anywhere]", children: focusedEntry.kind === "folder" ? focusedEntry.path : resolveIssueManagerReferenceLabel(focusedEntry) })
471
+ ] }) }),
472
+ /* @__PURE__ */ jsx2("div", { className: "space-y-2 lg:space-y-3", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5", children: [
473
+ /* @__PURE__ */ jsx2("p", { className: "truncate text-[15px] font-semibold text-foreground", children: resolveIssueManagerReferenceLabel(focusedEntry) }),
474
+ /* @__PURE__ */ jsx2("p", { className: "line-clamp-3 text-sm text-muted-foreground [overflow-wrap:anywhere]", children: focusedEntry.path })
475
+ ] }) })
476
+ ] }) : /* @__PURE__ */ jsx2(IssueManagerReferencePickerFeedback2, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) }) });
477
+ }
478
+ function IssueManagerReferencePickerFooter({
479
+ copy,
480
+ onClose,
481
+ onConfirm,
482
+ selectedRefs
483
+ }) {
484
+ return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-3 border-t border-border/70 px-4 py-4 sm:px-6 lg:flex-row lg:items-center lg:justify-between", children: [
485
+ /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:flex-1", children: [
486
+ /* @__PURE__ */ jsx2("span", { className: "text-sm text-muted-foreground", children: copy.t("referencePicker.selectedCount", {
487
+ count: selectedRefs.length
488
+ }) }),
489
+ selectedRefs.slice(0, 2).map((ref) => /* @__PURE__ */ jsx2(
490
+ Badge,
491
+ {
492
+ className: "max-w-[14rem] border-border/70 bg-background/80 text-foreground",
493
+ children: /* @__PURE__ */ jsx2("span", { className: "truncate", children: resolveIssueManagerReferenceLabel(ref) })
494
+ },
495
+ ref.path
496
+ )),
497
+ selectedRefs.length > 2 ? /* @__PURE__ */ jsxs2(Badge, { className: "border-border/70 bg-background/80 text-muted-foreground", children: [
498
+ "+",
499
+ selectedRefs.length - 2
500
+ ] }) : null
501
+ ] }),
502
+ /* @__PURE__ */ jsxs2("div", { className: "flex w-full items-center justify-end gap-2 lg:w-auto lg:shrink-0", children: [
503
+ /* @__PURE__ */ jsx2(Button2, { type: "button", variant: "outline", onClick: onClose, children: copy.t("actions.cancel") }),
504
+ /* @__PURE__ */ jsx2(
505
+ Button2,
506
+ {
507
+ disabled: selectedRefs.length === 0,
508
+ type: "button",
509
+ onClick: onConfirm,
510
+ children: copy.t("referencePicker.confirm")
511
+ }
512
+ )
513
+ ] })
514
+ ] });
515
+ }
516
+ function IssueManagerReferencePickerFeedback2({
517
+ children
518
+ }) {
519
+ return /* @__PURE__ */ jsx2("div", { className: "grid min-h-[10rem] place-items-center px-4 text-center text-sm text-muted-foreground", children });
520
+ }
521
+
522
+ // src/ui/internal/IssueManagerReferencePicker.tsx
523
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
524
+ var defaultDirectoryPath = "/";
525
+ function IssueManagerReferencePicker({
526
+ copy,
527
+ fileAdapter,
528
+ onClose,
529
+ onConfirm,
530
+ open,
531
+ workspaceId
532
+ }) {
533
+ const [searchQuery, setSearchQuery] = useState2("");
534
+ const [browseRootPath, setBrowseRootPath] = useState2(null);
535
+ const [searchEntries, setSearchEntries] = useState2([]);
536
+ const [directoryStateByPath, setDirectoryStateByPath] = useState2({});
537
+ const [expandedFolderPaths, setExpandedFolderPaths] = useState2({});
538
+ const [focusedPath, setFocusedPath] = useState2(null);
539
+ const [isLoading, setIsLoading] = useState2(false);
540
+ const [selectedRefs, setSelectedRefs] = useState2(
541
+ []
542
+ );
543
+ const supportsSearch = hasFileAdapterMethod(fileAdapter, "searchReferences");
544
+ const supportsTreeSnapshot = hasFileAdapterMethod(
545
+ fileAdapter,
546
+ "loadReferenceTree"
547
+ );
548
+ const mode = searchQuery.trim().length > 0 && supportsSearch ? "search" : "browse";
549
+ const browseDirectoryLoaded = browseRootPath !== null && directoryStateByPath[normalizeDirectoryPath(browseRootPath)]?.loaded === true;
550
+ const finalizeRequestedReferences = useEffectEvent2(
551
+ (refs) => {
552
+ onConfirm(uniqueIssueManagerFileReferences(refs));
553
+ onClose();
554
+ }
555
+ );
556
+ const readDirectoryListing = async (path) => {
557
+ if (!fileAdapter?.listDirectory) {
558
+ return null;
559
+ }
560
+ const listing = await fileAdapter.listDirectory({
561
+ path: path ?? void 0,
562
+ workspaceId
563
+ });
564
+ return {
565
+ displayPath: listing.directoryPath || listing.rootPath || path || defaultDirectoryPath,
566
+ entries: uniqueIssueManagerFileReferences(listing.entries),
567
+ normalizedPath: normalizeDirectoryPath(
568
+ listing.directoryPath || listing.rootPath || path || defaultDirectoryPath
569
+ )
570
+ };
571
+ };
572
+ useEffect2(() => {
573
+ if (!open) {
574
+ return;
575
+ }
576
+ setSearchQuery("");
577
+ setBrowseRootPath(null);
578
+ setSearchEntries([]);
579
+ setDirectoryStateByPath({});
580
+ setExpandedFolderPaths({});
581
+ setFocusedPath(null);
582
+ setSelectedRefs([]);
583
+ }, [open]);
584
+ useEffect2(() => {
585
+ if (!open || !fileAdapter) {
586
+ return;
587
+ }
588
+ let canceled = false;
589
+ const load = async () => {
590
+ setIsLoading(true);
591
+ try {
592
+ if (mode === "search" && fileAdapter.searchReferences) {
593
+ const refs = await fileAdapter.searchReferences({
594
+ query: searchQuery.trim(),
595
+ workspaceId
596
+ });
597
+ if (!canceled) {
598
+ setSearchEntries(uniqueIssueManagerFileReferences(refs));
599
+ }
600
+ return;
601
+ }
602
+ if (mode === "browse" && (fileAdapter.listDirectory || fileAdapter.loadReferenceTree)) {
603
+ if (browseDirectoryLoaded && browseRootPath) {
604
+ return;
605
+ }
606
+ if (supportsTreeSnapshot && fileAdapter.loadReferenceTree) {
607
+ const snapshot = await fileAdapter.loadReferenceTree({
608
+ path: browseRootPath ?? void 0,
609
+ prefetchBudgetMs: 500,
610
+ prefetchDepth: 4,
611
+ workspaceId
612
+ });
613
+ if (!canceled) {
614
+ setBrowseRootPath(
615
+ normalizeDirectoryPath(snapshot.directory.directoryPath)
616
+ );
617
+ setDirectoryStateByPath(
618
+ createReferenceDirectoryStateFromSnapshot(snapshot)
619
+ );
620
+ }
621
+ return;
622
+ }
623
+ const listing = await readDirectoryListing(browseRootPath);
624
+ if (!listing) {
625
+ return;
626
+ }
627
+ if (!canceled) {
628
+ setBrowseRootPath(listing.normalizedPath);
629
+ setDirectoryStateByPath((current) => ({
630
+ ...current,
631
+ [listing.normalizedPath]: {
632
+ displayPath: listing.displayPath,
633
+ entries: listing.entries,
634
+ loaded: true,
635
+ loading: false
636
+ }
637
+ }));
638
+ }
639
+ return;
640
+ }
641
+ if (fileAdapter.requestReferences) {
642
+ const refs = await fileAdapter.requestReferences({ workspaceId });
643
+ if (!canceled) {
644
+ finalizeRequestedReferences(refs);
645
+ }
646
+ return;
647
+ }
648
+ if (!canceled) {
649
+ setSearchEntries([]);
650
+ }
651
+ } finally {
652
+ if (!canceled) {
653
+ setIsLoading(false);
654
+ }
655
+ }
656
+ };
657
+ void load();
658
+ return () => {
659
+ canceled = true;
660
+ };
661
+ }, [
662
+ browseDirectoryLoaded,
663
+ browseRootPath,
664
+ fileAdapter,
665
+ mode,
666
+ open,
667
+ searchQuery,
668
+ supportsTreeSnapshot,
669
+ workspaceId
670
+ ]);
671
+ const browseRootEntries = useMemo(
672
+ () => browseRootPath ? directoryStateByPath[normalizeDirectoryPath(browseRootPath)]?.entries ?? [] : [],
673
+ [browseRootPath, directoryStateByPath]
674
+ );
675
+ const visibleEntries = useMemo(
676
+ () => mode === "search" ? searchEntries : collectVisibleTreeEntries(
677
+ browseRootEntries,
678
+ directoryStateByPath,
679
+ expandedFolderPaths
680
+ ),
681
+ [
682
+ browseRootEntries,
683
+ directoryStateByPath,
684
+ expandedFolderPaths,
685
+ mode,
686
+ searchEntries
687
+ ]
688
+ );
689
+ useEffect2(() => {
690
+ if (!open) {
691
+ return;
692
+ }
693
+ setFocusedPath((current) => {
694
+ if (current && visibleEntries.some((entry) => entry.path === current)) {
695
+ return current;
696
+ }
697
+ return visibleEntries[0]?.path ?? null;
698
+ });
699
+ }, [open, visibleEntries]);
700
+ if (!open) {
701
+ return null;
702
+ }
703
+ const focusedEntry = visibleEntries.find((entry) => entry.path === focusedPath) ?? selectedRefs.find((entry) => entry.path === focusedPath) ?? null;
704
+ const toggleRef = (ref) => {
705
+ setSelectedRefs((current) => {
706
+ const existing = current.some((item) => item.path === ref.path);
707
+ return existing ? current.filter((item) => item.path !== ref.path) : uniqueIssueManagerFileReferences([...current, ref]);
708
+ });
709
+ };
710
+ const loadFolderChildren = async (folder) => {
711
+ const folderKey = normalizeDirectoryPath(folder.path);
712
+ if (directoryStateByPath[folderKey]?.loaded) {
713
+ return;
714
+ }
715
+ setDirectoryStateByPath((current) => ({
716
+ ...current,
717
+ [folderKey]: {
718
+ displayPath: folder.path,
719
+ entries: current[folderKey]?.entries ?? [],
720
+ loaded: current[folderKey]?.loaded ?? false,
721
+ loading: true
722
+ }
723
+ }));
724
+ try {
725
+ const listing = await readDirectoryListing(folderKey);
726
+ if (!listing) {
727
+ return;
728
+ }
729
+ setDirectoryStateByPath((current) => ({
730
+ ...current,
731
+ [folderKey]: {
732
+ displayPath: listing.displayPath,
733
+ entries: listing.entries,
734
+ loaded: true,
735
+ loading: false
736
+ }
737
+ }));
738
+ } catch {
739
+ setDirectoryStateByPath((current) => ({
740
+ ...current,
741
+ [folderKey]: {
742
+ displayPath: current[folderKey]?.displayPath ?? folder.path,
743
+ entries: current[folderKey]?.entries ?? [],
744
+ loaded: current[folderKey]?.loaded ?? false,
745
+ loading: false
746
+ }
747
+ }));
748
+ }
749
+ };
750
+ const toggleFolder = (entry) => {
751
+ const folderKey = normalizeDirectoryPath(entry.path);
752
+ const childState = directoryStateByPath[folderKey];
753
+ const nextExpanded = !(expandedFolderPaths[folderKey] ?? false);
754
+ setExpandedFolderPaths((current) => ({
755
+ ...current,
756
+ [folderKey]: nextExpanded
757
+ }));
758
+ if (nextExpanded && !childState?.loaded && !childState?.loading) {
759
+ void loadFolderChildren(entry);
760
+ }
761
+ };
762
+ const dialog = /* @__PURE__ */ jsx3(
763
+ "div",
764
+ {
765
+ className: "fixed inset-0 grid place-items-center bg-black/24 px-3 py-4 backdrop-blur-md sm:px-6 sm:py-8",
766
+ style: { zIndex: "var(--z-panel)" },
767
+ onClick: onClose,
768
+ children: /* @__PURE__ */ jsxs3(
769
+ Card,
770
+ {
771
+ "aria-modal": "true",
772
+ className: "flex h-[min(88vh,44rem)] w-full max-w-5xl flex-col gap-0 overflow-hidden border-border/70 bg-popover/98 py-0 shadow-[var(--workbench-window-elevation)] sm:h-[min(82vh,44rem)]",
773
+ role: "dialog",
774
+ onClick: (event) => event.stopPropagation(),
775
+ children: [
776
+ /* @__PURE__ */ jsx3(CardHeader, { className: "border-b border-border/70 px-4 py-4 sm:px-6 sm:py-5", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between gap-4", children: [
777
+ /* @__PURE__ */ jsxs3("div", { className: "min-w-0 space-y-1", children: [
778
+ /* @__PURE__ */ jsx3(CardTitle, { children: copy.t("referencePicker.title") }),
779
+ /* @__PURE__ */ jsx3(CardDescription, { children: copy.t("referencePicker.selectedCount", {
780
+ count: selectedRefs.length
781
+ }) })
782
+ ] }),
783
+ /* @__PURE__ */ jsx3(
784
+ Button3,
785
+ {
786
+ "aria-label": copy.t("actions.cancel"),
787
+ size: "icon-sm",
788
+ type: "button",
789
+ variant: "ghost",
790
+ onClick: onClose,
791
+ children: /* @__PURE__ */ jsx3(CloseIcon, { size: 16 })
792
+ }
793
+ )
794
+ ] }) }),
795
+ /* @__PURE__ */ jsxs3(CardContent, { className: "grid min-h-0 flex-1 grid-rows-[minmax(0,1fr)_auto] gap-0 overflow-hidden p-0 lg:grid-cols-[minmax(0,1.15fr)_minmax(20rem,0.85fr)] lg:grid-rows-1", children: [
796
+ /* @__PURE__ */ jsx3(
797
+ IssueManagerReferencePickerBrowserPane,
798
+ {
799
+ browseRootEntries,
800
+ copy,
801
+ directoryStateByPath,
802
+ expandedFolderPaths,
803
+ focusedPath,
804
+ isLoading,
805
+ mode,
806
+ searchQuery,
807
+ selectedRefs,
808
+ setSearchQuery,
809
+ visibleEntries,
810
+ onFocusPath: setFocusedPath,
811
+ onToggleFolder: toggleFolder,
812
+ onToggleRef: toggleRef
813
+ }
814
+ ),
815
+ /* @__PURE__ */ jsx3(
816
+ IssueManagerReferencePickerPreviewPane,
817
+ {
818
+ copy,
819
+ focusedEntry,
820
+ mode
821
+ }
822
+ )
823
+ ] }),
824
+ /* @__PURE__ */ jsx3(
825
+ IssueManagerReferencePickerFooter,
826
+ {
827
+ copy,
828
+ onClose,
829
+ onConfirm: () => onConfirm(selectedRefs),
830
+ selectedRefs
831
+ }
832
+ )
833
+ ]
834
+ }
835
+ )
836
+ }
837
+ );
838
+ if (typeof document === "undefined") {
839
+ return dialog;
840
+ }
841
+ return createPortal(dialog, document.body);
842
+ }
843
+ function hasFileAdapterMethod(fileAdapter, methodName) {
844
+ return typeof Reflect.get(fileAdapter ?? {}, methodName) === "function";
845
+ }
846
+
847
+ // src/ui/internal/IssueManagerShell.tsx
848
+ import { Button as Button13, cn as cn9 } from "@nextop-os/ui-system";
849
+
850
+ // src/ui/internal/IssueManagerPanels.tsx
851
+ import { Badge as Badge3, Button as Button7, Input as Input2 } from "@nextop-os/ui-system";
852
+
853
+ // src/ui/internal/IssueManagerIssueSections.tsx
854
+ import {
855
+ Badge as Badge2,
856
+ Button as Button5,
857
+ FileCreateIcon as FileCreateIcon2,
858
+ ScrollArea as ScrollArea2,
859
+ cn as cn2
860
+ } from "@nextop-os/ui-system";
861
+
862
+ // src/ui/internal/IssueManagerPanelText.ts
863
+ function summarizeIssueManagerContent(content, fallback) {
864
+ const plainText = extractIssueManagerPlainTextFromContent(
865
+ content ?? ""
866
+ ).trim();
867
+ if (!plainText) {
868
+ return fallback;
869
+ }
870
+ if (plainText.length <= 120) {
871
+ return plainText;
872
+ }
873
+ return `${plainText.slice(0, 117)}...`;
874
+ }
875
+ function resolveTaskCreatorLabel(task) {
876
+ return resolveIssueManagerCreatorLabel(task);
877
+ }
878
+ function resolveIssueManagerCreatorLabel(entity) {
879
+ return entity.creatorDisplayName?.trim() || entity.creatorUserId;
880
+ }
881
+
882
+ // src/ui/internal/IssueManagerPanelSurface.tsx
883
+ import { Button as Button4, FileCreateIcon } from "@nextop-os/ui-system";
884
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
885
+ var workspaceDockTaskImage = new URL(
886
+ "../../assets/workspace-dock-task.png",
887
+ import.meta.url
888
+ ).href;
889
+ function IssueManagerEmptyIllustration() {
890
+ return /* @__PURE__ */ jsx4(
891
+ "img",
892
+ {
893
+ alt: "",
894
+ "aria-hidden": "true",
895
+ className: "h-[84px] w-[84px] object-contain",
896
+ decoding: "async",
897
+ draggable: false,
898
+ src: workspaceDockTaskImage
899
+ }
900
+ );
901
+ }
902
+ function IssueManagerPaneLoadingState() {
903
+ return /* @__PURE__ */ jsxs4(
904
+ "div",
905
+ {
906
+ "aria-hidden": "true",
907
+ className: "mx-auto flex w-full max-w-4xl flex-col gap-6",
908
+ children: [
909
+ /* @__PURE__ */ jsx4("div", { className: "h-6 w-28 rounded-full bg-muted" }),
910
+ /* @__PURE__ */ jsx4("div", { className: "h-12 w-2/3 rounded-full bg-muted" }),
911
+ /* @__PURE__ */ jsxs4("div", { className: "rounded-[28px] border border-border/70 bg-transparent px-5 py-5", children: [
912
+ /* @__PURE__ */ jsx4("div", { className: "h-4 w-24 rounded-full bg-muted" }),
913
+ /* @__PURE__ */ jsx4("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
914
+ /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
915
+ /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-10/12 rounded-full bg-muted" })
916
+ ] }),
917
+ /* @__PURE__ */ jsxs4("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-5 py-5", children: [
918
+ /* @__PURE__ */ jsx4("div", { className: "h-4 w-32 rounded-full bg-muted" }),
919
+ /* @__PURE__ */ jsx4("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
920
+ /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
921
+ ] })
922
+ ]
923
+ }
924
+ );
925
+ }
926
+ function IssueManagerTaskDrawerLoadingState() {
927
+ return /* @__PURE__ */ jsxs4("div", { "aria-hidden": "true", className: "grid gap-5", children: [
928
+ /* @__PURE__ */ jsx4("div", { className: "h-12 w-full rounded-2xl bg-muted" }),
929
+ /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-2 gap-3", children: [
930
+ /* @__PURE__ */ jsx4("div", { className: "h-10 rounded-xl bg-muted" }),
931
+ /* @__PURE__ */ jsx4("div", { className: "h-10 rounded-xl bg-muted" })
932
+ ] }),
933
+ /* @__PURE__ */ jsxs4("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-4 py-4", children: [
934
+ /* @__PURE__ */ jsx4("div", { className: "h-4 w-24 rounded-full bg-muted" }),
935
+ /* @__PURE__ */ jsx4("div", { className: "mt-4 h-4 w-full rounded-full bg-muted" }),
936
+ /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
937
+ /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
938
+ ] })
939
+ ] });
940
+ }
941
+
942
+ // src/ui/internal/IssueManagerIssueSections.tsx
943
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
944
+ function IssueManagerDetailTextSection({
945
+ body,
946
+ label,
947
+ meta,
948
+ tone = "muted"
949
+ }) {
950
+ return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
951
+ /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-foreground", children: label }),
952
+ /* @__PURE__ */ jsxs5("div", { className: "grid gap-1.5", children: [
953
+ /* @__PURE__ */ jsx5(
954
+ "p",
955
+ {
956
+ className: cn2(
957
+ "text-sm leading-6",
958
+ tone === "destructive" ? "text-destructive" : "text-muted-foreground"
959
+ ),
960
+ children: body
961
+ }
962
+ ),
963
+ meta ? /* @__PURE__ */ jsx5("p", { className: "text-xs leading-5 text-muted-foreground", children: meta }) : null
964
+ ] })
965
+ ] });
966
+ }
967
+ function IssueManagerOutputSection({
968
+ copy,
969
+ onOpen,
970
+ outputs
971
+ }) {
972
+ return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
973
+ /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-foreground", children: copy.t("labels.executionOutputs") }),
974
+ outputs.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-sm leading-6 text-muted-foreground", children: copy.t("messages.noExecutionOutputs") }) : /* @__PURE__ */ jsx5("div", { className: "grid gap-2", children: outputs.map((output) => /* @__PURE__ */ jsxs5(
975
+ "button",
976
+ {
977
+ className: "flex items-start justify-between gap-4 rounded-xl border border-border/65 px-4 py-3 text-left transition-colors hover:bg-accent/18",
978
+ type: "button",
979
+ onClick: () => {
980
+ void onOpen({
981
+ displayName: output.displayName,
982
+ kind: "file",
983
+ path: output.path
984
+ });
985
+ },
986
+ children: [
987
+ /* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1", children: [
988
+ /* @__PURE__ */ jsx5("span", { className: "block truncate text-sm font-semibold text-foreground", children: output.displayName }),
989
+ /* @__PURE__ */ jsx5("span", { className: "mt-1 block truncate text-xs text-muted-foreground", children: output.path })
990
+ ] }),
991
+ /* @__PURE__ */ jsx5("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatIssueManagerTimestamp(output.createdAtUnix) || "" })
992
+ ]
993
+ },
994
+ output.outputId
995
+ )) })
996
+ ] });
997
+ }
998
+ function IssueManagerSubtaskSection({
999
+ copy,
1000
+ onCreate,
1001
+ onSelectTask,
1002
+ selectedTaskId,
1003
+ tasks
1004
+ }) {
1005
+ return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
1006
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-3", children: [
1007
+ /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-foreground", children: copy.t("labels.subtasks") }),
1008
+ /* @__PURE__ */ jsxs5(
1009
+ Button5,
1010
+ {
1011
+ className: "px-3",
1012
+ size: "dialog",
1013
+ type: "button",
1014
+ variant: "secondary",
1015
+ onClick: onCreate,
1016
+ children: [
1017
+ /* @__PURE__ */ jsx5(FileCreateIcon2, { size: 14 }),
1018
+ copy.t("actions.add")
1019
+ ]
1020
+ }
1021
+ )
1022
+ ] }),
1023
+ tasks.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-sm leading-6 text-muted-foreground", children: copy.t("messages.noSubtasksForIssue") }) : /* @__PURE__ */ jsx5("div", { className: "grid gap-2", children: tasks.map((task) => /* @__PURE__ */ jsxs5(
1024
+ "button",
1025
+ {
1026
+ className: cn2(
1027
+ "flex items-start justify-between gap-4 rounded-xl border px-4 py-3 text-left transition-colors",
1028
+ selectedTaskId === task.taskId ? "border-border/90 bg-background-fronted" : "border-border/65 hover:bg-accent/18"
1029
+ ),
1030
+ type: "button",
1031
+ onClick: () => onSelectTask(task.taskId),
1032
+ children: [
1033
+ /* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex-1", children: [
1034
+ /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2.5", children: [
1035
+ /* @__PURE__ */ jsx5("span", { className: "truncate text-sm font-semibold text-foreground", children: task.title }),
1036
+ /* @__PURE__ */ jsx5(Badge2, { className: "rounded-md border-transparent bg-muted px-2 py-1 text-[11px] font-medium text-muted-foreground", children: resolveIssueManagerStatusLabel(copy, task.status) })
1037
+ ] }),
1038
+ /* @__PURE__ */ jsx5("p", { className: "mt-2 line-clamp-2 text-sm leading-6 text-muted-foreground", children: summarizeIssueManagerContent(
1039
+ task.content,
1040
+ copy.t("messages.taskContentEmpty")
1041
+ ) })
1042
+ ] }),
1043
+ /* @__PURE__ */ jsx5("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatIssueManagerTimestamp(
1044
+ task.createdAtUnix ?? task.updatedAtUnix
1045
+ ) || "" })
1046
+ ]
1047
+ },
1048
+ task.taskId
1049
+ )) })
1050
+ ] });
1051
+ }
1052
+
1053
+ // src/ui/internal/IssueManagerDescriptionSection.tsx
1054
+ import { useEffect as useEffect3, useRef, useState as useState3 } from "react";
1055
+ import { RichTextReadonlyContent } from "@nextop-os/ui-rich-text/editor";
1056
+ import { cn as cn3 } from "@nextop-os/ui-system";
1057
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1058
+ function IssueManagerDescriptionSection({
1059
+ content,
1060
+ emptyLabel,
1061
+ label,
1062
+ minHeightClass = "min-h-[14rem]",
1063
+ onOpen,
1064
+ variant = "card"
1065
+ }) {
1066
+ const contentRef = useRef(null);
1067
+ const [isOverflowing, setIsOverflowing] = useState3(false);
1068
+ const normalizedContent = normalizeIssueManagerContent(content).trim();
1069
+ useEffect3(() => {
1070
+ if (variant === "plain") {
1071
+ setIsOverflowing(false);
1072
+ return;
1073
+ }
1074
+ if (!normalizedContent) {
1075
+ setIsOverflowing(false);
1076
+ return;
1077
+ }
1078
+ const contentElement = contentRef.current;
1079
+ if (!contentElement) {
1080
+ return;
1081
+ }
1082
+ const measure = () => {
1083
+ setIsOverflowing(
1084
+ contentElement.scrollHeight > contentElement.clientHeight + 1
1085
+ );
1086
+ };
1087
+ measure();
1088
+ if (typeof ResizeObserver === "undefined") {
1089
+ return;
1090
+ }
1091
+ const observer = new ResizeObserver(() => {
1092
+ measure();
1093
+ });
1094
+ observer.observe(contentElement);
1095
+ return () => {
1096
+ observer.disconnect();
1097
+ };
1098
+ }, [normalizedContent, variant]);
1099
+ if (variant === "plain") {
1100
+ return /* @__PURE__ */ jsxs6("section", { className: "grid gap-2", children: [
1101
+ /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
1102
+ normalizedContent ? /* @__PURE__ */ jsx6("div", { className: "max-w-3xl text-sm leading-5 text-text-secondary", children: /* @__PURE__ */ jsx6(
1103
+ IssueManagerDescriptionContent,
1104
+ {
1105
+ content: normalizedContent,
1106
+ onOpen
1107
+ }
1108
+ ) }) : /* @__PURE__ */ jsx6("p", { className: "text-sm leading-5 text-text-secondary", children: emptyLabel })
1109
+ ] });
1110
+ }
1111
+ return /* @__PURE__ */ jsxs6("section", { className: "grid gap-2", children: [
1112
+ /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
1113
+ /* @__PURE__ */ jsxs6(
1114
+ "div",
1115
+ {
1116
+ className: cn3(
1117
+ "relative min-w-0 rounded-lg border border-border-1 bg-transparent px-4 py-3",
1118
+ minHeightClass
1119
+ ),
1120
+ children: [
1121
+ /* @__PURE__ */ jsx6(
1122
+ "div",
1123
+ {
1124
+ className: cn3(
1125
+ "max-h-[18rem] overflow-y-auto pr-2 text-sm leading-5 text-text-secondary",
1126
+ isOverflowing && "pb-8"
1127
+ ),
1128
+ ref: contentRef,
1129
+ children: normalizedContent ? /* @__PURE__ */ jsx6(
1130
+ IssueManagerDescriptionContent,
1131
+ {
1132
+ content: normalizedContent,
1133
+ onOpen
1134
+ }
1135
+ ) : /* @__PURE__ */ jsx6("p", { className: "text-text-secondary", children: emptyLabel })
1136
+ }
1137
+ ),
1138
+ isOverflowing ? /* @__PURE__ */ jsx6(
1139
+ "div",
1140
+ {
1141
+ className: "pointer-events-none absolute right-0 bottom-1 left-0 h-10",
1142
+ style: {
1143
+ background: "linear-gradient(to top, var(--background-panel), color-mix(in srgb, var(--background-panel) 80%, transparent), transparent)"
1144
+ }
1145
+ }
1146
+ ) : null
1147
+ ]
1148
+ }
1149
+ )
1150
+ ] });
1151
+ }
1152
+ function IssueManagerDescriptionContent({
1153
+ content,
1154
+ onOpen
1155
+ }) {
1156
+ return /* @__PURE__ */ jsx6(
1157
+ RichTextReadonlyContent,
1158
+ {
1159
+ value: content,
1160
+ onOpenWorkspaceReference: onOpen ? (reference) => onOpen({
1161
+ displayName: reference.label,
1162
+ kind: reference.kind,
1163
+ path: reference.path
1164
+ }) : void 0
1165
+ }
1166
+ );
1167
+ }
1168
+
1169
+ // src/ui/internal/IssueManagerRichTextTextarea.tsx
1170
+ import { useMemo as useMemo2 } from "react";
1171
+ import { RichTextAtEditor } from "@nextop-os/ui-rich-text/editor";
1172
+ import { Button as Button6, LinkIcon, cn as cn4 } from "@nextop-os/ui-system";
1173
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1174
+ function IssueManagerRichTextTextarea({
1175
+ controller,
1176
+ onChange,
1177
+ placeholder,
1178
+ surface,
1179
+ textareaClassName,
1180
+ value
1181
+ }) {
1182
+ const providers = useMemo2(
1183
+ () => controller.resolveRichTextAtProviders(surface),
1184
+ [controller, surface]
1185
+ );
1186
+ const showReferenceAction = controller.canReferenceWorkspaceFiles;
1187
+ return /* @__PURE__ */ jsx7(
1188
+ RichTextAtEditor,
1189
+ {
1190
+ maxResults: 8,
1191
+ minQueryLength: 1,
1192
+ providers,
1193
+ textOverrides: {
1194
+ loadingLabel: controller.copy.t("richTextAt.loading"),
1195
+ noMatchesLabel: controller.copy.t("richTextAt.noMatches"),
1196
+ removeReferenceActionLabel: controller.copy.t("actions.removeReference")
1197
+ },
1198
+ textareaClassName: cn4(textareaClassName, showReferenceAction && "pb-14"),
1199
+ placeholder,
1200
+ value,
1201
+ onChange,
1202
+ overlay: showReferenceAction ? /* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute inset-x-4 bottom-3 z-10 flex", children: /* @__PURE__ */ jsxs7(
1203
+ Button6,
1204
+ {
1205
+ className: "pointer-events-auto",
1206
+ size: "sm",
1207
+ type: "button",
1208
+ variant: "secondary",
1209
+ onClick: () => {
1210
+ void controller.insertReferences(surface);
1211
+ },
1212
+ children: [
1213
+ /* @__PURE__ */ jsx7(LinkIcon, { size: 14 }),
1214
+ controller.copy.t("actions.referenceWorkspaceFiles")
1215
+ ]
1216
+ }
1217
+ ) }) : null
1218
+ }
1219
+ );
1220
+ }
1221
+
1222
+ // src/ui/internal/IssueManagerPanels.tsx
1223
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
1224
+ function IssueManagerIssuePane({
1225
+ controller,
1226
+ selectedIssue,
1227
+ onDismissCreate
1228
+ }) {
1229
+ const copy = controller.copy;
1230
+ const isIssueTitleMissing = controller.issueDraft.title.trim().length === 0;
1231
+ const isCreatingIssue = controller.issueEditorMode === "create";
1232
+ const isEditingIssue = controller.issueEditorMode === "edit";
1233
+ const issueContent = selectedIssue?.content ?? "";
1234
+ const tasks = controller.issueDetail.value?.tasks ?? [];
1235
+ const selectedTaskId = controller.nodeState.selectedTaskId;
1236
+ const selectedTask = selectedTaskId ? (controller.taskDetail.value?.task?.taskId === selectedTaskId ? controller.taskDetail.value.task : tasks.find((task) => task.taskId === selectedTaskId)) ?? null : null;
1237
+ const latestRun = selectedTask ? controller.taskDetail.value?.latestRun ?? controller.taskDetail.value?.recentRuns[0] ?? null : null;
1238
+ const latestOutputs = selectedTask ? controller.taskDetail.value?.latestOutputs ?? [] : [];
1239
+ if (isCreatingIssue || isEditingIssue) {
1240
+ return /* @__PURE__ */ jsxs8("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
1241
+ /* @__PURE__ */ jsx8("div", { className: "flex min-h-0 flex-1 flex-col gap-[14px] overflow-y-auto px-7 py-8", children: /* @__PURE__ */ jsxs8("div", { className: "flex w-full min-w-0 flex-col gap-3", children: [
1242
+ /* @__PURE__ */ jsx8("div", { children: /* @__PURE__ */ jsx8("h2", { className: "m-0 text-[17px] font-semibold leading-[1.35] text-foreground", children: isCreatingIssue ? copy.t("actions.createIssue") : copy.t("actions.editIssue") }) }),
1243
+ /* @__PURE__ */ jsxs8("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
1244
+ /* @__PURE__ */ jsxs8("label", { className: "flex w-full min-w-0 flex-col gap-2 text-sm font-semibold text-foreground", children: [
1245
+ /* @__PURE__ */ jsx8("span", { className: "leading-5", children: copy.t("labels.title") }),
1246
+ /* @__PURE__ */ jsx8(
1247
+ Input2,
1248
+ {
1249
+ className: "h-10 min-h-10 rounded-lg border-border-1 bg-transparency-block px-3 text-sm font-semibold text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)]",
1250
+ placeholder: copy.t("composer.issueTitlePlaceholder"),
1251
+ value: controller.issueDraft.title,
1252
+ onChange: (event) => controller.setIssueTitle(event.target.value)
1253
+ }
1254
+ )
1255
+ ] }),
1256
+ /* @__PURE__ */ jsxs8("div", { className: "flex min-h-0 w-full min-w-0 flex-col gap-2 text-sm font-semibold text-foreground", children: [
1257
+ /* @__PURE__ */ jsx8("span", { className: "leading-5", children: copy.t("labels.content") }),
1258
+ /* @__PURE__ */ jsx8(
1259
+ IssueManagerRichTextTextarea,
1260
+ {
1261
+ controller,
1262
+ surface: "issue",
1263
+ textareaClassName: "min-h-[180px] w-full resize-none rounded-lg border border-border-1 bg-transparency-block px-4 py-3 text-sm font-normal leading-5 text-[var(--text-primary)] outline-none placeholder:text-[var(--text-placeholder)]",
1264
+ placeholder: copy.t("composer.issueContentPlaceholder"),
1265
+ value: controller.issueDraft.content,
1266
+ onChange: controller.setIssueContent
1267
+ }
1268
+ )
1269
+ ] })
1270
+ ] })
1271
+ ] }) }),
1272
+ /* @__PURE__ */ jsx8("div", { className: "shrink-0 border-t border-border-1 px-7 py-4", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-end gap-4", children: [
1273
+ /* @__PURE__ */ jsx8(
1274
+ Button7,
1275
+ {
1276
+ size: "dialog",
1277
+ type: "button",
1278
+ variant: "secondary",
1279
+ onClick: onDismissCreate,
1280
+ children: copy.t("actions.cancel")
1281
+ }
1282
+ ),
1283
+ /* @__PURE__ */ jsx8(
1284
+ Button7,
1285
+ {
1286
+ disabled: isIssueTitleMissing,
1287
+ size: "dialog",
1288
+ type: "button",
1289
+ onClick: () => void controller.saveIssue(),
1290
+ children: copy.t("actions.saveIssue")
1291
+ }
1292
+ )
1293
+ ] }) })
1294
+ ] });
1295
+ }
1296
+ if (!selectedIssue) {
1297
+ return /* @__PURE__ */ jsx8("div", { className: "h-full min-h-0" });
1298
+ }
1299
+ return /* @__PURE__ */ jsx8("div", { className: "flex min-h-0 flex-col", children: /* @__PURE__ */ jsx8("div", { className: "min-h-0 flex-1 overflow-y-auto px-8 py-7", children: controller.issueDetail.isLoading && controller.issueDetail.value === null ? /* @__PURE__ */ jsx8(IssueManagerPaneLoadingState, {}) : /* @__PURE__ */ jsxs8("div", { className: "flex w-full min-w-0 flex-col gap-9", children: [
1300
+ /* @__PURE__ */ jsxs8("header", { className: "flex items-start justify-between gap-6", children: [
1301
+ /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1302
+ /* @__PURE__ */ jsx8("h2", { className: "line-clamp-2 text-base font-semibold leading-6 text-foreground", children: selectedIssue.title }),
1303
+ /* @__PURE__ */ jsxs8("div", { className: "mt-3 flex flex-wrap items-center gap-x-5 gap-y-2 text-sm text-muted-foreground", children: [
1304
+ /* @__PURE__ */ jsx8(Badge3, { className: "rounded-full border-transparent bg-muted px-2 py-1 text-[11px] text-muted-foreground", children: resolveIssueManagerStatusLabel(copy, selectedIssue.status) }),
1305
+ /* @__PURE__ */ jsxs8("span", { children: [
1306
+ copy.t("labels.creator"),
1307
+ " ",
1308
+ resolveIssueManagerCreatorLabel(selectedIssue)
1309
+ ] }),
1310
+ /* @__PURE__ */ jsxs8("span", { children: [
1311
+ copy.t("labels.createdAt"),
1312
+ " ",
1313
+ formatIssueManagerTimestamp(selectedIssue.createdAtUnix) || "-"
1314
+ ] })
1315
+ ] })
1316
+ ] }),
1317
+ /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-center gap-5 pt-1", children: [
1318
+ /* @__PURE__ */ jsx8(
1319
+ Button7,
1320
+ {
1321
+ className: "h-auto px-0 text-sm font-semibold text-muted-foreground hover:text-foreground",
1322
+ size: "sm",
1323
+ type: "button",
1324
+ variant: "ghost",
1325
+ onClick: () => controller.setIssueEditorMode("edit"),
1326
+ children: copy.t("actions.edit")
1327
+ }
1328
+ ),
1329
+ /* @__PURE__ */ jsx8(
1330
+ Button7,
1331
+ {
1332
+ className: "h-auto px-0 text-sm font-semibold text-destructive hover:text-destructive",
1333
+ size: "sm",
1334
+ type: "button",
1335
+ variant: "ghost",
1336
+ onClick: () => {
1337
+ void controller.deleteIssue();
1338
+ },
1339
+ children: copy.t("actions.delete")
1340
+ }
1341
+ )
1342
+ ] })
1343
+ ] }),
1344
+ /* @__PURE__ */ jsx8(
1345
+ IssueManagerDescriptionSection,
1346
+ {
1347
+ content: issueContent,
1348
+ emptyLabel: copy.t("messages.issueContentEmpty"),
1349
+ label: copy.t("labels.description"),
1350
+ onOpen: controller.openReference,
1351
+ variant: "plain"
1352
+ }
1353
+ ),
1354
+ /* @__PURE__ */ jsx8(
1355
+ IssueManagerDetailTextSection,
1356
+ {
1357
+ body: latestRun ? latestRun.summary?.trim() || resolveIssueManagerStatusLabel(copy, latestRun.status) : copy.t("messages.noExecutionStatus"),
1358
+ label: copy.t("labels.latestRunStatus"),
1359
+ meta: latestRun ? formatIssueManagerTimestamp(
1360
+ latestRun.updatedAtUnix ?? latestRun.createdAtUnix
1361
+ ) || void 0 : void 0,
1362
+ tone: latestRun?.status === "failed" ? "destructive" : "muted"
1363
+ }
1364
+ ),
1365
+ /* @__PURE__ */ jsx8(
1366
+ IssueManagerOutputSection,
1367
+ {
1368
+ copy,
1369
+ outputs: latestOutputs,
1370
+ onOpen: controller.openReference
1371
+ }
1372
+ ),
1373
+ /* @__PURE__ */ jsx8(
1374
+ IssueManagerSubtaskSection,
1375
+ {
1376
+ copy,
1377
+ onCreate: controller.createTaskDraft,
1378
+ onSelectTask: controller.selectTask,
1379
+ selectedTaskId: selectedTask?.taskId ?? null,
1380
+ tasks
1381
+ }
1382
+ )
1383
+ ] }) }) });
1384
+ }
1385
+
1386
+ // src/ui/internal/IssueManagerBottomBar.tsx
1387
+ import { Button as Button8, cn as cn5 } from "@nextop-os/ui-system";
1388
+
1389
+ // src/ui/internal/IssueManagerRunSections.tsx
1390
+ import { useState as useState4 } from "react";
1391
+ import {
1392
+ Badge as Badge4,
1393
+ Select,
1394
+ SelectContent,
1395
+ SelectItem,
1396
+ SelectTrigger,
1397
+ SparkIcon
1398
+ } from "@nextop-os/ui-system";
1399
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1400
+ function IssueManagerRunActionTrigger({
1401
+ controller,
1402
+ disabled = false,
1403
+ iconSize = 16,
1404
+ triggerClassName
1405
+ }) {
1406
+ const [resetToken, setResetToken] = useState4(0);
1407
+ return /* @__PURE__ */ jsxs9(
1408
+ Select,
1409
+ {
1410
+ disabled: controller.isRunningTask || disabled,
1411
+ onValueChange: (provider) => {
1412
+ setResetToken((current) => current + 1);
1413
+ void controller.runTask(provider);
1414
+ },
1415
+ children: [
1416
+ /* @__PURE__ */ jsx9(
1417
+ SelectTrigger,
1418
+ {
1419
+ "aria-label": controller.copy.t("actions.askAgentToRun"),
1420
+ className: triggerClassName,
1421
+ children: /* @__PURE__ */ jsxs9("span", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1422
+ /* @__PURE__ */ jsx9(SparkIcon, { size: iconSize }),
1423
+ /* @__PURE__ */ jsx9("span", { className: "truncate", children: controller.copy.t("actions.askAgentToRun") })
1424
+ ] })
1425
+ }
1426
+ ),
1427
+ /* @__PURE__ */ jsx9(SelectContent, { style: { zIndex: "var(--z-panel-popover)" }, children: controller.providerOptions.map((provider) => /* @__PURE__ */ jsx9(SelectItem, { value: provider, children: provider }, provider)) })
1428
+ ]
1429
+ },
1430
+ `${controller.nodeState.selectedAgentProvider}:${resetToken}`
1431
+ );
1432
+ }
1433
+ function IssueManagerRunPanels({
1434
+ copy,
1435
+ onOpen,
1436
+ outputs,
1437
+ recentRuns
1438
+ }) {
1439
+ return /* @__PURE__ */ jsxs9("div", { className: "grid gap-4", children: [
1440
+ /* @__PURE__ */ jsxs9("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
1441
+ /* @__PURE__ */ jsx9("h4", { className: "mb-3 text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.recentRuns") }),
1442
+ recentRuns.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "text-sm leading-5 text-text-secondary", children: copy.t("messages.noRecentRuns") }) : /* @__PURE__ */ jsx9("div", { className: "grid gap-2.5", children: recentRuns.map((run) => /* @__PURE__ */ jsxs9(
1443
+ "div",
1444
+ {
1445
+ className: "rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3",
1446
+ children: [
1447
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-3", children: [
1448
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
1449
+ /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: run.summary || run.runId }),
1450
+ /* @__PURE__ */ jsx9("p", { className: "mt-1 text-xs leading-[1.55] text-text-secondary", children: formatIssueManagerTimestamp(
1451
+ run.updatedAtUnix ?? run.createdAtUnix
1452
+ ) })
1453
+ ] }),
1454
+ /* @__PURE__ */ jsx9(Badge4, { className: "rounded-full border-transparent bg-transparency-block px-2.5 py-1 text-xs text-text-secondary", children: resolveIssueManagerStatusLabel(copy, run.status) })
1455
+ ] }),
1456
+ run.errorMessage ? /* @__PURE__ */ jsx9("p", { className: "mt-2 text-xs text-destructive", children: run.errorMessage }) : null
1457
+ ]
1458
+ },
1459
+ run.runId
1460
+ )) })
1461
+ ] }),
1462
+ /* @__PURE__ */ jsxs9("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
1463
+ /* @__PURE__ */ jsx9("h4", { className: "mb-3 text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.outputs") }),
1464
+ outputs.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "text-sm leading-5 text-text-secondary", children: copy.t("messages.noOutputs") }) : /* @__PURE__ */ jsx9("div", { className: "grid gap-2.5", children: outputs.map((output) => /* @__PURE__ */ jsxs9(
1465
+ "button",
1466
+ {
1467
+ className: "rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3 text-left transition-colors hover:bg-transparency-hover",
1468
+ type: "button",
1469
+ onClick: () => {
1470
+ void onOpen({
1471
+ displayName: output.displayName,
1472
+ kind: "file",
1473
+ path: output.path
1474
+ });
1475
+ },
1476
+ children: [
1477
+ /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: output.displayName }),
1478
+ /* @__PURE__ */ jsx9("p", { className: "mt-1 truncate text-xs leading-[1.55] text-text-secondary", children: output.path })
1479
+ ]
1480
+ },
1481
+ output.outputId
1482
+ )) })
1483
+ ] })
1484
+ ] });
1485
+ }
1486
+
1487
+ // src/ui/internal/IssueManagerBottomBar.tsx
1488
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1489
+ function IssueManagerBottomBar({
1490
+ controller,
1491
+ isNarrowLayout,
1492
+ selectedIssue,
1493
+ selectedTask,
1494
+ visible
1495
+ }) {
1496
+ const copy = controller.copy;
1497
+ if (!visible || !selectedIssue) {
1498
+ return null;
1499
+ }
1500
+ return /* @__PURE__ */ jsx10("div", { className: "border-t border-[var(--border-1)] bg-transparent px-6 py-4 backdrop-blur", children: /* @__PURE__ */ jsxs10(
1501
+ "div",
1502
+ {
1503
+ className: cn5(
1504
+ "flex gap-3",
1505
+ isNarrowLayout ? "flex-col items-stretch" : "items-center justify-end"
1506
+ ),
1507
+ children: [
1508
+ /* @__PURE__ */ jsx10(
1509
+ IssueManagerRunActionTrigger,
1510
+ {
1511
+ controller,
1512
+ disabled: !selectedTask,
1513
+ triggerClassName: cn5(
1514
+ "rounded-xl border-[var(--border-1)] bg-[var(--transparency-block)] px-4 py-2",
1515
+ isNarrowLayout ? "w-full" : "min-w-[14rem]"
1516
+ )
1517
+ }
1518
+ ),
1519
+ controller.canInviteCollaborators ? /* @__PURE__ */ jsx10(
1520
+ Button8,
1521
+ {
1522
+ className: cn5("px-4", isNarrowLayout && "w-full"),
1523
+ disabled: !selectedIssue,
1524
+ size: "dialog",
1525
+ type: "button",
1526
+ onClick: () => {
1527
+ void controller.shareSelection();
1528
+ },
1529
+ children: copy.t("actions.inviteCollaborator")
1530
+ }
1531
+ ) : null
1532
+ ]
1533
+ }
1534
+ ) });
1535
+ }
1536
+
1537
+ // src/ui/internal/IssueManagerFloatingNotice.tsx
1538
+ import {
1539
+ FailedFilledIcon,
1540
+ Spinner,
1541
+ toastVariants,
1542
+ cn as cn6
1543
+ } from "@nextop-os/ui-system";
1544
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1545
+ function IssueManagerFloatingNotice({
1546
+ notice
1547
+ }) {
1548
+ const variant = notice.tone === "destructive" ? "destructive" : "default";
1549
+ return /* @__PURE__ */ jsx11("div", { className: "pointer-events-none absolute top-4 left-1/2 z-30 flex w-full max-w-full -translate-x-1/2 justify-center px-4", children: /* @__PURE__ */ jsx11(
1550
+ "div",
1551
+ {
1552
+ "aria-busy": notice.isLoading,
1553
+ "aria-live": variant === "destructive" ? "assertive" : "polite",
1554
+ className: cn6(
1555
+ toastVariants({ variant }),
1556
+ "w-fit max-w-[min(72vw,40rem)] px-4 py-3 shadow-lg"
1557
+ ),
1558
+ role: variant === "destructive" ? "alert" : "status",
1559
+ children: /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 max-w-full items-center gap-[6px] whitespace-nowrap text-sm font-normal leading-normal", children: [
1560
+ notice.isLoading ? /* @__PURE__ */ jsx11(
1561
+ Spinner,
1562
+ {
1563
+ className: "shrink-0 text-current",
1564
+ size: 16,
1565
+ strokeWidth: 3,
1566
+ trackColor: "color-mix(in srgb, currentColor 28%, transparent)"
1567
+ }
1568
+ ) : notice.tone === "destructive" ? /* @__PURE__ */ jsx11(FailedFilledIcon, { className: "size-4 shrink-0 text-current" }) : null,
1569
+ /* @__PURE__ */ jsx11("span", { className: "min-w-0 max-w-full truncate whitespace-nowrap", children: notice.title })
1570
+ ] })
1571
+ }
1572
+ ) });
1573
+ }
1574
+
1575
+ // src/ui/internal/IssueManagerSidebar.tsx
1576
+ import { cn as cn8 } from "@nextop-os/ui-system";
1577
+
1578
+ // src/ui/internal/IssueManagerSidebarSections.tsx
1579
+ import {
1580
+ Badge as Badge5,
1581
+ Button as Button9,
1582
+ CloseIcon as CloseIcon2,
1583
+ FileCreateIcon as FileCreateIcon3,
1584
+ Input as Input3,
1585
+ ScrollArea as ScrollArea3,
1586
+ UnderlineTabs,
1587
+ cn as cn7
1588
+ } from "@nextop-os/ui-system";
1589
+
1590
+ // src/ui/internal/IssueManagerShellState.ts
1591
+ var issueManagerStatusFilters = [
1592
+ "all",
1593
+ "not_started",
1594
+ "running",
1595
+ "pending_acceptance",
1596
+ "completed",
1597
+ "failed",
1598
+ "canceled"
1599
+ ];
1600
+ function resolveIssueManagerSidebarViewState(input) {
1601
+ if (input.issues.isLoading && input.issues.value.length === 0) {
1602
+ return {
1603
+ kind: "loading"
1604
+ };
1605
+ }
1606
+ if (input.issues.error) {
1607
+ return {
1608
+ kind: "error",
1609
+ retryLabel: input.copy.t("actions.refresh"),
1610
+ title: input.copy.t("messages.issueRefreshFailed")
1611
+ };
1612
+ }
1613
+ if (input.issues.value.length === 0) {
1614
+ return {
1615
+ body: input.copy.t("messages.noIssuesForFilterBody"),
1616
+ kind: "empty",
1617
+ title: input.copy.t("messages.noIssuesForFilterTitle")
1618
+ };
1619
+ }
1620
+ return {
1621
+ issues: input.issues.value,
1622
+ kind: "list"
1623
+ };
1624
+ }
1625
+ function buildIssueManagerStatusCounts(issues) {
1626
+ const counts = {
1627
+ all: issues.length,
1628
+ canceled: 0,
1629
+ completed: 0,
1630
+ failed: 0,
1631
+ not_started: 0,
1632
+ pending_acceptance: 0,
1633
+ running: 0
1634
+ };
1635
+ for (const issue of issues) {
1636
+ if (issue.status in counts) {
1637
+ counts[issue.status] += 1;
1638
+ }
1639
+ }
1640
+ return counts;
1641
+ }
1642
+ function resolveIssueManagerShellContentViewState(input) {
1643
+ const isIssueEditing = input.issueEditorMode !== "read";
1644
+ const isTaskCreating = !isIssueEditing && input.taskEditorMode === "create";
1645
+ const isTaskDrawerOpen = !isIssueEditing && !isTaskCreating && (input.taskEditorMode === "edit" || input.selectedTaskPresent);
1646
+ return {
1647
+ isIssueEditing,
1648
+ isTaskCreating,
1649
+ isTaskDrawerOpen,
1650
+ showBottomBar: input.selectedIssue !== null && input.issueEditorMode === "read" && input.taskEditorMode === "read"
1651
+ };
1652
+ }
1653
+
1654
+ // src/ui/internal/IssueManagerSidebarSections.tsx
1655
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1656
+ function IssueManagerSidebarHeader({
1657
+ copy,
1658
+ issueSearchQuery,
1659
+ onCreateIssue,
1660
+ onIssueSearchQueryChange
1661
+ }) {
1662
+ return /* @__PURE__ */ jsx12("div", { className: "px-4 py-4", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2.5", children: [
1663
+ /* @__PURE__ */ jsx12(
1664
+ IssueManagerSearchField,
1665
+ {
1666
+ clearLabel: copy.t("actions.clearSearch"),
1667
+ placeholder: copy.t("labels.searchIssues"),
1668
+ value: issueSearchQuery,
1669
+ onChange: onIssueSearchQueryChange
1670
+ }
1671
+ ),
1672
+ /* @__PURE__ */ jsxs12(
1673
+ Button9,
1674
+ {
1675
+ className: "gap-2 px-3",
1676
+ size: "dialog",
1677
+ type: "button",
1678
+ variant: "secondary",
1679
+ onClick: onCreateIssue,
1680
+ children: [
1681
+ /* @__PURE__ */ jsx12(FileCreateIcon3, { size: 16 }),
1682
+ copy.t("actions.createIssue")
1683
+ ]
1684
+ }
1685
+ )
1686
+ ] }) });
1687
+ }
1688
+ function IssueManagerSidebarStatusTabs({
1689
+ copy,
1690
+ issueStatusFilter,
1691
+ statusCounts,
1692
+ onIssueStatusFilterChange
1693
+ }) {
1694
+ return /* @__PURE__ */ jsx12(
1695
+ UnderlineTabs,
1696
+ {
1697
+ ariaLabel: copy.t("labels.status"),
1698
+ className: "px-4",
1699
+ scrollLeftLabel: copy.t("labels.scrollStatusTabsLeft"),
1700
+ scrollRightLabel: copy.t("labels.scrollStatusTabsRight"),
1701
+ tabs: issueManagerStatusFilters.map((status) => ({
1702
+ count: statusCounts[status] ?? 0,
1703
+ label: status === "all" ? copy.t("labels.allStatus") : resolveIssueManagerStatusLabel(copy, status),
1704
+ value: status
1705
+ })),
1706
+ value: issueStatusFilter,
1707
+ onValueChange: onIssueStatusFilterChange
1708
+ }
1709
+ );
1710
+ }
1711
+ function IssueManagerSidebarBody({
1712
+ copy,
1713
+ isNarrowLayout,
1714
+ selectedIssueId,
1715
+ sidebarViewState,
1716
+ onRetry,
1717
+ onSelectIssue
1718
+ }) {
1719
+ return /* @__PURE__ */ jsx12(
1720
+ ScrollArea3,
1721
+ {
1722
+ className: cn7("min-h-0", isNarrowLayout ? "flex-none" : "h-full flex-1"),
1723
+ children: /* @__PURE__ */ jsx12(
1724
+ "div",
1725
+ {
1726
+ className: cn7(
1727
+ "flex min-h-full flex-col gap-2.5 px-4 pt-1.5 pb-4",
1728
+ isNarrowLayout ? "min-h-0" : "h-full"
1729
+ ),
1730
+ children: sidebarViewState.kind === "loading" ? /* @__PURE__ */ jsx12(IssueManagerSidebarLoadingState, { isNarrowLayout }) : sidebarViewState.kind === "error" ? /* @__PURE__ */ jsx12(
1731
+ IssueManagerSidebarErrorState,
1732
+ {
1733
+ isNarrowLayout,
1734
+ retryLabel: sidebarViewState.retryLabel,
1735
+ title: sidebarViewState.title,
1736
+ onRetry
1737
+ }
1738
+ ) : sidebarViewState.kind === "empty" ? /* @__PURE__ */ jsx12(
1739
+ IssueManagerSidebarEmptyState,
1740
+ {
1741
+ body: sidebarViewState.body,
1742
+ isNarrowLayout,
1743
+ title: sidebarViewState.title
1744
+ }
1745
+ ) : /* @__PURE__ */ jsx12(
1746
+ IssueManagerSidebarIssueList,
1747
+ {
1748
+ copy,
1749
+ isNarrowLayout,
1750
+ issues: sidebarViewState.issues,
1751
+ selectedIssueId,
1752
+ onSelectIssue
1753
+ }
1754
+ )
1755
+ }
1756
+ )
1757
+ }
1758
+ );
1759
+ }
1760
+ function IssueManagerSidebarStandalonePane({
1761
+ body,
1762
+ isNarrowLayout,
1763
+ kind,
1764
+ retryLabel,
1765
+ title,
1766
+ onRetry
1767
+ }) {
1768
+ if (kind === "error" && retryLabel) {
1769
+ return /* @__PURE__ */ jsx12(
1770
+ IssueManagerSidebarErrorState,
1771
+ {
1772
+ isNarrowLayout,
1773
+ retryLabel,
1774
+ title,
1775
+ onRetry
1776
+ }
1777
+ );
1778
+ }
1779
+ return /* @__PURE__ */ jsx12(
1780
+ IssueManagerSidebarEmptyState,
1781
+ {
1782
+ body: body ?? "",
1783
+ isNarrowLayout,
1784
+ title
1785
+ }
1786
+ );
1787
+ }
1788
+ function IssueManagerSearchField({
1789
+ clearLabel,
1790
+ onChange,
1791
+ placeholder,
1792
+ value
1793
+ }) {
1794
+ return /* @__PURE__ */ jsxs12(
1795
+ "div",
1796
+ {
1797
+ className: "relative min-w-0 flex-1",
1798
+ "data-has-value": value ? "true" : "false",
1799
+ children: [
1800
+ /* @__PURE__ */ jsx12(
1801
+ Input3,
1802
+ {
1803
+ "aria-label": placeholder,
1804
+ className: cn7(
1805
+ "box-border h-8 min-h-8 rounded-md border-0 bg-[var(--transparency-block)] px-3 text-sm font-normal leading-normal text-[var(--text-primary)] shadow-none outline-none ring-0 transition-colors placeholder:text-[var(--text-placeholder)] hover:bg-[var(--transparency-hover)] focus:border-0 focus:bg-[var(--transparency-hover)] focus-visible:border-0 focus-visible:bg-[var(--transparency-hover)] focus-visible:ring-0 focus-visible:ring-offset-0 disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-disabled)] disabled:opacity-100",
1806
+ "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
1807
+ value ? "pr-9" : "pr-3"
1808
+ ),
1809
+ placeholder,
1810
+ type: "search",
1811
+ value,
1812
+ onChange: (event) => onChange(event.target.value)
1813
+ }
1814
+ ),
1815
+ value ? /* @__PURE__ */ jsx12(
1816
+ "button",
1817
+ {
1818
+ "aria-label": clearLabel,
1819
+ className: "absolute top-1/2 right-1 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md border-0 bg-transparent p-0 text-[var(--text-tertiary)] transition-colors hover:bg-[var(--transparency-hover)] hover:text-[var(--text-secondary)] focus-visible:bg-[var(--transparency-hover)] focus-visible:text-[var(--text-secondary)] focus-visible:outline-none",
1820
+ type: "button",
1821
+ onClick: () => onChange(""),
1822
+ onMouseDown: (event) => event.preventDefault(),
1823
+ children: /* @__PURE__ */ jsx12(CloseIcon2, { className: "size-3.5" })
1824
+ }
1825
+ ) : null
1826
+ ]
1827
+ }
1828
+ );
1829
+ }
1830
+ function IssueManagerSidebarIssueList({
1831
+ copy,
1832
+ isNarrowLayout,
1833
+ issues,
1834
+ selectedIssueId,
1835
+ onSelectIssue
1836
+ }) {
1837
+ return /* @__PURE__ */ jsx12(
1838
+ "div",
1839
+ {
1840
+ className: cn7(
1841
+ "flex gap-2.5",
1842
+ isNarrowLayout ? "flex-row flex-nowrap items-start overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" : "flex-col"
1843
+ ),
1844
+ children: issues.map((issue) => /* @__PURE__ */ jsx12(
1845
+ IssueManagerSidebarItem,
1846
+ {
1847
+ copy,
1848
+ isNarrowLayout,
1849
+ issue,
1850
+ selected: selectedIssueId === issue.issueId,
1851
+ onSelect: onSelectIssue
1852
+ },
1853
+ issue.issueId
1854
+ ))
1855
+ }
1856
+ );
1857
+ }
1858
+ function IssueManagerSidebarItem({
1859
+ copy,
1860
+ isNarrowLayout,
1861
+ issue,
1862
+ onSelect,
1863
+ selected
1864
+ }) {
1865
+ return /* @__PURE__ */ jsxs12(
1866
+ "button",
1867
+ {
1868
+ className: cn7(
1869
+ "rounded-lg border px-3.5 py-3.5 text-left transition-colors",
1870
+ isNarrowLayout ? "h-24 max-h-24 min-h-24 w-[clamp(220px,58vw,320px)] flex-[0_0_clamp(220px,58vw,320px)] overflow-hidden" : "w-full",
1871
+ selected ? "border-[var(--border-1)] bg-[var(--background-fronted)]" : "border-[var(--border-1)] bg-transparent hover:bg-[var(--transparency-block)]"
1872
+ ),
1873
+ type: "button",
1874
+ onClick: () => onSelect(issue.issueId),
1875
+ children: [
1876
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
1877
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1 space-y-2", children: [
1878
+ /* @__PURE__ */ jsx12("p", { className: "text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: formatIssueManagerDate(issue.updatedAtUnix ?? issue.createdAtUnix) }),
1879
+ /* @__PURE__ */ jsx12("p", { className: "line-clamp-4 text-[14px] font-semibold leading-[1.35rem] text-[var(--text-primary)]", children: issue.title })
1880
+ ] }),
1881
+ /* @__PURE__ */ jsx12(Badge5, { className: "rounded-full border-transparent bg-[var(--transparency-block)] px-2 py-1 text-[11px] text-[var(--text-secondary)]", children: resolveIssueManagerStatusLabel(copy, issue.status) })
1882
+ ] }),
1883
+ /* @__PURE__ */ jsx12("div", { className: "mt-2 text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: copy.t("labels.taskCount", { count: issue.taskCount ?? 0 }) })
1884
+ ]
1885
+ }
1886
+ );
1887
+ }
1888
+ function IssueManagerSidebarLoadingState({
1889
+ isNarrowLayout
1890
+ }) {
1891
+ return /* @__PURE__ */ jsx12(
1892
+ "div",
1893
+ {
1894
+ "aria-hidden": "true",
1895
+ className: cn7(
1896
+ "gap-2.5",
1897
+ isNarrowLayout ? "flex flex-row flex-nowrap overflow-x-hidden" : "grid"
1898
+ ),
1899
+ children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxs12(
1900
+ "div",
1901
+ {
1902
+ className: cn7(
1903
+ "rounded-lg bg-transparent px-3.5 py-3.5",
1904
+ isNarrowLayout && "h-24 max-h-24 min-h-24 w-[clamp(220px,58vw,320px)] flex-[0_0_clamp(220px,58vw,320px)]"
1905
+ ),
1906
+ children: [
1907
+ /* @__PURE__ */ jsx12("div", { className: "h-3.5 w-20 rounded-full bg-[var(--transparency-block)]" }),
1908
+ /* @__PURE__ */ jsx12("div", { className: "mt-3 h-4 w-4/5 rounded-full bg-[var(--transparency-block)]" }),
1909
+ /* @__PURE__ */ jsx12("div", { className: "mt-4 h-3.5 w-24 rounded-full bg-[var(--transparency-block)]" })
1910
+ ]
1911
+ },
1912
+ index
1913
+ ))
1914
+ }
1915
+ );
1916
+ }
1917
+ function IssueManagerSidebarEmptyState({
1918
+ body,
1919
+ isNarrowLayout,
1920
+ title,
1921
+ tone = "default"
1922
+ }) {
1923
+ return /* @__PURE__ */ jsxs12(
1924
+ "div",
1925
+ {
1926
+ className: cn7(
1927
+ "relative flex flex-1 flex-col items-center justify-center self-stretch overflow-hidden p-0 text-center",
1928
+ isNarrowLayout ? "h-24 max-h-24 min-h-24 w-full flex-[0_0_100%]" : "min-h-full"
1929
+ ),
1930
+ children: [
1931
+ /* @__PURE__ */ jsx12(
1932
+ "p",
1933
+ {
1934
+ className: cn7(
1935
+ "text-sm font-semibold leading-5 text-[var(--text-primary)]",
1936
+ tone === "destructive" ? "text-[var(--state-danger)]" : "text-[var(--text-primary)]"
1937
+ ),
1938
+ children: title
1939
+ }
1940
+ ),
1941
+ /* @__PURE__ */ jsx12("p", { className: "mt-1.5 max-w-sm text-sm leading-5 text-[var(--text-secondary)]", children: body })
1942
+ ]
1943
+ }
1944
+ );
1945
+ }
1946
+ function IssueManagerSidebarErrorState({
1947
+ isNarrowLayout,
1948
+ retryLabel,
1949
+ title,
1950
+ onRetry
1951
+ }) {
1952
+ return /* @__PURE__ */ jsxs12(
1953
+ "div",
1954
+ {
1955
+ className: cn7(
1956
+ "relative flex flex-1 flex-col items-center justify-center self-stretch overflow-hidden px-4 py-6 text-center",
1957
+ isNarrowLayout ? "h-24 max-h-24 min-h-24 w-full flex-[0_0_100%]" : "min-h-full"
1958
+ ),
1959
+ children: [
1960
+ /* @__PURE__ */ jsx12("p", { className: "text-sm font-semibold leading-5 text-[var(--state-danger)]", children: title }),
1961
+ /* @__PURE__ */ jsx12(
1962
+ Button9,
1963
+ {
1964
+ className: "mt-3",
1965
+ size: "sm",
1966
+ type: "button",
1967
+ variant: "secondary",
1968
+ onClick: onRetry,
1969
+ children: retryLabel
1970
+ }
1971
+ )
1972
+ ]
1973
+ }
1974
+ );
1975
+ }
1976
+
1977
+ // src/ui/internal/IssueManagerSidebarState.ts
1978
+ function resolveIssueManagerSidebarPresentationState(input) {
1979
+ const { showStandaloneState, sidebarViewState } = input;
1980
+ if (!showStandaloneState) {
1981
+ return { kind: "none" };
1982
+ }
1983
+ if (sidebarViewState.kind === "error") {
1984
+ return {
1985
+ kind: "error",
1986
+ retryLabel: sidebarViewState.retryLabel,
1987
+ title: sidebarViewState.title
1988
+ };
1989
+ }
1990
+ if (sidebarViewState.kind === "empty") {
1991
+ return {
1992
+ body: sidebarViewState.body,
1993
+ kind: "empty",
1994
+ title: sidebarViewState.title
1995
+ };
1996
+ }
1997
+ return { kind: "none" };
1998
+ }
1999
+
2000
+ // src/ui/internal/IssueManagerSidebar.tsx
2001
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2002
+ function IssueManagerSidebar({
2003
+ controller,
2004
+ isCollapsed,
2005
+ isNarrowLayout,
2006
+ showStandaloneState,
2007
+ sidebarViewState,
2008
+ statusCounts
2009
+ }) {
2010
+ const copy = controller.copy;
2011
+ const presentation = resolveIssueManagerSidebarPresentationState({
2012
+ showStandaloneState,
2013
+ sidebarViewState
2014
+ });
2015
+ return /* @__PURE__ */ jsxs13(
2016
+ "aside",
2017
+ {
2018
+ "aria-hidden": isCollapsed ? "true" : void 0,
2019
+ className: cn8(
2020
+ "absolute top-0 left-0 z-10 isolate flex h-full w-[var(--issue-manager-sidebar-width)] min-h-0 flex-col overflow-hidden bg-transparent will-change-[transform,opacity] transition-[transform,opacity,border-color] duration-[220ms] ease-[cubic-bezier(0.22,1,0.36,1)] after:pointer-events-none after:absolute after:inset-0 after:z-[1] after:bg-[color-mix(in_srgb,var(--background-panel)_88%,transparent)] after:opacity-0 after:transition-opacity after:duration-[180ms] motion-reduce:transition-none",
2021
+ isNarrowLayout ? "border-b border-[var(--border-1)]" : "border-r border-[var(--border-1)]",
2022
+ isCollapsed && "pointer-events-none -translate-x-full border-r-transparent opacity-0 after:opacity-100 [&>*]:opacity-0 [&>*]:transition-opacity [&>*]:duration-[120ms] motion-reduce:transform-none"
2023
+ ),
2024
+ inert: isCollapsed ? true : void 0,
2025
+ children: [
2026
+ /* @__PURE__ */ jsx13(
2027
+ IssueManagerSidebarHeader,
2028
+ {
2029
+ copy,
2030
+ issueSearchQuery: controller.nodeState.issueSearchQuery,
2031
+ onCreateIssue: () => controller.setIssueEditorMode("create"),
2032
+ onIssueSearchQueryChange: controller.setIssueSearchQuery
2033
+ }
2034
+ ),
2035
+ /* @__PURE__ */ jsx13(
2036
+ IssueManagerSidebarStatusTabs,
2037
+ {
2038
+ copy,
2039
+ issueStatusFilter: controller.nodeState.issueStatusFilter,
2040
+ statusCounts,
2041
+ onIssueStatusFilterChange: controller.setIssueStatusFilter
2042
+ }
2043
+ ),
2044
+ /* @__PURE__ */ jsx13("div", { "aria-hidden": "true", className: "h-2.5 flex-none" }),
2045
+ /* @__PURE__ */ jsx13(
2046
+ "div",
2047
+ {
2048
+ className: cn8(
2049
+ "relative flex min-h-0 flex-col",
2050
+ isNarrowLayout ? "flex-none" : "flex-1"
2051
+ ),
2052
+ children: presentation.kind !== "none" ? /* @__PURE__ */ jsx13("div", { className: "flex h-full min-h-0 items-center justify-center px-4 pt-1.5 pb-4", children: /* @__PURE__ */ jsx13(
2053
+ IssueManagerSidebarStandalonePane,
2054
+ {
2055
+ body: presentation.kind === "empty" ? presentation.body : void 0,
2056
+ isNarrowLayout: false,
2057
+ kind: presentation.kind,
2058
+ retryLabel: presentation.kind === "error" ? presentation.retryLabel : void 0,
2059
+ title: presentation.title,
2060
+ onRetry: () => controller.refreshAll()
2061
+ }
2062
+ ) }) : /* @__PURE__ */ jsx13(
2063
+ IssueManagerSidebarBody,
2064
+ {
2065
+ copy,
2066
+ isNarrowLayout,
2067
+ selectedIssueId: controller.nodeState.selectedIssueId,
2068
+ sidebarViewState,
2069
+ onRetry: () => controller.refreshAll(),
2070
+ onSelectIssue: controller.selectIssue
2071
+ }
2072
+ )
2073
+ }
2074
+ )
2075
+ ]
2076
+ }
2077
+ );
2078
+ }
2079
+
2080
+ // src/ui/internal/IssueManagerTaskComposerPane.tsx
2081
+ import {
2082
+ Button as Button10,
2083
+ Input as Input4,
2084
+ Select as Select2,
2085
+ SelectContent as SelectContent2,
2086
+ SelectItem as SelectItem2,
2087
+ SelectTrigger as SelectTrigger2,
2088
+ SelectValue,
2089
+ UploadIcon
2090
+ } from "@nextop-os/ui-system";
2091
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
2092
+ var taskPriorityOptions = ["high", "medium", "low"];
2093
+ function IssueManagerTaskComposerPane({
2094
+ controller,
2095
+ onCancel,
2096
+ selectedIssue
2097
+ }) {
2098
+ const copy = controller.copy;
2099
+ const isTaskTitleMissing = controller.taskDraft.title.trim().length === 0;
2100
+ const showAttachmentActions = controller.canUploadWorkspaceFiles || controller.canReferenceWorkspaceFiles;
2101
+ return /* @__PURE__ */ jsxs14("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
2102
+ /* @__PURE__ */ jsx14("div", { className: "min-h-0 flex-1 overflow-y-auto px-7 py-8", children: /* @__PURE__ */ jsxs14("div", { className: "flex w-full max-w-[76rem] flex-col gap-8", children: [
2103
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-start justify-between gap-4", children: [
2104
+ /* @__PURE__ */ jsx14("h2", { className: "text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: copy.t("actions.addSubtask") }),
2105
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3", children: [
2106
+ /* @__PURE__ */ jsx14("span", { className: "text-sm text-text-secondary", children: copy.t("labels.priority") }),
2107
+ /* @__PURE__ */ jsxs14(
2108
+ Select2,
2109
+ {
2110
+ value: controller.taskDraft.priority,
2111
+ onValueChange: (value) => controller.setTaskPriority(value),
2112
+ children: [
2113
+ /* @__PURE__ */ jsx14(
2114
+ SelectTrigger2,
2115
+ {
2116
+ "aria-label": copy.t("labels.priority"),
2117
+ className: "min-w-28 rounded-lg border-border-1 bg-transparency-block text-sm",
2118
+ children: /* @__PURE__ */ jsx14(SelectValue, {})
2119
+ }
2120
+ ),
2121
+ /* @__PURE__ */ jsx14(SelectContent2, { style: { zIndex: "var(--z-panel-popover)" }, children: taskPriorityOptions.map((priority) => /* @__PURE__ */ jsx14(SelectItem2, { value: priority, children: resolveIssueManagerPriorityLabel(copy, priority) }, priority)) })
2122
+ ]
2123
+ }
2124
+ )
2125
+ ] })
2126
+ ] }),
2127
+ /* @__PURE__ */ jsxs14("label", { className: "grid gap-2", children: [
2128
+ /* @__PURE__ */ jsx14("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.title") }),
2129
+ /* @__PURE__ */ jsx14(
2130
+ Input4,
2131
+ {
2132
+ className: "h-10 rounded-lg border-0 bg-transparency-block px-3 text-sm font-semibold text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)]",
2133
+ placeholder: copy.t("composer.subtaskTitlePlaceholder"),
2134
+ value: controller.taskDraft.title,
2135
+ onChange: (event) => controller.setTaskTitle(event.target.value)
2136
+ }
2137
+ )
2138
+ ] }),
2139
+ /* @__PURE__ */ jsxs14("section", { className: "grid gap-2", children: [
2140
+ /* @__PURE__ */ jsx14("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.requirementDescription") }),
2141
+ /* @__PURE__ */ jsxs14("div", { className: "overflow-hidden rounded-lg border border-border-1 bg-transparency-block", children: [
2142
+ /* @__PURE__ */ jsx14(
2143
+ IssueManagerRichTextTextarea,
2144
+ {
2145
+ controller,
2146
+ surface: "task",
2147
+ textareaClassName: "min-h-[20rem] w-full resize-none border-0 bg-transparent px-4 py-3 text-sm leading-5 text-[var(--text-primary)] outline-none placeholder:text-[var(--text-placeholder)]",
2148
+ placeholder: copy.t("composer.subtaskContentPlaceholder"),
2149
+ value: controller.taskDraft.content,
2150
+ onChange: controller.setTaskContent
2151
+ }
2152
+ ),
2153
+ showAttachmentActions ? /* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center gap-3 border-t border-border-1 px-4 py-3", children: [
2154
+ controller.canUploadWorkspaceFiles ? /* @__PURE__ */ jsxs14(
2155
+ Button10,
2156
+ {
2157
+ className: "px-3",
2158
+ size: "dialog",
2159
+ type: "button",
2160
+ variant: "secondary",
2161
+ onClick: () => {
2162
+ void controller.uploadReferences("task", "files");
2163
+ },
2164
+ children: [
2165
+ /* @__PURE__ */ jsx14(UploadIcon, { size: 16 }),
2166
+ copy.t("actions.uploadFiles")
2167
+ ]
2168
+ }
2169
+ ) : null,
2170
+ controller.canUploadWorkspaceFiles ? /* @__PURE__ */ jsxs14(
2171
+ Button10,
2172
+ {
2173
+ className: "px-3",
2174
+ size: "dialog",
2175
+ type: "button",
2176
+ variant: "secondary",
2177
+ onClick: () => {
2178
+ void controller.uploadReferences("task", "folder");
2179
+ },
2180
+ children: [
2181
+ /* @__PURE__ */ jsx14(UploadIcon, { size: 16 }),
2182
+ copy.t("actions.uploadFolder")
2183
+ ]
2184
+ }
2185
+ ) : null
2186
+ ] }) : null
2187
+ ] })
2188
+ ] })
2189
+ ] }) }),
2190
+ /* @__PURE__ */ jsx14("div", { className: "shrink-0 border-t border-border-1 px-7 py-4", children: /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-end gap-3", children: [
2191
+ /* @__PURE__ */ jsx14(
2192
+ Button10,
2193
+ {
2194
+ size: "default",
2195
+ type: "button",
2196
+ variant: "secondary",
2197
+ onClick: onCancel,
2198
+ children: copy.t("actions.cancel")
2199
+ }
2200
+ ),
2201
+ /* @__PURE__ */ jsx14(
2202
+ Button10,
2203
+ {
2204
+ disabled: !selectedIssue || isTaskTitleMissing,
2205
+ size: "default",
2206
+ type: "button",
2207
+ onClick: () => void controller.saveTask(),
2208
+ children: copy.t("actions.saveSubtask")
2209
+ }
2210
+ )
2211
+ ] }) })
2212
+ ] });
2213
+ }
2214
+
2215
+ // src/ui/internal/IssueManagerTaskDrawer.tsx
2216
+ import { ScrollArea as ScrollArea4 } from "@nextop-os/ui-system";
2217
+
2218
+ // src/ui/internal/IssueManagerTaskDrawerSections.tsx
2219
+ import {
2220
+ Badge as Badge6,
2221
+ Button as Button12,
2222
+ CloseIcon as CloseIcon3,
2223
+ DropdownMenu,
2224
+ DropdownMenuContent,
2225
+ DropdownMenuItem,
2226
+ DropdownMenuTrigger,
2227
+ Input as Input5,
2228
+ Select as Select3,
2229
+ SelectContent as SelectContent3,
2230
+ SelectItem as SelectItem3,
2231
+ SelectTrigger as SelectTrigger3,
2232
+ SelectValue as SelectValue2,
2233
+ SparkIcon as SparkIcon2
2234
+ } from "@nextop-os/ui-system";
2235
+
2236
+ // src/ui/internal/IssueManagerContextSection.tsx
2237
+ import { Button as Button11, DirectoryIcon as DirectoryIcon3, FileIcon as FileIcon3 } from "@nextop-os/ui-system";
2238
+ import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
2239
+ function IssueManagerContextSection({
2240
+ copy,
2241
+ emptyLabel,
2242
+ onAdd,
2243
+ onOpen,
2244
+ onRemove,
2245
+ refs
2246
+ }) {
2247
+ return /* @__PURE__ */ jsxs15("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
2248
+ /* @__PURE__ */ jsxs15("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
2249
+ /* @__PURE__ */ jsx15("h4", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.contextReferences") }),
2250
+ /* @__PURE__ */ jsx15(
2251
+ Button11,
2252
+ {
2253
+ className: "px-3",
2254
+ size: "dialog",
2255
+ type: "button",
2256
+ variant: "secondary",
2257
+ onClick: onAdd,
2258
+ children: copy.t("actions.addReferences")
2259
+ }
2260
+ )
2261
+ ] }),
2262
+ refs.length === 0 ? /* @__PURE__ */ jsx15("p", { className: "text-sm leading-5 text-text-secondary", children: emptyLabel }) : /* @__PURE__ */ jsx15("div", { className: "grid gap-2.5", children: refs.map((ref) => /* @__PURE__ */ jsxs15(
2263
+ "div",
2264
+ {
2265
+ className: "flex items-center justify-between gap-3 rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3",
2266
+ children: [
2267
+ /* @__PURE__ */ jsxs15(
2268
+ "button",
2269
+ {
2270
+ className: "flex min-w-0 flex-1 items-center gap-3 text-left",
2271
+ type: "button",
2272
+ onClick: () => {
2273
+ void onOpen({
2274
+ displayName: ref.displayName,
2275
+ kind: ref.path.endsWith("/") ? "folder" : "file",
2276
+ path: ref.path
2277
+ });
2278
+ },
2279
+ children: [
2280
+ ref.path.endsWith("/") ? /* @__PURE__ */ jsx15(
2281
+ DirectoryIcon3,
2282
+ {
2283
+ className: "shrink-0 text-text-secondary",
2284
+ size: 16
2285
+ }
2286
+ ) : /* @__PURE__ */ jsx15(
2287
+ FileIcon3,
2288
+ {
2289
+ className: "shrink-0 text-text-secondary",
2290
+ size: 16
2291
+ }
2292
+ ),
2293
+ /* @__PURE__ */ jsxs15("span", { className: "min-w-0", children: [
2294
+ /* @__PURE__ */ jsx15("span", { className: "block truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: ref.displayName }),
2295
+ /* @__PURE__ */ jsx15("span", { className: "block truncate text-xs leading-[1.55] text-text-secondary", children: ref.path })
2296
+ ] })
2297
+ ]
2298
+ }
2299
+ ),
2300
+ /* @__PURE__ */ jsx15(
2301
+ Button11,
2302
+ {
2303
+ className: "h-7 rounded-md px-2 text-[13px] font-semibold text-text-secondary hover:text-[var(--text-primary)]",
2304
+ size: "sm",
2305
+ type: "button",
2306
+ variant: "ghost",
2307
+ onClick: () => {
2308
+ void onRemove(ref);
2309
+ },
2310
+ children: copy.t("actions.removeReference")
2311
+ }
2312
+ )
2313
+ ]
2314
+ },
2315
+ ref.contextRefId
2316
+ )) })
2317
+ ] });
2318
+ }
2319
+
2320
+ // src/ui/internal/IssueManagerTaskDrawerState.ts
2321
+ function resolveIssueManagerTaskDrawerViewState(input) {
2322
+ const { controller, selectedTask } = input;
2323
+ const isCreate = controller.taskEditorMode === "create";
2324
+ const isEdit = controller.taskEditorMode === "edit";
2325
+ const isRead = !isCreate && !isEdit;
2326
+ const showTaskMetadata = isRead && selectedTask !== null;
2327
+ const bodyKind = controller.taskDetail.isLoading && isCreate === false && controller.taskDetail.value === null ? "loading" : isCreate || isEdit ? "edit" : "read";
2328
+ return {
2329
+ bodyKind,
2330
+ isCreate,
2331
+ isEdit,
2332
+ isRead,
2333
+ isTaskTitleMissing: controller.taskDraft.title.trim().length === 0,
2334
+ showEditFooter: isCreate || isEdit,
2335
+ showReadFooter: showTaskMetadata,
2336
+ showTaskActions: showTaskMetadata,
2337
+ showTaskMetadata,
2338
+ title: isCreate || isEdit ? isCreate ? controller.copy.t("actions.createTask") : controller.copy.t("actions.editTask") : selectedTask?.title || controller.copy.t("labels.taskDetails")
2339
+ };
2340
+ }
2341
+ function resolveIssueManagerTaskRefs(input) {
2342
+ return input.controller.taskDetail.value?.contextRefs.filter(
2343
+ (ref) => ref.parentKind === "task"
2344
+ ) ?? [];
2345
+ }
2346
+ function canIssueManagerSaveTask(input) {
2347
+ return input.selectedIssue !== null && input.view.isTaskTitleMissing === false;
2348
+ }
2349
+
2350
+ // src/ui/internal/IssueManagerTaskDrawerSections.tsx
2351
+ import { Fragment, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
2352
+ var taskPriorityOptions2 = ["high", "medium", "low"];
2353
+ function IssueManagerTaskDrawerHeader({
2354
+ controller,
2355
+ selectedTask,
2356
+ view,
2357
+ onClose
2358
+ }) {
2359
+ const copy = controller.copy;
2360
+ return /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-4 border-b border-border-1 px-7 py-5", children: [
2361
+ /* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1", children: [
2362
+ view.showTaskMetadata && selectedTask ? /* @__PURE__ */ jsx16("div", { className: "grid min-w-0 gap-2", children: /* @__PURE__ */ jsx16("h3", { className: "line-clamp-3 text-sm font-semibold leading-[1.35] text-[var(--text-primary)]", children: view.title }) }) : /* @__PURE__ */ jsx16("h3", { className: "line-clamp-2 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: view.title }),
2363
+ view.showTaskMetadata && selectedTask ? /* @__PURE__ */ jsxs16("div", { className: "mt-2 flex min-w-0 items-center overflow-hidden text-sm leading-[1.55] text-text-secondary", children: [
2364
+ /* @__PURE__ */ jsx16(Badge6, { className: "shrink-0 rounded-full border-transparent bg-[var(--accent-bg)] px-2.5 py-1 text-xs text-[var(--text-primary)]", children: resolveIssueManagerStatusLabel(copy, selectedTask.status) }),
2365
+ /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
2366
+ /* @__PURE__ */ jsx16(Badge6, { className: "shrink-0 rounded-full border-transparent bg-transparency-block px-2.5 py-1 text-xs text-text-secondary", children: resolveIssueManagerPriorityLabel(copy, selectedTask.priority) }),
2367
+ /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
2368
+ /* @__PURE__ */ jsxs16("span", { children: [
2369
+ copy.t("labels.updatedAt"),
2370
+ " ",
2371
+ formatIssueManagerTimestamp(
2372
+ selectedTask.updatedAtUnix ?? selectedTask.createdAtUnix
2373
+ ) || "-"
2374
+ ] }),
2375
+ /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
2376
+ /* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: resolveTaskCreatorLabel(selectedTask) })
2377
+ ] }) : null
2378
+ ] }),
2379
+ /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
2380
+ view.showTaskActions && selectedTask ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
2381
+ /* @__PURE__ */ jsx16(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx16(
2382
+ Button12,
2383
+ {
2384
+ "aria-label": copy.t("actions.moreActions"),
2385
+ size: "icon-sm",
2386
+ type: "button",
2387
+ variant: "ghost",
2388
+ children: /* @__PURE__ */ jsx16(
2389
+ "span",
2390
+ {
2391
+ "aria-hidden": "true",
2392
+ className: "text-base leading-none tracking-[0.18em] text-text-secondary",
2393
+ children: "..."
2394
+ }
2395
+ )
2396
+ }
2397
+ ) }),
2398
+ /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", sideOffset: 8, children: [
2399
+ /* @__PURE__ */ jsx16(
2400
+ DropdownMenuItem,
2401
+ {
2402
+ onClick: () => controller.setTaskEditorMode("edit"),
2403
+ children: copy.t("actions.editTask")
2404
+ }
2405
+ ),
2406
+ /* @__PURE__ */ jsx16(
2407
+ DropdownMenuItem,
2408
+ {
2409
+ variant: "destructive",
2410
+ onClick: () => {
2411
+ void controller.deleteTask();
2412
+ },
2413
+ children: copy.t("actions.deleteTask")
2414
+ }
2415
+ )
2416
+ ] })
2417
+ ] }) : null,
2418
+ /* @__PURE__ */ jsx16(
2419
+ Button12,
2420
+ {
2421
+ "aria-label": copy.t("actions.cancel"),
2422
+ size: "icon-sm",
2423
+ type: "button",
2424
+ variant: "ghost",
2425
+ onClick: onClose,
2426
+ children: /* @__PURE__ */ jsx16(CloseIcon3, { size: 16 })
2427
+ }
2428
+ )
2429
+ ] })
2430
+ ] });
2431
+ }
2432
+ function IssueManagerTaskDrawerLoadingBody() {
2433
+ return /* @__PURE__ */ jsx16(IssueManagerTaskDrawerLoadingState, {});
2434
+ }
2435
+ function IssueManagerTaskDrawerBody({
2436
+ controller,
2437
+ taskContent,
2438
+ taskRefs,
2439
+ view
2440
+ }) {
2441
+ if (view.bodyKind === "loading") {
2442
+ return /* @__PURE__ */ jsx16(IssueManagerTaskDrawerLoadingBody, {});
2443
+ }
2444
+ if (view.bodyKind === "edit") {
2445
+ return /* @__PURE__ */ jsx16(
2446
+ IssueManagerTaskDrawerEditBody,
2447
+ {
2448
+ controller,
2449
+ isCreate: view.isCreate,
2450
+ taskRefs
2451
+ }
2452
+ );
2453
+ }
2454
+ return /* @__PURE__ */ jsx16(
2455
+ IssueManagerTaskDrawerReadBody,
2456
+ {
2457
+ controller,
2458
+ taskContent,
2459
+ taskRefs
2460
+ }
2461
+ );
2462
+ }
2463
+ function IssueManagerTaskDrawerEditBody({
2464
+ controller,
2465
+ isCreate,
2466
+ taskRefs
2467
+ }) {
2468
+ const copy = controller.copy;
2469
+ return /* @__PURE__ */ jsxs16(Fragment, { children: [
2470
+ /* @__PURE__ */ jsxs16("div", { className: "grid gap-5", children: [
2471
+ /* @__PURE__ */ jsxs16("label", { className: "grid gap-2", children: [
2472
+ /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.title") }),
2473
+ /* @__PURE__ */ jsx16(
2474
+ Input5,
2475
+ {
2476
+ className: "h-10 rounded-lg border-border-1 bg-transparency-block text-sm font-semibold text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)]",
2477
+ placeholder: copy.t("composer.taskTitlePlaceholder"),
2478
+ value: controller.taskDraft.title,
2479
+ onChange: (event) => controller.setTaskTitle(event.target.value)
2480
+ }
2481
+ )
2482
+ ] }),
2483
+ /* @__PURE__ */ jsx16("div", { className: "flex flex-wrap items-center gap-3", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
2484
+ /* @__PURE__ */ jsx16("span", { className: "text-sm font-medium text-text-secondary", children: copy.t("labels.priority") }),
2485
+ /* @__PURE__ */ jsxs16(
2486
+ Select3,
2487
+ {
2488
+ value: controller.taskDraft.priority,
2489
+ onValueChange: (value) => controller.setTaskPriority(value),
2490
+ children: [
2491
+ /* @__PURE__ */ jsx16(
2492
+ SelectTrigger3,
2493
+ {
2494
+ "aria-label": copy.t("labels.priority"),
2495
+ className: "min-w-28 rounded-lg border-border-1 bg-transparency-block text-sm",
2496
+ children: /* @__PURE__ */ jsx16(SelectValue2, {})
2497
+ }
2498
+ ),
2499
+ /* @__PURE__ */ jsx16(SelectContent3, { style: { zIndex: "var(--z-panel-popover)" }, children: taskPriorityOptions2.map((priority) => /* @__PURE__ */ jsx16(SelectItem3, { value: priority, children: resolveIssueManagerPriorityLabel(copy, priority) }, priority)) })
2500
+ ]
2501
+ }
2502
+ )
2503
+ ] }) }),
2504
+ /* @__PURE__ */ jsxs16("div", { className: "grid gap-2", children: [
2505
+ /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.content") }),
2506
+ /* @__PURE__ */ jsx16(
2507
+ IssueManagerRichTextTextarea,
2508
+ {
2509
+ controller,
2510
+ surface: "task",
2511
+ textareaClassName: "min-h-[12rem] w-full resize-none rounded-lg border border-border-1 bg-transparency-block px-4 py-3 text-sm leading-5 text-[var(--text-primary)] outline-none placeholder:text-[var(--text-placeholder)]",
2512
+ placeholder: copy.t("composer.taskContentPlaceholder"),
2513
+ value: controller.taskDraft.content,
2514
+ onChange: controller.setTaskContent
2515
+ }
2516
+ )
2517
+ ] })
2518
+ ] }),
2519
+ /* @__PURE__ */ jsx16(
2520
+ IssueManagerContextSection,
2521
+ {
2522
+ copy,
2523
+ emptyLabel: copy.t("messages.noTaskReferences"),
2524
+ refs: taskRefs,
2525
+ onAdd: () => {
2526
+ void controller.attachReferences("task");
2527
+ },
2528
+ onOpen: controller.openReference,
2529
+ onRemove: controller.removeContextRef
2530
+ }
2531
+ ),
2532
+ !isCreate ? /* @__PURE__ */ jsx16(
2533
+ IssueManagerRunPanels,
2534
+ {
2535
+ copy,
2536
+ outputs: controller.taskDetail.value?.latestOutputs ?? [],
2537
+ recentRuns: controller.taskDetail.value?.recentRuns ?? [],
2538
+ onOpen: controller.openReference
2539
+ }
2540
+ ) : null
2541
+ ] });
2542
+ }
2543
+ function IssueManagerTaskDrawerReadBody({
2544
+ controller,
2545
+ taskContent,
2546
+ taskRefs
2547
+ }) {
2548
+ const copy = controller.copy;
2549
+ return /* @__PURE__ */ jsxs16(Fragment, { children: [
2550
+ /* @__PURE__ */ jsx16(
2551
+ IssueManagerDescriptionSection,
2552
+ {
2553
+ content: taskContent,
2554
+ emptyLabel: copy.t("messages.taskContentEmpty"),
2555
+ label: copy.t("labels.content"),
2556
+ minHeightClass: "min-h-[8rem]",
2557
+ onOpen: controller.openReference
2558
+ }
2559
+ ),
2560
+ /* @__PURE__ */ jsx16(
2561
+ IssueManagerContextSection,
2562
+ {
2563
+ copy,
2564
+ emptyLabel: copy.t("messages.noTaskReferences"),
2565
+ refs: taskRefs,
2566
+ onAdd: () => {
2567
+ void controller.attachReferences("task");
2568
+ },
2569
+ onOpen: controller.openReference,
2570
+ onRemove: controller.removeContextRef
2571
+ }
2572
+ ),
2573
+ /* @__PURE__ */ jsx16(
2574
+ IssueManagerRunPanels,
2575
+ {
2576
+ copy,
2577
+ outputs: controller.taskDetail.value?.latestOutputs ?? [],
2578
+ recentRuns: controller.taskDetail.value?.recentRuns ?? [],
2579
+ onOpen: controller.openReference
2580
+ }
2581
+ )
2582
+ ] });
2583
+ }
2584
+ function IssueManagerTaskDrawerFooter({
2585
+ controller,
2586
+ selectedIssue,
2587
+ selectedTask,
2588
+ view
2589
+ }) {
2590
+ const copy = controller.copy;
2591
+ if (view.showReadFooter && selectedTask) {
2592
+ return /* @__PURE__ */ jsx16("div", { className: "border-t border-border-1 px-7 py-4", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-3", children: [
2593
+ /* @__PURE__ */ jsx16(
2594
+ IssueManagerRunActionTrigger,
2595
+ {
2596
+ controller,
2597
+ iconSize: 15,
2598
+ triggerClassName: "min-w-[11rem] rounded-lg border-border-1 bg-transparency-block px-3.5 py-2 text-sm"
2599
+ }
2600
+ ),
2601
+ controller.canInviteCollaborators ? /* @__PURE__ */ jsx16(
2602
+ Button12,
2603
+ {
2604
+ className: "shrink-0 px-4",
2605
+ size: "dialog",
2606
+ type: "button",
2607
+ onClick: () => {
2608
+ void controller.shareSelection();
2609
+ },
2610
+ children: copy.t("actions.inviteCollaborator")
2611
+ }
2612
+ ) : null
2613
+ ] }) });
2614
+ }
2615
+ if (view.showEditFooter) {
2616
+ return /* @__PURE__ */ jsx16("div", { className: "border-t border-border-1 px-7 py-4", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-3", children: [
2617
+ /* @__PURE__ */ jsx16("div", { className: "flex items-center gap-2", children: !view.isCreate && selectedTask ? /* @__PURE__ */ jsx16(
2618
+ Button12,
2619
+ {
2620
+ size: "default",
2621
+ type: "button",
2622
+ variant: "destructive",
2623
+ onClick: () => {
2624
+ void controller.deleteTask();
2625
+ },
2626
+ children: copy.t("actions.deleteTask")
2627
+ }
2628
+ ) : null }),
2629
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
2630
+ /* @__PURE__ */ jsx16(
2631
+ Button12,
2632
+ {
2633
+ size: "default",
2634
+ type: "button",
2635
+ variant: "secondary",
2636
+ onClick: () => controller.setTaskEditorMode("read"),
2637
+ children: copy.t("actions.cancel")
2638
+ }
2639
+ ),
2640
+ /* @__PURE__ */ jsxs16(
2641
+ Button12,
2642
+ {
2643
+ disabled: canIssueManagerSaveTask({
2644
+ selectedIssue,
2645
+ view
2646
+ }) === false,
2647
+ size: "default",
2648
+ type: "button",
2649
+ onClick: () => void controller.saveTask(),
2650
+ children: [
2651
+ /* @__PURE__ */ jsx16(SparkIcon2, { size: 16 }),
2652
+ copy.t("actions.saveTask")
2653
+ ]
2654
+ }
2655
+ )
2656
+ ] })
2657
+ ] }) });
2658
+ }
2659
+ return null;
2660
+ }
2661
+
2662
+ // src/ui/internal/IssueManagerTaskDrawer.tsx
2663
+ import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
2664
+ function IssueManagerTaskDrawer({
2665
+ controller,
2666
+ selectedIssue,
2667
+ selectedTask,
2668
+ onClose
2669
+ }) {
2670
+ const view = resolveIssueManagerTaskDrawerViewState({
2671
+ controller,
2672
+ selectedTask
2673
+ });
2674
+ const taskRefs = resolveIssueManagerTaskRefs({ controller });
2675
+ const taskContent = selectedTask?.content ?? "";
2676
+ return /* @__PURE__ */ jsx17(
2677
+ "div",
2678
+ {
2679
+ className: "absolute inset-0 z-20 flex justify-end bg-[var(--backdrop)] backdrop-blur-[1px]",
2680
+ onClick: onClose,
2681
+ children: /* @__PURE__ */ jsxs17(
2682
+ "aside",
2683
+ {
2684
+ className: "flex h-full w-[34rem] max-w-[92vw] flex-col border-l border-border-1 bg-background-panel text-[var(--text-primary)] shadow-[-20px_0_60px_var(--shadow-elevated)]",
2685
+ onClick: (event) => event.stopPropagation(),
2686
+ children: [
2687
+ /* @__PURE__ */ jsx17(
2688
+ IssueManagerTaskDrawerHeader,
2689
+ {
2690
+ controller,
2691
+ selectedTask,
2692
+ view,
2693
+ onClose
2694
+ }
2695
+ ),
2696
+ /* @__PURE__ */ jsx17(ScrollArea4, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx17("div", { className: "flex flex-col gap-5 px-7 py-6", children: /* @__PURE__ */ jsx17(
2697
+ IssueManagerTaskDrawerBody,
2698
+ {
2699
+ controller,
2700
+ taskContent,
2701
+ taskRefs,
2702
+ view
2703
+ }
2704
+ ) }) }),
2705
+ /* @__PURE__ */ jsx17(
2706
+ IssueManagerTaskDrawerFooter,
2707
+ {
2708
+ controller,
2709
+ selectedIssue,
2710
+ selectedTask,
2711
+ view
2712
+ }
2713
+ )
2714
+ ]
2715
+ }
2716
+ )
2717
+ }
2718
+ );
2719
+ }
2720
+
2721
+ // src/ui/internal/useIssueManagerShellView.ts
2722
+ import {
2723
+ useEffect as useEffect4,
2724
+ useEffectEvent as useEffectEvent3,
2725
+ useRef as useRef2,
2726
+ useState as useState5
2727
+ } from "react";
2728
+ function useIssueManagerShellView({
2729
+ controller,
2730
+ selectedIssue,
2731
+ selectedTask
2732
+ }) {
2733
+ const layoutRef = useRef2(null);
2734
+ const resizeRef = useRef2(null);
2735
+ const [sidebarWidth, setSidebarWidth] = useState5(
2736
+ issueManagerSidebarDefaultWidth
2737
+ );
2738
+ const [isNarrowLayout, setIsNarrowLayout] = useState5(false);
2739
+ const dismissNotification = useEffectEvent3(() => {
2740
+ controller.dismissNotification();
2741
+ });
2742
+ const floatingNotice = controller.floatingNotice;
2743
+ useEffect4(() => {
2744
+ const publishLayout = () => {
2745
+ const width = layoutRef.current?.getBoundingClientRect().width ?? 0;
2746
+ if (!width) {
2747
+ return;
2748
+ }
2749
+ setSidebarWidth(
2750
+ (current) => clampIssueManagerSidebarWidth(current, width)
2751
+ );
2752
+ setIsNarrowLayout(shouldAutoCollapseIssueManagerSidebar(width));
2753
+ };
2754
+ const layout = layoutRef.current;
2755
+ const observer = layout && typeof ResizeObserver !== "undefined" ? new ResizeObserver(publishLayout) : null;
2756
+ publishLayout();
2757
+ if (observer && layout) {
2758
+ observer.observe(layout);
2759
+ }
2760
+ window.addEventListener("resize", publishLayout);
2761
+ return () => {
2762
+ observer?.disconnect();
2763
+ window.removeEventListener("resize", publishLayout);
2764
+ };
2765
+ }, []);
2766
+ useEffect4(() => {
2767
+ if (!floatingNotice) {
2768
+ return void 0;
2769
+ }
2770
+ const timeout = window.setTimeout(() => {
2771
+ dismissNotification();
2772
+ }, floatingNotice.durationMs);
2773
+ return () => {
2774
+ window.clearTimeout(timeout);
2775
+ };
2776
+ }, [dismissNotification, floatingNotice]);
2777
+ const content = resolveIssueManagerShellContentViewState({
2778
+ issueEditorMode: controller.issueEditorMode,
2779
+ selectedIssue,
2780
+ selectedTaskPresent: selectedTask !== null,
2781
+ taskEditorMode: controller.taskEditorMode
2782
+ });
2783
+ const sidebarViewState = resolveIssueManagerSidebarViewState({
2784
+ copy: controller.copy,
2785
+ issues: controller.issues
2786
+ });
2787
+ const statusCounts = buildIssueManagerStatusCounts(controller.issues.value);
2788
+ const isSidebarAutoCollapsed = isNarrowLayout;
2789
+ const isSidebarCollapsed = controller.nodeState.taskListCollapsed === true || isSidebarAutoCollapsed;
2790
+ return {
2791
+ content,
2792
+ floatingNotice,
2793
+ isNarrowLayout,
2794
+ layoutRef,
2795
+ layoutStyle: {
2796
+ "--issue-manager-sidebar-width": `${sidebarWidth}px`
2797
+ },
2798
+ resizeHandle: {
2799
+ ariaValueMax: issueManagerSidebarMaxWidth,
2800
+ ariaValueMin: issueManagerSidebarMinWidth,
2801
+ ariaValueNow: sidebarWidth,
2802
+ onKeyDown: (event) => {
2803
+ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") {
2804
+ return;
2805
+ }
2806
+ const delta = event.key === "ArrowRight" ? 16 : -16;
2807
+ const layoutWidth = layoutRef.current?.getBoundingClientRect().width ?? 0;
2808
+ if (!layoutWidth) {
2809
+ return;
2810
+ }
2811
+ event.preventDefault();
2812
+ setSidebarWidth(
2813
+ (current) => clampIssueManagerSidebarWidth(current + delta, layoutWidth)
2814
+ );
2815
+ },
2816
+ onPointerCancel: (event) => {
2817
+ resizeRef.current = null;
2818
+ event.currentTarget.releasePointerCapture?.(event.pointerId);
2819
+ },
2820
+ onPointerDown: (event) => {
2821
+ if (event.button !== 0) {
2822
+ return;
2823
+ }
2824
+ const layoutWidth = layoutRef.current?.getBoundingClientRect().width ?? 0;
2825
+ if (!layoutWidth) {
2826
+ return;
2827
+ }
2828
+ const startWidth = clampIssueManagerSidebarWidth(
2829
+ sidebarWidth,
2830
+ layoutWidth
2831
+ );
2832
+ resizeRef.current = {
2833
+ maxWidth: clampIssueManagerSidebarWidth(
2834
+ issueManagerSidebarMaxWidth,
2835
+ layoutWidth
2836
+ ),
2837
+ pointerId: event.pointerId,
2838
+ startClientX: event.clientX,
2839
+ startWidth
2840
+ };
2841
+ setSidebarWidth(startWidth);
2842
+ event.currentTarget.setPointerCapture?.(event.pointerId);
2843
+ },
2844
+ onPointerMove: (event) => {
2845
+ const state = resizeRef.current;
2846
+ if (!state || state.pointerId !== event.pointerId) {
2847
+ return;
2848
+ }
2849
+ setSidebarWidth(
2850
+ Math.min(
2851
+ Math.max(
2852
+ state.startWidth + event.clientX - state.startClientX,
2853
+ issueManagerSidebarMinWidth
2854
+ ),
2855
+ state.maxWidth
2856
+ )
2857
+ );
2858
+ },
2859
+ onPointerUp: (event) => {
2860
+ resizeRef.current = null;
2861
+ event.currentTarget.releasePointerCapture?.(event.pointerId);
2862
+ }
2863
+ },
2864
+ sidebar: {
2865
+ isAutoCollapsed: isSidebarAutoCollapsed,
2866
+ isCollapsed: isSidebarCollapsed,
2867
+ showStandaloneState: !isNarrowLayout && (sidebarViewState.kind === "empty" || sidebarViewState.kind === "error"),
2868
+ statusCounts,
2869
+ viewState: sidebarViewState
2870
+ }
2871
+ };
2872
+ }
2873
+
2874
+ // src/ui/internal/IssueManagerShell.tsx
2875
+ import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
2876
+ function IssueManagerShell({
2877
+ controller,
2878
+ onCloseTaskDrawer,
2879
+ onDismissIssueCreate,
2880
+ selectedIssue,
2881
+ selectedTask
2882
+ }) {
2883
+ const shellView = useIssueManagerShellView({
2884
+ controller,
2885
+ selectedIssue,
2886
+ selectedTask
2887
+ });
2888
+ return /* @__PURE__ */ jsxs18(
2889
+ "div",
2890
+ {
2891
+ className: "relative min-h-0 flex-1 overflow-hidden bg-transparent",
2892
+ "data-issue-manager-sidebar-auto-collapsed": shellView.sidebar.isAutoCollapsed ? "true" : void 0,
2893
+ "data-issue-manager-sidebar-collapsed": shellView.sidebar.isCollapsed ? "true" : void 0,
2894
+ ref: shellView.layoutRef,
2895
+ style: shellView.layoutStyle,
2896
+ children: [
2897
+ shellView.floatingNotice ? /* @__PURE__ */ jsx18(IssueManagerFloatingNotice, { notice: shellView.floatingNotice }) : null,
2898
+ /* @__PURE__ */ jsx18(
2899
+ IssueManagerSidebar,
2900
+ {
2901
+ controller,
2902
+ isCollapsed: shellView.sidebar.isCollapsed,
2903
+ isNarrowLayout: shellView.isNarrowLayout,
2904
+ showStandaloneState: shellView.sidebar.showStandaloneState,
2905
+ sidebarViewState: shellView.sidebar.viewState,
2906
+ statusCounts: shellView.sidebar.statusCounts
2907
+ }
2908
+ ),
2909
+ shellView.sidebar.isCollapsed ? null : /* @__PURE__ */ jsx18(
2910
+ "div",
2911
+ {
2912
+ "aria-label": controller.copy.t("labels.resizeIssueList"),
2913
+ "aria-orientation": "vertical",
2914
+ "aria-valuemax": shellView.resizeHandle.ariaValueMax,
2915
+ "aria-valuemin": shellView.resizeHandle.ariaValueMin,
2916
+ "aria-valuenow": shellView.resizeHandle.ariaValueNow,
2917
+ className: "group absolute top-0 bottom-0 left-[calc(var(--issue-manager-sidebar-width)-6px)] z-20 w-3 cursor-col-resize touch-none",
2918
+ role: "separator",
2919
+ tabIndex: 0,
2920
+ onKeyDown: shellView.resizeHandle.onKeyDown,
2921
+ onPointerCancel: shellView.resizeHandle.onPointerCancel,
2922
+ onPointerDown: shellView.resizeHandle.onPointerDown,
2923
+ onPointerMove: shellView.resizeHandle.onPointerMove,
2924
+ onPointerUp: shellView.resizeHandle.onPointerUp,
2925
+ children: /* @__PURE__ */ jsx18("span", { className: "absolute top-0 bottom-0 left-1/2 w-px -translate-x-1/2 bg-transparent transition-[background-color,width] duration-150 group-hover:w-0.5 group-hover:bg-[color-mix(in_srgb,var(--border-focus)_40%,transparent)] group-focus-visible:w-0.5 group-focus-visible:bg-[color-mix(in_srgb,var(--border-focus)_40%,transparent)]" })
2926
+ }
2927
+ ),
2928
+ /* @__PURE__ */ jsxs18(
2929
+ "div",
2930
+ {
2931
+ className: cn9(
2932
+ "relative min-h-0 h-full overflow-hidden bg-transparent",
2933
+ !shellView.sidebar.isCollapsed && "pl-[var(--issue-manager-sidebar-width)]"
2934
+ ),
2935
+ children: [
2936
+ /* @__PURE__ */ jsxs18("div", { className: "flex h-full min-h-0 flex-col", children: [
2937
+ /* @__PURE__ */ jsx18("div", { className: "min-h-0 flex-1 overflow-hidden", children: shellView.content.isIssueEditing ? /* @__PURE__ */ jsx18(
2938
+ IssueManagerIssuePane,
2939
+ {
2940
+ controller,
2941
+ selectedIssue,
2942
+ onDismissCreate: onDismissIssueCreate
2943
+ }
2944
+ ) : shellView.content.isTaskCreating ? /* @__PURE__ */ jsx18(
2945
+ IssueManagerTaskComposerPane,
2946
+ {
2947
+ controller,
2948
+ selectedIssue,
2949
+ onCancel: () => controller.setTaskEditorMode("read")
2950
+ }
2951
+ ) : selectedIssue ? /* @__PURE__ */ jsx18(
2952
+ IssueManagerIssuePane,
2953
+ {
2954
+ controller,
2955
+ selectedIssue,
2956
+ onDismissCreate: onDismissIssueCreate
2957
+ }
2958
+ ) : /* @__PURE__ */ jsx18(IssueManagerShellEmptyState, { controller }) }),
2959
+ /* @__PURE__ */ jsx18(
2960
+ IssueManagerBottomBar,
2961
+ {
2962
+ controller,
2963
+ isNarrowLayout: shellView.isNarrowLayout,
2964
+ selectedIssue,
2965
+ selectedTask,
2966
+ visible: shellView.content.showBottomBar
2967
+ }
2968
+ )
2969
+ ] }),
2970
+ shellView.content.isTaskDrawerOpen ? /* @__PURE__ */ jsx18(
2971
+ IssueManagerTaskDrawer,
2972
+ {
2973
+ controller,
2974
+ selectedIssue,
2975
+ selectedTask,
2976
+ onClose: onCloseTaskDrawer
2977
+ }
2978
+ ) : null
2979
+ ]
2980
+ }
2981
+ )
2982
+ ]
2983
+ }
2984
+ );
2985
+ }
2986
+ function IssueManagerShellEmptyState({
2987
+ controller
2988
+ }) {
2989
+ return /* @__PURE__ */ jsx18("div", { className: "flex h-full min-h-[320px] items-center justify-center px-10 py-10", children: /* @__PURE__ */ jsxs18("div", { className: "grid max-w-[420px] justify-items-center gap-2 text-center", children: [
2990
+ /* @__PURE__ */ jsx18(IssueManagerEmptyIllustration, {}),
2991
+ /* @__PURE__ */ jsx18("h2", { className: "text-lg font-semibold leading-[1.35] text-[var(--text-primary)]", children: controller.copy.t("messages.noIssues") }),
2992
+ /* @__PURE__ */ jsx18("p", { className: "max-w-[420px] text-base leading-[1.3] text-[var(--text-secondary)]", children: controller.copy.t("emptyState") }),
2993
+ /* @__PURE__ */ jsx18(
2994
+ Button13,
2995
+ {
2996
+ className: "mt-2",
2997
+ type: "button",
2998
+ onClick: () => controller.setIssueEditorMode("create"),
2999
+ children: controller.copy.t("actions.createIssue")
3000
+ }
3001
+ )
3002
+ ] }) });
3003
+ }
3004
+
3005
+ // src/ui/internal/useIssueManagerController.ts
3006
+ import { useMemo as useMemo4 } from "react";
3007
+
3008
+ // src/ui/internal/IssueManagerControllerCapabilities.ts
3009
+ var issueManagerProviderOptions = ["codex"];
3010
+ function resolveIssueManagerControllerCapabilities(feature) {
3011
+ return {
3012
+ canInviteCollaborators: feature.ui.showInviteCollaborator === true && typeof feature.shareAdapter?.createIssueLink === "function",
3013
+ canReferenceWorkspaceFiles: hasFileAdapterMethod2(feature.fileAdapter, "requestReferences") || hasFileAdapterMethod2(feature.fileAdapter, "loadReferenceTree") || hasFileAdapterMethod2(feature.fileAdapter, "listDirectory") || hasFileAdapterMethod2(feature.fileAdapter, "searchReferences"),
3014
+ canUploadWorkspaceFiles: hasFileAdapterMethod2(
3015
+ feature.fileAdapter,
3016
+ "requestUpload"
3017
+ )
3018
+ };
3019
+ }
3020
+ function hasFileAdapterMethod2(fileAdapter, methodName) {
3021
+ return typeof Reflect.get(fileAdapter ?? {}, methodName) === "function";
3022
+ }
3023
+
3024
+ // src/services/internal/controllerCommands.ts
3025
+ function canIssueManagerRequestReferencesDirectly(fileAdapter) {
3026
+ return Boolean(
3027
+ fileAdapter?.requestReferences && !fileAdapter.loadReferenceTree && !fileAdapter.listDirectory && !fileAdapter.searchReferences
3028
+ );
3029
+ }
3030
+ async function executeIssueManagerRequestReferences(input) {
3031
+ return input.fileAdapter.requestReferences({
3032
+ workspaceId: input.workspaceId
3033
+ });
3034
+ }
3035
+ function canIssueManagerUploadReferences(fileAdapter) {
3036
+ return typeof fileAdapter?.requestUpload === "function";
3037
+ }
3038
+ function canIssueManagerOpenReferences(fileAdapter) {
3039
+ return typeof fileAdapter?.openReference === "function";
3040
+ }
3041
+ function canIssueManagerCreateShareLink(shareAdapter) {
3042
+ return typeof shareAdapter?.createIssueLink === "function";
3043
+ }
3044
+ async function executeIssueManagerUploadReferences(input) {
3045
+ const refs = await input.fileAdapter.requestUpload({
3046
+ mode: input.mode,
3047
+ targetDirectoryPath: "/",
3048
+ workspaceId: input.workspaceId
3049
+ });
3050
+ if (refs.length === 0) {
3051
+ return refs;
3052
+ }
3053
+ await input.fileAdapter.refreshTree?.({
3054
+ depth: 1,
3055
+ paths: refs.map((ref) => ref.path),
3056
+ workspaceId: input.workspaceId
3057
+ });
3058
+ return refs;
3059
+ }
3060
+ function resolveIssueManagerReferenceInsertionContent(input) {
3061
+ const preparedRefs = prepareIssueManagerReferences(input.refs);
3062
+ if (preparedRefs.length === 0) {
3063
+ return input.content;
3064
+ }
3065
+ return appendIssueManagerWorkspaceFileLinksToContent(
3066
+ input.content,
3067
+ preparedRefs.map(toIssueManagerWorkspaceFileLinkInput)
3068
+ );
3069
+ }
3070
+ async function executeIssueManagerAttachReferences(input) {
3071
+ const preparedRefs = prepareIssueManagerReferences(input.refs);
3072
+ if (!input.target || preparedRefs.length === 0 || !input.selectedIssueId) {
3073
+ return false;
3074
+ }
3075
+ await input.backend.addContextRefs(
3076
+ input.target.parentKind === "task" ? {
3077
+ issueId: input.selectedIssueId,
3078
+ parentKind: "task",
3079
+ refs: preparedRefs.map(toContextRefInput),
3080
+ taskId: input.target.taskId,
3081
+ workspaceId: input.workspaceId
3082
+ } : {
3083
+ issueId: input.selectedIssueId,
3084
+ parentKind: "issue",
3085
+ refs: preparedRefs.map(toContextRefInput),
3086
+ workspaceId: input.workspaceId
3087
+ }
3088
+ );
3089
+ return true;
3090
+ }
3091
+ async function executeIssueManagerOpenReference(input) {
3092
+ await input.fileAdapter.openReference(input.reference);
3093
+ }
3094
+ async function executeIssueManagerRemoveContextRef(input) {
3095
+ await input.backend.removeContextRef(
3096
+ input.ref.parentKind === "task" ? {
3097
+ contextRefId: input.ref.contextRefId,
3098
+ issueId: input.ref.issueId,
3099
+ parentKind: "task",
3100
+ taskId: input.ref.taskId,
3101
+ workspaceId: input.workspaceId
3102
+ } : {
3103
+ contextRefId: input.ref.contextRefId,
3104
+ issueId: input.ref.issueId,
3105
+ parentKind: "issue",
3106
+ workspaceId: input.workspaceId
3107
+ }
3108
+ );
3109
+ }
3110
+ async function executeIssueManagerRunTask(input) {
3111
+ const currentUser = await Promise.resolve(
3112
+ input.feature.identityAdapter.currentUser()
3113
+ );
3114
+ const createdRun = await input.feature.backend.createRun({
3115
+ agentProvider: input.provider,
3116
+ agentUserId: currentUser?.userId ?? void 0,
3117
+ issueId: input.issue.issueId,
3118
+ taskId: input.task.taskId,
3119
+ workspaceId: input.workspaceId
3120
+ });
3121
+ await input.onCreatedRun?.(createdRun);
3122
+ try {
3123
+ const result = await input.feature.agentRunner.runTask({
3124
+ issue: input.issue,
3125
+ provider: input.provider,
3126
+ run: createdRun,
3127
+ task: input.task,
3128
+ workspaceId: input.workspaceId
3129
+ });
3130
+ await input.feature.backend.completeRun({
3131
+ errorMessage: result.errorMessage,
3132
+ issueId: input.issue.issueId,
3133
+ outputs: result.outputs ?? [],
3134
+ runId: createdRun.runId,
3135
+ status: result.status,
3136
+ summary: result.summary,
3137
+ taskId: input.task.taskId,
3138
+ workspaceId: input.workspaceId
3139
+ });
3140
+ return {
3141
+ createdRun,
3142
+ status: result.status
3143
+ };
3144
+ } catch (error) {
3145
+ try {
3146
+ await input.feature.backend.completeRun({
3147
+ errorMessage: String(error instanceof Error ? error.message : error),
3148
+ issueId: input.issue.issueId,
3149
+ outputs: [],
3150
+ runId: createdRun.runId,
3151
+ status: "failed",
3152
+ summary: input.copy.t("run.failedSummaryFallback"),
3153
+ taskId: input.task.taskId,
3154
+ workspaceId: input.workspaceId
3155
+ });
3156
+ } catch {
3157
+ }
3158
+ throw error;
3159
+ }
3160
+ }
3161
+ async function executeIssueManagerSaveIssue(input) {
3162
+ const content = normalizeIssueManagerContent(input.issueDraft.content);
3163
+ const savedIssue = input.issueEditorMode === "create" ? await input.feature.backend.createIssue({
3164
+ content,
3165
+ title: input.issueDraft.title.trim(),
3166
+ workspaceId: input.workspaceId
3167
+ }) : await input.feature.backend.updateIssue({
3168
+ content,
3169
+ issueId: input.selectedIssueId ?? "",
3170
+ title: input.issueDraft.title.trim(),
3171
+ workspaceId: input.workspaceId
3172
+ });
3173
+ await syncIssueManagerContentReferences({
3174
+ backend: input.feature.backend,
3175
+ content,
3176
+ existingRefs: input.issueEditorMode === "create" ? [] : input.issueDetail?.contextRefs.filter(
3177
+ (ref) => ref.parentKind === "issue"
3178
+ ) ?? [],
3179
+ issueId: savedIssue.issueId,
3180
+ parentKind: "issue",
3181
+ workspaceId: input.workspaceId
3182
+ });
3183
+ return {
3184
+ content,
3185
+ savedIssue
3186
+ };
3187
+ }
3188
+ async function executeIssueManagerSaveTask(input) {
3189
+ const content = normalizeIssueManagerContent(input.taskDraft.content);
3190
+ const savedTask = input.taskEditorMode === "create" ? await input.feature.backend.createTask({
3191
+ content,
3192
+ issueId: input.selectedIssueId,
3193
+ priority: input.taskDraft.priority,
3194
+ title: input.taskDraft.title.trim(),
3195
+ workspaceId: input.workspaceId
3196
+ }) : await input.feature.backend.updateTask({
3197
+ content,
3198
+ issueId: input.selectedIssueId,
3199
+ priority: input.taskDraft.priority,
3200
+ taskId: input.selectedTaskId ?? "",
3201
+ title: input.taskDraft.title.trim(),
3202
+ workspaceId: input.workspaceId
3203
+ });
3204
+ await syncIssueManagerContentReferences({
3205
+ backend: input.feature.backend,
3206
+ content,
3207
+ existingRefs: input.taskEditorMode === "create" ? [] : input.taskDetail?.contextRefs.filter(
3208
+ (ref) => ref.parentKind === "task"
3209
+ ) ?? [],
3210
+ issueId: input.selectedIssueId,
3211
+ parentKind: "task",
3212
+ taskId: savedTask.taskId,
3213
+ workspaceId: input.workspaceId
3214
+ });
3215
+ return {
3216
+ content,
3217
+ savedTask
3218
+ };
3219
+ }
3220
+ async function executeIssueManagerShareSelection(input) {
3221
+ const link = await input.shareAdapter.createIssueLink({
3222
+ issueId: input.issueId,
3223
+ taskId: input.taskId ?? void 0,
3224
+ workspaceId: input.workspaceId
3225
+ });
3226
+ if (typeof navigator === "undefined" || !navigator.clipboard?.writeText) {
3227
+ throw new Error("issue_manager.clipboard_unavailable");
3228
+ }
3229
+ await navigator.clipboard.writeText(link);
3230
+ }
3231
+ function prepareIssueManagerReferences(refs) {
3232
+ return refs.filter((ref) => ref.path.trim().length > 0);
3233
+ }
3234
+ async function syncIssueManagerContentReferences(input) {
3235
+ const existingPaths = new Set(input.existingRefs.map((ref) => ref.path));
3236
+ const missingRefs = extractIssueManagerWorkspaceFileLinksFromContent(
3237
+ input.content
3238
+ ).filter((ref) => !existingPaths.has(ref.path)).map((ref) => ({
3239
+ displayName: ref.name,
3240
+ path: ref.path,
3241
+ refType: ref.kind
3242
+ }));
3243
+ if (missingRefs.length === 0) {
3244
+ return;
3245
+ }
3246
+ await input.backend.addContextRefs(
3247
+ input.parentKind === "task" ? {
3248
+ issueId: input.issueId,
3249
+ parentKind: "task",
3250
+ refs: missingRefs,
3251
+ taskId: input.taskId ?? "",
3252
+ workspaceId: input.workspaceId
3253
+ } : {
3254
+ issueId: input.issueId,
3255
+ parentKind: "issue",
3256
+ refs: missingRefs,
3257
+ workspaceId: input.workspaceId
3258
+ }
3259
+ );
3260
+ }
3261
+
3262
+ // src/services/internal/controllerOutcomes.ts
3263
+ function applyIssueManagerControllerOutcome(input) {
3264
+ if (input.outcome.notificationKey) {
3265
+ input.notify(input.translate(input.outcome.notificationKey));
3266
+ }
3267
+ if (input.outcome.issueDraft) {
3268
+ input.setIssueDraftInternal(input.outcome.issueDraft);
3269
+ }
3270
+ if (input.outcome.issueEditorMode) {
3271
+ input.setIssueEditorModeState(input.outcome.issueEditorMode);
3272
+ }
3273
+ if ("referenceTarget" in input.outcome) {
3274
+ input.setReferenceTarget(input.outcome.referenceTarget ?? null);
3275
+ }
3276
+ if (input.outcome.taskDraft) {
3277
+ input.setTaskDraftInternal(input.outcome.taskDraft);
3278
+ }
3279
+ if (input.outcome.taskEditorMode) {
3280
+ input.setTaskEditorModeState(input.outcome.taskEditorMode);
3281
+ }
3282
+ if (input.outcome.nodeState) {
3283
+ input.updateNodeState(input.outcome.nodeState);
3284
+ }
3285
+ if (input.outcome.refreshAll) {
3286
+ input.refreshAll();
3287
+ }
3288
+ if (input.outcome.refreshDetails) {
3289
+ input.refreshDetails();
3290
+ }
3291
+ }
3292
+ function createIssueManagerRunTaskSuccessOutcome(input) {
3293
+ return {
3294
+ notificationKey: input.status === "completed" ? void 0 : "messages.runFailed"
3295
+ };
3296
+ }
3297
+ function createIssueManagerSaveIssueSuccessOutcome(issueId) {
3298
+ return {
3299
+ issueEditorMode: "read",
3300
+ nodeState: (current) => applyIssueManagerIssueSaved(current, issueId),
3301
+ refreshAll: true
3302
+ };
3303
+ }
3304
+ function createIssueManagerSaveTaskSuccessOutcome(taskId) {
3305
+ return {
3306
+ nodeState: (current) => applyIssueManagerTaskSaved(current, taskId),
3307
+ refreshAll: true,
3308
+ taskEditorMode: "read"
3309
+ };
3310
+ }
3311
+ function createIssueManagerOpenReferencePickerOutcome(target) {
3312
+ return {
3313
+ referenceTarget: target
3314
+ };
3315
+ }
3316
+ function createIssueManagerAttachReferencesOutcome(attached) {
3317
+ return {
3318
+ referenceTarget: null,
3319
+ refreshDetails: attached
3320
+ };
3321
+ }
3322
+ function createIssueManagerInsertReferencesOutcome(input) {
3323
+ return input.target.parentKind === "issue" ? {
3324
+ issueDraft: (current) => ({
3325
+ ...current,
3326
+ content: resolveIssueManagerReferenceInsertionContent({
3327
+ content: current.content,
3328
+ refs: input.refs
3329
+ })
3330
+ }),
3331
+ referenceTarget: null
3332
+ } : {
3333
+ referenceTarget: null,
3334
+ taskDraft: (current) => ({
3335
+ ...current,
3336
+ content: resolveIssueManagerReferenceInsertionContent({
3337
+ content: current.content,
3338
+ refs: input.refs
3339
+ })
3340
+ })
3341
+ };
3342
+ }
3343
+
3344
+ // src/services/internal/controllerPlans.ts
3345
+ function createIssueManagerRunTaskPlan(input) {
3346
+ if (!input.issueDetail || !input.taskDetail) {
3347
+ return { kind: "skip" };
3348
+ }
3349
+ const provider = input.providerOverride?.trim() || input.selectedAgentProvider.trim();
3350
+ if (!provider) {
3351
+ return { kind: "skip" };
3352
+ }
3353
+ return {
3354
+ kind: "ready",
3355
+ provider,
3356
+ shouldUpdateSelectedAgentProvider: provider !== input.selectedAgentProvider
3357
+ };
3358
+ }
3359
+ function createIssueManagerSaveIssuePlan(input) {
3360
+ const title = input.issueDraft.title.trim();
3361
+ if (!title) {
3362
+ return {
3363
+ kind: "blocked",
3364
+ notificationKey: "messages.titleRequired"
3365
+ };
3366
+ }
3367
+ return { kind: "ready" };
3368
+ }
3369
+ function createIssueManagerSaveTaskPlan(input) {
3370
+ if (!input.selectedIssueId) {
3371
+ return { kind: "skip" };
3372
+ }
3373
+ const title = input.taskDraft.title.trim();
3374
+ if (!title) {
3375
+ return {
3376
+ kind: "blocked",
3377
+ notificationKey: "messages.titleRequired"
3378
+ };
3379
+ }
3380
+ return {
3381
+ kind: "ready",
3382
+ selectedIssueId: input.selectedIssueId
3383
+ };
3384
+ }
3385
+ function createIssueManagerAttachReferenceTarget(parentKind, selectedTaskId) {
3386
+ return parentKind === "task" ? {
3387
+ mode: "attach",
3388
+ parentKind: "task",
3389
+ taskId: selectedTaskId ?? ""
3390
+ } : {
3391
+ mode: "attach",
3392
+ parentKind: "issue"
3393
+ };
3394
+ }
3395
+ function createIssueManagerInsertReferenceTarget(parentKind, selectedTaskId) {
3396
+ return parentKind === "task" ? {
3397
+ mode: "insert",
3398
+ parentKind: "task",
3399
+ taskId: selectedTaskId ?? ""
3400
+ } : {
3401
+ mode: "insert",
3402
+ parentKind: "issue"
3403
+ };
3404
+ }
3405
+ function createIssueManagerAttachReferencesPlan(input) {
3406
+ if (!input.hasFileAdapter) {
3407
+ return { kind: "skip" };
3408
+ }
3409
+ if (input.parentKind === "task" && !input.selectedTaskId) {
3410
+ return { kind: "skip" };
3411
+ }
3412
+ const target = createIssueManagerAttachReferenceTarget(
3413
+ input.parentKind,
3414
+ input.selectedTaskId
3415
+ );
3416
+ return input.requestReferencesDirectly ? { kind: "request_directly", target } : { kind: "open_picker", target };
3417
+ }
3418
+ function createIssueManagerInsertReferencesPlan(input) {
3419
+ if (!input.hasFileAdapter) {
3420
+ return { kind: "skip" };
3421
+ }
3422
+ if (input.parentKind === "task" && !input.selectedTaskId && input.taskEditorMode !== "create") {
3423
+ return { kind: "skip" };
3424
+ }
3425
+ const target = createIssueManagerInsertReferenceTarget(
3426
+ input.parentKind,
3427
+ input.selectedTaskId
3428
+ );
3429
+ return input.requestReferencesDirectly ? { kind: "request_directly", target } : { kind: "open_picker", target };
3430
+ }
3431
+
3432
+ // src/services/internal/controllerActions.ts
3433
+ function createIssueManagerControllerActions(input) {
3434
+ const {
3435
+ copy,
3436
+ feature,
3437
+ issueDetail,
3438
+ issueDraft,
3439
+ issueEditorMode,
3440
+ nodeState,
3441
+ referenceTarget,
3442
+ refreshAll,
3443
+ refreshDetails,
3444
+ setNotification,
3445
+ setIsRunningTask,
3446
+ setIssueDraftInternal,
3447
+ setIssueEditorModeState,
3448
+ setReferenceTarget,
3449
+ setTaskDraftInternal,
3450
+ setTaskEditorModeState,
3451
+ taskDetail,
3452
+ taskDraft,
3453
+ taskEditorMode,
3454
+ updateNodeState,
3455
+ workspaceId
3456
+ } = input;
3457
+ const notifyTip = (message, tone = "destructive") => {
3458
+ setNotification({
3459
+ title: message,
3460
+ tone
3461
+ });
3462
+ };
3463
+ const notifyError = (error, fallbackKey) => {
3464
+ setNotification({
3465
+ title: resolveIssueManagerErrorMessage(error, copy, fallbackKey),
3466
+ tone: "destructive"
3467
+ });
3468
+ };
3469
+ const applyOutcome = (outcome) => {
3470
+ applyIssueManagerControllerOutcome({
3471
+ notify: notifyTip,
3472
+ outcome,
3473
+ refreshAll,
3474
+ refreshDetails,
3475
+ setIssueDraftInternal,
3476
+ setIssueEditorModeState,
3477
+ setReferenceTarget: (target) => setReferenceTarget(target),
3478
+ setTaskDraftInternal,
3479
+ setTaskEditorModeState,
3480
+ translate: (key) => copy.t(key),
3481
+ updateNodeState
3482
+ });
3483
+ };
3484
+ const submitReferences = async (refs, target = referenceTarget) => {
3485
+ if (!target) {
3486
+ applyOutcome({
3487
+ referenceTarget: null
3488
+ });
3489
+ return;
3490
+ }
3491
+ if (target.mode === "insert") {
3492
+ applyOutcome(
3493
+ createIssueManagerInsertReferencesOutcome({
3494
+ refs,
3495
+ target
3496
+ })
3497
+ );
3498
+ return;
3499
+ }
3500
+ const attached = await executeIssueManagerAttachReferences({
3501
+ backend: feature.backend,
3502
+ refs,
3503
+ selectedIssueId: nodeState.selectedIssueId,
3504
+ target,
3505
+ workspaceId
3506
+ });
3507
+ applyOutcome(createIssueManagerAttachReferencesOutcome(attached));
3508
+ };
3509
+ return {
3510
+ async attachReferences(parentKind) {
3511
+ const fileAdapter = feature.fileAdapter;
3512
+ const attachPlan = createIssueManagerAttachReferencesPlan({
3513
+ hasFileAdapter: Boolean(fileAdapter),
3514
+ parentKind,
3515
+ requestReferencesDirectly: canIssueManagerRequestReferencesDirectly(fileAdapter),
3516
+ selectedTaskId: nodeState.selectedTaskId
3517
+ });
3518
+ if (attachPlan.kind === "skip") {
3519
+ return;
3520
+ }
3521
+ if (attachPlan.kind === "request_directly") {
3522
+ if (!canIssueManagerRequestReferencesDirectly(fileAdapter)) {
3523
+ return;
3524
+ }
3525
+ const refs = await executeIssueManagerRequestReferences({
3526
+ fileAdapter,
3527
+ workspaceId
3528
+ });
3529
+ await submitReferences(refs, attachPlan.target);
3530
+ return;
3531
+ }
3532
+ applyOutcome(
3533
+ createIssueManagerOpenReferencePickerOutcome(attachPlan.target)
3534
+ );
3535
+ },
3536
+ createTaskDraft() {
3537
+ setTaskEditorModeState("create");
3538
+ setTaskDraftInternal({
3539
+ content: nodeState.taskDraftContent ?? "",
3540
+ priority: defaultTaskPriority,
3541
+ title: nodeState.taskDraftTitle ?? ""
3542
+ });
3543
+ updateNodeState((current) => ({
3544
+ ...current,
3545
+ selectedTaskId: null
3546
+ }));
3547
+ },
3548
+ async deleteIssue() {
3549
+ const selectedIssueId = nodeState.selectedIssueId;
3550
+ if (!selectedIssueId || !confirmIssueManagerMessage(copy.t("confirmations.deleteIssue"))) {
3551
+ return;
3552
+ }
3553
+ try {
3554
+ await feature.backend.deleteIssue({
3555
+ issueId: selectedIssueId,
3556
+ workspaceId
3557
+ });
3558
+ setIssueEditorModeState("read");
3559
+ setTaskEditorModeState("read");
3560
+ updateNodeState((current) => applyIssueManagerIssueDeleted(current));
3561
+ refreshAll();
3562
+ } catch (error) {
3563
+ notifyError(error, "messages.issueDeleteFailed");
3564
+ }
3565
+ },
3566
+ async deleteTask() {
3567
+ const selectedIssueId = nodeState.selectedIssueId;
3568
+ const selectedTaskId = nodeState.selectedTaskId;
3569
+ if (!selectedIssueId || !selectedTaskId || !confirmIssueManagerMessage(copy.t("confirmations.deleteTask"))) {
3570
+ return;
3571
+ }
3572
+ try {
3573
+ await feature.backend.deleteTask({
3574
+ issueId: selectedIssueId,
3575
+ taskId: selectedTaskId,
3576
+ workspaceId
3577
+ });
3578
+ setTaskEditorModeState("read");
3579
+ updateNodeState((current) => applyIssueManagerTaskDeleted(current));
3580
+ refreshAll();
3581
+ } catch (error) {
3582
+ notifyError(error, "messages.taskDeleteFailed");
3583
+ }
3584
+ },
3585
+ async insertReferences(parentKind) {
3586
+ const fileAdapter = feature.fileAdapter;
3587
+ const insertPlan = createIssueManagerInsertReferencesPlan({
3588
+ hasFileAdapter: Boolean(fileAdapter),
3589
+ parentKind,
3590
+ requestReferencesDirectly: canIssueManagerRequestReferencesDirectly(fileAdapter),
3591
+ selectedTaskId: nodeState.selectedTaskId,
3592
+ taskEditorMode
3593
+ });
3594
+ if (insertPlan.kind === "skip") {
3595
+ return;
3596
+ }
3597
+ if (insertPlan.kind === "request_directly") {
3598
+ if (!canIssueManagerRequestReferencesDirectly(fileAdapter)) {
3599
+ return;
3600
+ }
3601
+ const refs = await executeIssueManagerRequestReferences({
3602
+ fileAdapter,
3603
+ workspaceId
3604
+ });
3605
+ await submitReferences(refs, insertPlan.target);
3606
+ return;
3607
+ }
3608
+ applyOutcome(
3609
+ createIssueManagerOpenReferencePickerOutcome(insertPlan.target)
3610
+ );
3611
+ },
3612
+ async uploadReferences(parentKind, mode) {
3613
+ const fileAdapter = feature.fileAdapter;
3614
+ if (!canIssueManagerUploadReferences(fileAdapter)) {
3615
+ return;
3616
+ }
3617
+ const refs = await executeIssueManagerUploadReferences({
3618
+ fileAdapter,
3619
+ mode,
3620
+ workspaceId
3621
+ });
3622
+ if (refs.length === 0) {
3623
+ return;
3624
+ }
3625
+ await submitReferences(
3626
+ refs,
3627
+ createIssueManagerInsertReferenceTarget(
3628
+ parentKind,
3629
+ nodeState.selectedTaskId
3630
+ )
3631
+ );
3632
+ },
3633
+ async openReference(reference) {
3634
+ const fileAdapter = feature.fileAdapter;
3635
+ if (!canIssueManagerOpenReferences(fileAdapter)) {
3636
+ return;
3637
+ }
3638
+ await executeIssueManagerOpenReference({
3639
+ fileAdapter,
3640
+ reference
3641
+ });
3642
+ },
3643
+ async removeContextRef(ref) {
3644
+ try {
3645
+ await executeIssueManagerRemoveContextRef({
3646
+ backend: feature.backend,
3647
+ ref,
3648
+ workspaceId
3649
+ });
3650
+ refreshDetails();
3651
+ } catch (error) {
3652
+ notifyError(error, "messages.referenceRemoveFailed");
3653
+ }
3654
+ },
3655
+ async runTask(providerOverride) {
3656
+ const runPlan = createIssueManagerRunTaskPlan({
3657
+ issueDetail: issueDetail.value,
3658
+ providerOverride,
3659
+ selectedAgentProvider: nodeState.selectedAgentProvider,
3660
+ taskDetail: taskDetail.value
3661
+ });
3662
+ if (runPlan.kind !== "ready") {
3663
+ return;
3664
+ }
3665
+ const currentIssueDetail = issueDetail.value;
3666
+ const currentTaskDetail = taskDetail.value;
3667
+ if (!currentIssueDetail || !currentTaskDetail) {
3668
+ return;
3669
+ }
3670
+ if (runPlan.shouldUpdateSelectedAgentProvider) {
3671
+ updateNodeState(
3672
+ (current) => applyIssueManagerSelectedAgentProvider(current, runPlan.provider)
3673
+ );
3674
+ }
3675
+ setIsRunningTask(true);
3676
+ try {
3677
+ const result = await executeIssueManagerRunTask({
3678
+ copy,
3679
+ feature,
3680
+ issue: currentIssueDetail.issue,
3681
+ onCreatedRun: refreshDetails,
3682
+ provider: runPlan.provider,
3683
+ task: currentTaskDetail.task,
3684
+ workspaceId
3685
+ });
3686
+ const outcome = createIssueManagerRunTaskSuccessOutcome({
3687
+ status: result.status
3688
+ });
3689
+ applyOutcome(outcome);
3690
+ } catch (error) {
3691
+ notifyTip(
3692
+ resolveIssueManagerErrorMessage(error, copy, "messages.runFailed")
3693
+ );
3694
+ } finally {
3695
+ setIsRunningTask(false);
3696
+ refreshDetails();
3697
+ }
3698
+ },
3699
+ async saveIssue() {
3700
+ const savePlan = createIssueManagerSaveIssuePlan({
3701
+ issueDraft
3702
+ });
3703
+ if (savePlan.kind === "blocked") {
3704
+ notifyTip(copy.t(savePlan.notificationKey));
3705
+ return;
3706
+ }
3707
+ try {
3708
+ const { savedIssue } = await executeIssueManagerSaveIssue({
3709
+ feature,
3710
+ issueDetail: issueDetail.value,
3711
+ issueDraft,
3712
+ issueEditorMode,
3713
+ selectedIssueId: nodeState.selectedIssueId,
3714
+ workspaceId
3715
+ });
3716
+ const outcome = createIssueManagerSaveIssueSuccessOutcome(
3717
+ savedIssue.issueId
3718
+ );
3719
+ applyOutcome(outcome);
3720
+ } catch (error) {
3721
+ notifyError(error, "messages.issueSaveFailed");
3722
+ }
3723
+ },
3724
+ async saveTask() {
3725
+ const savePlan = createIssueManagerSaveTaskPlan({
3726
+ selectedIssueId: nodeState.selectedIssueId,
3727
+ taskDraft
3728
+ });
3729
+ if (savePlan.kind === "skip") {
3730
+ return;
3731
+ }
3732
+ if (savePlan.kind === "blocked") {
3733
+ notifyTip(copy.t(savePlan.notificationKey));
3734
+ return;
3735
+ }
3736
+ try {
3737
+ const { savedTask } = await executeIssueManagerSaveTask({
3738
+ feature,
3739
+ selectedIssueId: savePlan.selectedIssueId,
3740
+ selectedTaskId: nodeState.selectedTaskId,
3741
+ taskDetail: taskDetail.value,
3742
+ taskDraft,
3743
+ taskEditorMode,
3744
+ workspaceId
3745
+ });
3746
+ const outcome = createIssueManagerSaveTaskSuccessOutcome(
3747
+ savedTask.taskId
3748
+ );
3749
+ applyOutcome(outcome);
3750
+ } catch (error) {
3751
+ notifyError(error, "messages.taskSaveFailed");
3752
+ }
3753
+ },
3754
+ async shareSelection() {
3755
+ const selectedIssueId = nodeState.selectedIssueId;
3756
+ const shareAdapter = feature.shareAdapter;
3757
+ if (!canIssueManagerCreateShareLink(shareAdapter) || !selectedIssueId) {
3758
+ return;
3759
+ }
3760
+ try {
3761
+ await executeIssueManagerShareSelection({
3762
+ issueId: selectedIssueId,
3763
+ shareAdapter,
3764
+ taskId: nodeState.selectedTaskId,
3765
+ workspaceId
3766
+ });
3767
+ } catch (error) {
3768
+ notifyError(error, "messages.copyShareLinkFailed");
3769
+ }
3770
+ },
3771
+ async submitReferenceSelection(refs) {
3772
+ await submitReferences(refs);
3773
+ }
3774
+ };
3775
+ }
3776
+
3777
+ // src/ui/internal/createIssueManagerControllerActionsBridge.ts
3778
+ function createIssueManagerControllerActionsBridge(input) {
3779
+ const {
3780
+ controllerSession,
3781
+ copy,
3782
+ feature,
3783
+ issueDetail,
3784
+ issueDraft,
3785
+ issueEditorMode,
3786
+ nodeState,
3787
+ referenceTarget,
3788
+ taskDetail,
3789
+ taskDraft,
3790
+ taskEditorMode,
3791
+ workspaceId
3792
+ } = input;
3793
+ return createIssueManagerControllerActions({
3794
+ copy,
3795
+ feature,
3796
+ issueDetail,
3797
+ issueDraft,
3798
+ issueEditorMode,
3799
+ nodeState,
3800
+ referenceTarget,
3801
+ refreshAll: () => controllerSession.refreshAll(),
3802
+ refreshDetails: () => controllerSession.refreshDetails(),
3803
+ setNotification: (update) => controllerSession.setNotification(
3804
+ (current) => createIssueManagerControllerNotificationState(current, update)
3805
+ ),
3806
+ setIsRunningTask: (update) => controllerSession.setIsRunningTask(update),
3807
+ setIssueDraftInternal: (update) => controllerSession.setIssueDraftInternal(update),
3808
+ setIssueEditorModeState: (update) => controllerSession.setIssueEditorModeState(update),
3809
+ setReferenceTarget: (update) => controllerSession.setReferenceTarget(update),
3810
+ setTaskDraftInternal: (update) => controllerSession.setTaskDraftInternal(update),
3811
+ setTaskEditorModeState: (update) => controllerSession.setTaskEditorModeState(update),
3812
+ taskDetail,
3813
+ taskDraft,
3814
+ taskEditorMode,
3815
+ updateNodeState: (updater) => controllerSession.updateNodeState(updater),
3816
+ workspaceId
3817
+ });
3818
+ }
3819
+ function createIssueManagerControllerNotificationState(current, input) {
3820
+ return {
3821
+ id: (current?.id ?? 0) + 1,
3822
+ title: input.title,
3823
+ tone: input.tone ?? "default"
3824
+ };
3825
+ }
3826
+
3827
+ // src/ui/internal/createIssueManagerIssueBindings.ts
3828
+ function createIssueManagerIssueBindings(input) {
3829
+ const { controllerSession, issueEditorMode, nodeState } = input;
3830
+ return {
3831
+ setIssueContent(content) {
3832
+ controllerSession.setIssueDraftInternal((current) => ({
3833
+ ...current,
3834
+ content
3835
+ }));
3836
+ controllerSession.updateNodeState(
3837
+ (current) => persistIssueManagerIssueDraftContent(current, issueEditorMode, content)
3838
+ );
3839
+ },
3840
+ setIssueDraft(patch) {
3841
+ controllerSession.setIssueDraftInternal((current) => ({
3842
+ ...current,
3843
+ ...patch
3844
+ }));
3845
+ },
3846
+ setIssueEditorMode(mode) {
3847
+ controllerSession.setIssueEditorModeState(mode);
3848
+ if (mode === "create") {
3849
+ controllerSession.setIssueDraftInternal(
3850
+ createIssueManagerIssueDraftFromNodeState(nodeState)
3851
+ );
3852
+ }
3853
+ controllerSession.updateNodeState(
3854
+ (current) => applyIssueManagerIssueEditorModeToNodeState(current, mode)
3855
+ );
3856
+ },
3857
+ setIssueSearchQuery(query) {
3858
+ controllerSession.updateNodeState((current) => ({
3859
+ ...current,
3860
+ issueSearchQuery: query
3861
+ }));
3862
+ },
3863
+ setIssueStatusFilter(value) {
3864
+ controllerSession.updateNodeState((current) => ({
3865
+ ...current,
3866
+ issueStatusFilter: value
3867
+ }));
3868
+ },
3869
+ setIssueTitle(title) {
3870
+ controllerSession.setIssueDraftInternal((current) => ({
3871
+ ...current,
3872
+ title
3873
+ }));
3874
+ controllerSession.updateNodeState(
3875
+ (current) => persistIssueManagerIssueDraftTitle(current, issueEditorMode, title)
3876
+ );
3877
+ }
3878
+ };
3879
+ }
3880
+
3881
+ // src/ui/internal/createIssueManagerTaskBindings.ts
3882
+ function createIssueManagerTaskBindings(input) {
3883
+ const { controllerSession, nodeState, taskEditorMode } = input;
3884
+ return {
3885
+ selectTask(taskId) {
3886
+ controllerSession.updateNodeState(
3887
+ (current) => applyIssueManagerTaskSelection(current, taskId)
3888
+ );
3889
+ controllerSession.setTaskEditorModeState("read");
3890
+ },
3891
+ setTaskContent(content) {
3892
+ controllerSession.setTaskDraftInternal((current) => ({
3893
+ ...current,
3894
+ content
3895
+ }));
3896
+ controllerSession.updateNodeState(
3897
+ (current) => persistIssueManagerTaskDraftContent(current, taskEditorMode, content)
3898
+ );
3899
+ },
3900
+ setTaskDraft(patch) {
3901
+ controllerSession.setTaskDraftInternal((current) => ({
3902
+ ...current,
3903
+ ...patch
3904
+ }));
3905
+ },
3906
+ setTaskEditorMode(mode) {
3907
+ controllerSession.setTaskEditorModeState(mode);
3908
+ if (mode === "create") {
3909
+ controllerSession.setTaskDraftInternal(
3910
+ createIssueManagerTaskDraftFromNodeState(nodeState)
3911
+ );
3912
+ }
3913
+ controllerSession.updateNodeState(
3914
+ (current) => applyIssueManagerTaskEditorModeToNodeState(current, mode)
3915
+ );
3916
+ },
3917
+ setTaskListCollapsed(collapsed) {
3918
+ controllerSession.updateNodeState((current) => ({
3919
+ ...current,
3920
+ taskListCollapsed: collapsed
3921
+ }));
3922
+ },
3923
+ setTaskPriority(priority) {
3924
+ controllerSession.setTaskDraftInternal((current) => ({
3925
+ ...current,
3926
+ priority
3927
+ }));
3928
+ },
3929
+ setTaskTitle(title) {
3930
+ controllerSession.setTaskDraftInternal((current) => ({
3931
+ ...current,
3932
+ title
3933
+ }));
3934
+ controllerSession.updateNodeState(
3935
+ (current) => persistIssueManagerTaskDraftTitle(current, taskEditorMode, title)
3936
+ );
3937
+ }
3938
+ };
3939
+ }
3940
+
3941
+ // src/ui/internal/createIssueManagerControllerBindings.ts
3942
+ function createIssueManagerControllerBindings(input) {
3943
+ const {
3944
+ controllerSession,
3945
+ issueEditorMode,
3946
+ nodeState,
3947
+ onResolveRichTextAtProviders,
3948
+ taskEditorMode,
3949
+ workspaceId
3950
+ } = input;
3951
+ const issueBindings = createIssueManagerIssueBindings({
3952
+ controllerSession,
3953
+ issueEditorMode,
3954
+ nodeState
3955
+ });
3956
+ const taskBindings = createIssueManagerTaskBindings({
3957
+ controllerSession,
3958
+ nodeState,
3959
+ taskEditorMode
3960
+ });
3961
+ return {
3962
+ ...issueBindings,
3963
+ ...taskBindings,
3964
+ dismissNotification() {
3965
+ controllerSession.setNotification(null);
3966
+ },
3967
+ refreshAll() {
3968
+ controllerSession.refreshAll();
3969
+ },
3970
+ resolveRichTextAtProviders(surface) {
3971
+ return onResolveRichTextAtProviders?.({
3972
+ surface,
3973
+ workspaceId
3974
+ }) ?? [];
3975
+ },
3976
+ selectIssue(issueId) {
3977
+ controllerSession.updateNodeState(
3978
+ (current) => applyIssueManagerIssueSelection(current, issueId)
3979
+ );
3980
+ controllerSession.setIssueEditorModeState("read");
3981
+ controllerSession.setTaskEditorModeState("read");
3982
+ },
3983
+ setReferenceTarget(target) {
3984
+ controllerSession.setReferenceTarget(target);
3985
+ },
3986
+ setSelectedAgentProvider(provider) {
3987
+ controllerSession.updateNodeState((current) => ({
3988
+ ...current,
3989
+ selectedAgentProvider: provider
3990
+ }));
3991
+ }
3992
+ };
3993
+ }
3994
+
3995
+ // src/ui/internal/useIssueManagerControllerRuntime.ts
3996
+ import { useDeferredValue, useEffect as useEffect5, useMemo as useMemo3 } from "react";
3997
+ import { useSnapshot } from "valtio";
3998
+
3999
+ // src/ui/internal/IssueManagerNoticeState.ts
4000
+ var issueManagerNoticeDurationMs = 3200;
4001
+ function resolveIssueManagerFloatingNoticeViewState(input) {
4002
+ if (!input.notification) {
4003
+ return null;
4004
+ }
4005
+ return {
4006
+ durationMs: issueManagerNoticeDurationMs,
4007
+ id: input.notification.id,
4008
+ isLoading: false,
4009
+ title: input.notification.title,
4010
+ tone: input.notification.tone
4011
+ };
4012
+ }
4013
+
4014
+ // src/ui/internal/useIssueManagerControllerRuntime.ts
4015
+ function useIssueManagerControllerRuntime(input) {
4016
+ const { feature, onStateChange, service, state, workspaceId } = input;
4017
+ const controllerService = useMemo3(
4018
+ () => service ?? createIssueManagerControllerService(),
4019
+ [service]
4020
+ );
4021
+ const controllerSession = useMemo3(
4022
+ () => controllerService.createSession({
4023
+ feature,
4024
+ state,
4025
+ workspaceId
4026
+ }),
4027
+ [controllerService, feature, workspaceId]
4028
+ );
4029
+ const snapshot = useSnapshot(
4030
+ controllerSession.store
4031
+ );
4032
+ const deferredIssueSearch = useDeferredValue(
4033
+ snapshot.nodeState.issueSearchQuery
4034
+ );
4035
+ const floatingNotice = resolveIssueManagerFloatingNoticeViewState({
4036
+ notification: snapshot.notification
4037
+ });
4038
+ useEffect5(() => {
4039
+ controllerSession.retain();
4040
+ return () => {
4041
+ controllerSession.release();
4042
+ };
4043
+ }, [controllerSession]);
4044
+ useEffect5(() => {
4045
+ controllerSession.syncInput({
4046
+ deferredIssueSearch,
4047
+ onStateChange,
4048
+ taskListCollapsed: state?.taskListCollapsed === true
4049
+ });
4050
+ }, [
4051
+ controllerSession,
4052
+ deferredIssueSearch,
4053
+ onStateChange,
4054
+ state?.taskListCollapsed
4055
+ ]);
4056
+ return {
4057
+ controllerSession,
4058
+ deferredIssueSearch,
4059
+ floatingNotice,
4060
+ snapshot
4061
+ };
4062
+ }
4063
+
4064
+ // src/ui/internal/useIssueManagerController.ts
4065
+ function useIssueManagerController({
4066
+ feature,
4067
+ onStateChange,
4068
+ resolveRichTextAtProviders,
4069
+ service,
4070
+ state,
4071
+ workspaceId
4072
+ }) {
4073
+ const copy = feature.i18n;
4074
+ const { controllerSession, floatingNotice, snapshot } = useIssueManagerControllerRuntime({
4075
+ feature,
4076
+ onStateChange,
4077
+ service,
4078
+ state,
4079
+ workspaceId
4080
+ });
4081
+ const {
4082
+ issueDetail,
4083
+ issueDraft,
4084
+ issueEditorMode,
4085
+ issues,
4086
+ isRunningTask,
4087
+ nodeState,
4088
+ notification,
4089
+ referenceTarget,
4090
+ taskDetail,
4091
+ taskDraft,
4092
+ taskEditorMode
4093
+ } = snapshot;
4094
+ const {
4095
+ canInviteCollaborators,
4096
+ canReferenceWorkspaceFiles,
4097
+ canUploadWorkspaceFiles
4098
+ } = useMemo4(
4099
+ () => resolveIssueManagerControllerCapabilities(feature),
4100
+ [feature]
4101
+ );
4102
+ const actions = createIssueManagerControllerActionsBridge({
4103
+ controllerSession,
4104
+ copy,
4105
+ feature,
4106
+ issueDetail,
4107
+ issueDraft,
4108
+ issueEditorMode,
4109
+ nodeState,
4110
+ referenceTarget,
4111
+ taskDetail,
4112
+ taskDraft,
4113
+ taskEditorMode,
4114
+ workspaceId
4115
+ });
4116
+ const bindings = createIssueManagerControllerBindings({
4117
+ controllerSession,
4118
+ issueEditorMode,
4119
+ nodeState,
4120
+ onResolveRichTextAtProviders: resolveRichTextAtProviders,
4121
+ taskEditorMode,
4122
+ workspaceId
4123
+ });
4124
+ return {
4125
+ ...actions,
4126
+ ...bindings,
4127
+ canInviteCollaborators,
4128
+ canReferenceWorkspaceFiles,
4129
+ canUploadWorkspaceFiles,
4130
+ copy,
4131
+ issueDetail,
4132
+ issueDraft,
4133
+ issueEditorMode,
4134
+ floatingNotice,
4135
+ issues,
4136
+ isRunningTask,
4137
+ nodeState,
4138
+ notification,
4139
+ providerOptions: issueManagerProviderOptions,
4140
+ referenceTarget,
4141
+ taskDetail,
4142
+ taskDraft,
4143
+ taskEditorMode,
4144
+ workspaceId
4145
+ };
4146
+ }
4147
+
4148
+ // src/ui/internal/useIssueManagerNodeView.ts
4149
+ function useIssueManagerNodeView({
4150
+ feature,
4151
+ nodeId,
4152
+ onStateChange,
4153
+ resolveRichTextAtProviders,
4154
+ service,
4155
+ state,
4156
+ workspaceId
4157
+ }) {
4158
+ const controller = useIssueManagerController({
4159
+ feature,
4160
+ onStateChange,
4161
+ resolveRichTextAtProviders,
4162
+ service,
4163
+ state,
4164
+ workspaceId
4165
+ });
4166
+ useIssueManagerTaskListCollapsedSync({
4167
+ nodeId,
4168
+ onCollapsedChange: (collapsed) => {
4169
+ controller.setTaskListCollapsed(collapsed);
4170
+ }
4171
+ });
4172
+ const selectedIssue = resolveIssueManagerSelectedIssue({
4173
+ issueDetail: controller.issueDetail.value?.issue ?? null,
4174
+ issues: controller.issues.value,
4175
+ selectedIssueId: controller.nodeState.selectedIssueId
4176
+ });
4177
+ const selectedTask = resolveIssueManagerSelectedTask({
4178
+ selectedTaskId: controller.nodeState.selectedTaskId,
4179
+ taskDetail: controller.taskDetail.value?.task ?? null,
4180
+ tasks: controller.issueDetail.value?.tasks ?? []
4181
+ });
4182
+ return {
4183
+ controller,
4184
+ referencePicker: {
4185
+ onClose: () => {
4186
+ controller.setReferenceTarget(null);
4187
+ },
4188
+ onConfirm: (refs) => {
4189
+ void controller.submitReferenceSelection(refs);
4190
+ },
4191
+ open: controller.referenceTarget !== null
4192
+ },
4193
+ selectedIssue,
4194
+ selectedTask,
4195
+ shell: {
4196
+ onCloseTaskDrawer: () => {
4197
+ controller.setTaskEditorMode("read");
4198
+ controller.selectTask(null);
4199
+ },
4200
+ onDismissIssueCreate: () => {
4201
+ controller.setIssueEditorMode("read");
4202
+ }
4203
+ }
4204
+ };
4205
+ }
4206
+
4207
+ // src/ui/IssueManagerNode.tsx
4208
+ import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
4209
+ function IssueManagerNode({
4210
+ feature,
4211
+ nodeId,
4212
+ onStateChange,
4213
+ resolveRichTextAtProviders,
4214
+ service,
4215
+ state,
4216
+ workspaceId
4217
+ }) {
4218
+ const { controller, referencePicker, selectedIssue, selectedTask, shell } = useIssueManagerNodeView({
4219
+ feature,
4220
+ nodeId,
4221
+ onStateChange,
4222
+ resolveRichTextAtProviders,
4223
+ service,
4224
+ state,
4225
+ workspaceId
4226
+ });
4227
+ return /* @__PURE__ */ jsxs19(
4228
+ "section",
4229
+ {
4230
+ "aria-label": controller.copy.t("title"),
4231
+ className: "flex h-full min-h-0 w-full min-w-0 flex-col overflow-hidden text-[var(--text-primary)]",
4232
+ "data-issue-manager-node-id": nodeId,
4233
+ "data-issue-manager-workspace-id": workspaceId,
4234
+ children: [
4235
+ /* @__PURE__ */ jsx19(
4236
+ IssueManagerShell,
4237
+ {
4238
+ controller,
4239
+ onCloseTaskDrawer: shell.onCloseTaskDrawer,
4240
+ onDismissIssueCreate: shell.onDismissIssueCreate,
4241
+ selectedIssue,
4242
+ selectedTask
4243
+ }
4244
+ ),
4245
+ /* @__PURE__ */ jsx19(
4246
+ IssueManagerReferencePicker,
4247
+ {
4248
+ copy: controller.copy,
4249
+ fileAdapter: feature.fileAdapter,
4250
+ open: referencePicker.open,
4251
+ workspaceId,
4252
+ onClose: referencePicker.onClose,
4253
+ onConfirm: referencePicker.onConfirm
4254
+ }
4255
+ )
4256
+ ]
4257
+ }
4258
+ );
4259
+ }
4260
+ function IssueManagerNodeHeader({
4261
+ className,
4262
+ copy,
4263
+ defaultActions,
4264
+ isSidebarAutoCollapsed,
4265
+ isSidebarCollapsed,
4266
+ nodeId,
4267
+ onToggleSidebar,
4268
+ title,
4269
+ ...headerProps
4270
+ }) {
4271
+ const { effectiveCollapsed, toggleLabel, toggleSidebar } = useIssueManagerNodeHeaderView({
4272
+ copy,
4273
+ isSidebarAutoCollapsed,
4274
+ isSidebarCollapsed,
4275
+ nodeId,
4276
+ onToggleSidebar
4277
+ });
4278
+ return /* @__PURE__ */ jsxs19(
4279
+ "header",
4280
+ {
4281
+ ...headerProps,
4282
+ className: cn10(
4283
+ "flex h-full min-h-0 items-center justify-between gap-3 bg-[var(--background-panel)] px-2 pl-3",
4284
+ className
4285
+ ),
4286
+ children: [
4287
+ /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 items-center gap-2", children: [
4288
+ /* @__PURE__ */ jsx19("span", { className: "min-w-0 truncate text-[13px] font-semibold leading-5 text-[var(--text-primary)]", children: title?.trim() || copy.t("title") }),
4289
+ /* @__PURE__ */ jsx19(
4290
+ Button14,
4291
+ {
4292
+ "aria-label": toggleLabel,
4293
+ className: "rounded-md",
4294
+ "data-issue-manager-sidebar-auto-collapsed": isSidebarAutoCollapsed ? "true" : void 0,
4295
+ "data-issue-manager-sidebar-collapsed": effectiveCollapsed ? "true" : void 0,
4296
+ size: "icon-sm",
4297
+ title: toggleLabel,
4298
+ type: "button",
4299
+ variant: "chrome",
4300
+ onClick: (event) => {
4301
+ event.stopPropagation();
4302
+ toggleSidebar();
4303
+ },
4304
+ onDoubleClick: (event) => event.stopPropagation(),
4305
+ onPointerDown: (event) => event.stopPropagation(),
4306
+ children: /* @__PURE__ */ jsx19(PanelIcon, { className: "size-[18px]" })
4307
+ }
4308
+ )
4309
+ ] }),
4310
+ /* @__PURE__ */ jsx19(
4311
+ "div",
4312
+ {
4313
+ className: "flex flex-none items-center gap-1",
4314
+ onDoubleClick: (event) => event.stopPropagation(),
4315
+ onPointerDown: (event) => event.stopPropagation(),
4316
+ children: defaultActions
4317
+ }
4318
+ )
4319
+ ]
4320
+ }
4321
+ );
4322
+ }
4323
+
4324
+ export {
4325
+ dispatchIssueManagerTaskListCollapsed,
4326
+ IssueManagerNode,
4327
+ IssueManagerNodeHeader
4328
+ };
4329
+ //# sourceMappingURL=chunk-WSFC2COJ.js.map