@nextop-os/workspace-issue-manager 0.0.18 → 0.0.20

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