@nextop-os/workspace-issue-manager 0.0.27 → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{chunk-LJQG24Y2.js → chunk-I7SVY3KV.js} +159 -25
  2. package/dist/chunk-I7SVY3KV.js.map +1 -0
  3. package/dist/{chunk-JGIOWEUE.js → chunk-MJXXZPDJ.js} +93 -35
  4. package/dist/chunk-MJXXZPDJ.js.map +1 -0
  5. package/dist/chunk-N6NGQ7DZ.js +14 -0
  6. package/dist/chunk-N6NGQ7DZ.js.map +1 -0
  7. package/dist/{chunk-MCVRP7RR.js → chunk-SUCZIXKI.js} +66 -20
  8. package/dist/chunk-SUCZIXKI.js.map +1 -0
  9. package/dist/{chunk-5V4DIEWZ.js → chunk-UT34M3FS.js} +1673 -1933
  10. package/dist/chunk-UT34M3FS.js.map +1 -0
  11. package/dist/contracts/index.d.ts +100 -68
  12. package/dist/core/index.d.ts +14 -6
  13. package/dist/core/index.js +4 -2
  14. package/dist/{feature-2zhsUF_g.d.ts → feature-Daez355C.d.ts} +7 -1
  15. package/dist/i18n/index.js +1 -1
  16. package/dist/index.d.ts +4 -3
  17. package/dist/index.js +5 -3
  18. package/dist/{issueManagerControllerService.interface-BtvnnFla.d.ts → issueManagerControllerService.interface-SdcCRGnc.d.ts} +3 -2
  19. package/dist/services/index.d.ts +4 -3
  20. package/dist/services/index.js +3 -3
  21. package/dist/ui/index.d.ts +5 -3
  22. package/dist/ui/index.js +4 -4
  23. package/dist/workbench/constants.d.ts +6 -0
  24. package/dist/workbench/constants.js +9 -0
  25. package/dist/workbench/constants.js.map +1 -0
  26. package/dist/workbench/index.d.ts +5 -4
  27. package/dist/workbench/index.js +10 -11
  28. package/dist/workbench/index.js.map +1 -1
  29. package/openapi/issue-manager.v1.yaml +366 -2
  30. package/package.json +11 -6
  31. package/dist/chunk-5V4DIEWZ.js.map +0 -1
  32. package/dist/chunk-JGIOWEUE.js.map +0 -1
  33. package/dist/chunk-LJQG24Y2.js.map +0 -1
  34. package/dist/chunk-MCVRP7RR.js.map +0 -1
@@ -4,6 +4,7 @@ import {
4
4
  applyIssueManagerIssueSaved,
5
5
  applyIssueManagerIssueSelection,
6
6
  applyIssueManagerSelectedAgentProvider,
7
+ applyIssueManagerSelectedExecutionDirectory,
7
8
  applyIssueManagerTaskDeleted,
8
9
  applyIssueManagerTaskEditorModeToNodeState,
9
10
  applyIssueManagerTaskSaved,
@@ -16,16 +17,13 @@ import {
16
17
  formatIssueManagerDate,
17
18
  formatIssueManagerTimestamp,
18
19
  persistIssueManagerIssueDraftContent,
19
- persistIssueManagerIssueDraftTitle,
20
20
  persistIssueManagerTaskDraftContent,
21
- persistIssueManagerTaskDraftTitle,
22
21
  resolveIssueManagerErrorMessage,
23
- resolveIssueManagerPriorityLabel,
24
22
  resolveIssueManagerStatusLabel,
23
+ resolveIssueManagerTopicDeleteErrorMessage,
25
24
  toContextRefInput,
26
- toIssueManagerWorkspaceFileLinkInput,
27
- uniqueIssueManagerFileReferences
28
- } from "./chunk-LJQG24Y2.js";
25
+ toIssueManagerWorkspaceFileLinkInput
26
+ } from "./chunk-I7SVY3KV.js";
29
27
  import {
30
28
  appendIssueManagerWorkspaceFileLinksToContent,
31
29
  clampIssueManagerSidebarWidth,
@@ -36,11 +34,78 @@ import {
36
34
  issueManagerSidebarMinWidth,
37
35
  normalizeIssueManagerContent,
38
36
  shouldAutoCollapseIssueManagerSidebar
39
- } from "./chunk-MCVRP7RR.js";
37
+ } from "./chunk-SUCZIXKI.js";
40
38
 
41
39
  // src/ui/react/internal/shell/IssueManagerNodeState.ts
42
40
  import { useEffect, useEffectEvent, useState } from "react";
43
41
  var issueManagerTaskListCollapsedEvent = "nextop:issue-manager-task-list-collapsed";
42
+ function createIssueManagerKeyedEventHub(input) {
43
+ const listenerSetByKey = /* @__PURE__ */ new Map();
44
+ return {
45
+ publish(detail) {
46
+ listenerSetByKey.get(input.getKey(detail))?.forEach((listener) => {
47
+ listener(detail);
48
+ });
49
+ },
50
+ subscribe(key, listener) {
51
+ let listenerSet = listenerSetByKey.get(key);
52
+ if (!listenerSet) {
53
+ listenerSet = /* @__PURE__ */ new Set();
54
+ listenerSetByKey.set(key, listenerSet);
55
+ }
56
+ listenerSet.add(listener);
57
+ return () => {
58
+ listenerSet?.delete(listener);
59
+ if (listenerSet?.size === 0) {
60
+ listenerSetByKey.delete(key);
61
+ }
62
+ };
63
+ }
64
+ };
65
+ }
66
+ function createIssueManagerKeyedReplayEventHub(input) {
67
+ const currentByKey = /* @__PURE__ */ new Map();
68
+ const eventHub = createIssueManagerKeyedEventHub(input);
69
+ return {
70
+ get(key) {
71
+ return currentByKey.get(key) ?? null;
72
+ },
73
+ publish(detail) {
74
+ currentByKey.set(input.getKey(detail), detail);
75
+ eventHub.publish(detail);
76
+ },
77
+ subscribe(key, listener) {
78
+ const unsubscribe = eventHub.subscribe(key, listener);
79
+ const current = currentByKey.get(key);
80
+ if (current) {
81
+ listener(current);
82
+ }
83
+ return unsubscribe;
84
+ }
85
+ };
86
+ }
87
+ var issueManagerTopicHeaderStateHub = createIssueManagerKeyedReplayEventHub({
88
+ getKey: (detail) => detail.nodeId
89
+ });
90
+ var issueManagerTopicSelectionHub = createIssueManagerKeyedEventHub({
91
+ getKey: (detail) => detail.nodeId
92
+ });
93
+ var issueManagerTopicCreateHub = createIssueManagerKeyedEventHub({
94
+ getKey: (detail) => detail.nodeId
95
+ });
96
+ var issueManagerTopicDeleteHub = createIssueManagerKeyedEventHub({
97
+ getKey: (detail) => detail.nodeId
98
+ });
99
+ var issueManagerTopicUpdateHub = createIssueManagerKeyedEventHub({
100
+ getKey: (detail) => detail.nodeId
101
+ });
102
+ function resolveIssueManagerTopicHeaderState(input) {
103
+ return issueManagerTopicHeaderStateHub.get(input.nodeId) ?? {
104
+ activeTopicId: input.activeTopicId,
105
+ nodeId: input.nodeId,
106
+ topics: []
107
+ };
108
+ }
44
109
  function dispatchIssueManagerTaskListCollapsed(input) {
45
110
  if (typeof window === "undefined") {
46
111
  return;
@@ -54,6 +119,21 @@ function dispatchIssueManagerTaskListCollapsed(input) {
54
119
  )
55
120
  );
56
121
  }
122
+ function dispatchIssueManagerTopicHeaderState(input) {
123
+ issueManagerTopicHeaderStateHub.publish(input);
124
+ }
125
+ function dispatchIssueManagerTopicSelection(input) {
126
+ issueManagerTopicSelectionHub.publish(input);
127
+ }
128
+ function dispatchIssueManagerTopicCreate(input) {
129
+ issueManagerTopicCreateHub.publish(input);
130
+ }
131
+ function dispatchIssueManagerTopicDelete(input) {
132
+ issueManagerTopicDeleteHub.publish(input);
133
+ }
134
+ function dispatchIssueManagerTopicUpdate(input) {
135
+ issueManagerTopicUpdateHub.publish(input);
136
+ }
57
137
  function useIssueManagerTaskListCollapsedSync(input) {
58
138
  const onCollapsedChange = useEffectEvent(input.onCollapsedChange);
59
139
  useEffect(() => {
@@ -79,6 +159,74 @@ function useIssueManagerTaskListCollapsedSync(input) {
79
159
  };
80
160
  }, [input.nodeId, onCollapsedChange]);
81
161
  }
162
+ function useIssueManagerTopicHeaderStateSync(input) {
163
+ const [state, setState] = useState(
164
+ () => resolveIssueManagerTopicHeaderState(input)
165
+ );
166
+ useEffect(() => {
167
+ setState(
168
+ (current) => current.activeTopicId === input.activeTopicId && current.nodeId === input.nodeId && current.topics === resolveIssueManagerTopicHeaderState(input).topics ? current : resolveIssueManagerTopicHeaderState(input)
169
+ );
170
+ }, [input.activeTopicId, input.nodeId]);
171
+ useEffect(() => {
172
+ const handleTopicHeaderStateChange = (detail) => {
173
+ setState(detail);
174
+ };
175
+ return issueManagerTopicHeaderStateHub.subscribe(
176
+ input.nodeId,
177
+ handleTopicHeaderStateChange
178
+ );
179
+ }, [input.nodeId]);
180
+ return state;
181
+ }
182
+ function useIssueManagerTopicHeaderCommandSync(input) {
183
+ const onCreateTopic = useEffectEvent(input.onCreateTopic);
184
+ const onDeleteTopic = useEffectEvent(input.onDeleteTopic);
185
+ const onSelectTopic = useEffectEvent(input.onSelectTopic);
186
+ const onUpdateTopic = useEffectEvent(input.onUpdateTopic);
187
+ useEffect(() => {
188
+ const handleTopicSelection = (detail) => {
189
+ onSelectTopic(detail.topicId);
190
+ };
191
+ const handleTopicCreate = (detail) => {
192
+ onCreateTopic(detail.input);
193
+ };
194
+ const handleTopicDelete = (detail) => {
195
+ onDeleteTopic(detail.topicId);
196
+ };
197
+ const handleTopicUpdate = (detail) => {
198
+ onUpdateTopic(detail.input);
199
+ };
200
+ const unsubscribeSelection = issueManagerTopicSelectionHub.subscribe(
201
+ input.nodeId,
202
+ handleTopicSelection
203
+ );
204
+ const unsubscribeCreate = issueManagerTopicCreateHub.subscribe(
205
+ input.nodeId,
206
+ handleTopicCreate
207
+ );
208
+ const unsubscribeDelete = issueManagerTopicDeleteHub.subscribe(
209
+ input.nodeId,
210
+ handleTopicDelete
211
+ );
212
+ const unsubscribeUpdate = issueManagerTopicUpdateHub.subscribe(
213
+ input.nodeId,
214
+ handleTopicUpdate
215
+ );
216
+ return () => {
217
+ unsubscribeSelection();
218
+ unsubscribeCreate();
219
+ unsubscribeDelete();
220
+ unsubscribeUpdate();
221
+ };
222
+ }, [
223
+ input.nodeId,
224
+ onCreateTopic,
225
+ onDeleteTopic,
226
+ onSelectTopic,
227
+ onUpdateTopic
228
+ ]);
229
+ }
82
230
  function useIssueManagerNodeHeaderView(input) {
83
231
  const [manualCollapsed, setManualCollapsed] = useState(
84
232
  input.isSidebarCollapsed
@@ -113,80 +261,15 @@ function resolveIssueManagerSelectedTask(input) {
113
261
  }
114
262
 
115
263
  // 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
- }
264
+ import {
265
+ collectVisibleTreeEntries,
266
+ createWorkspaceFileReferenceDirectoryStateFromSnapshot,
267
+ mergeExpandedFolderPaths,
268
+ mergePrefetchedDirectoryState,
269
+ normalizeDirectoryPath,
270
+ prefetchReferenceTree,
271
+ workspaceFileReferenceDefaultExpandedDepth
272
+ } from "@nextop-os/workspace-file-reference/react";
190
273
 
191
274
  // src/ui/react/internal/controller/useIssueManagerController.ts
192
275
  import { useMemo as useMemo2 } from "react";
@@ -195,6 +278,7 @@ import { useMemo as useMemo2 } from "react";
195
278
  var issueManagerProviderOptions = ["codex"];
196
279
  function resolveIssueManagerControllerCapabilities(feature) {
197
280
  return {
281
+ canSelectExecutionDirectory: typeof feature.executionDirectoryPicker?.selectDirectory === "function",
198
282
  canInviteCollaborators: feature.ui.showInviteCollaborator === true && typeof feature.shareAdapter?.createIssueLink === "function",
199
283
  canReferenceWorkspaceFiles: hasFileAdapterMethod(feature.fileAdapter, "requestReferences") || hasFileAdapterMethod(feature.fileAdapter, "loadReferenceTree") || hasFileAdapterMethod(feature.fileAdapter, "listDirectory") || hasFileAdapterMethod(feature.fileAdapter, "searchReferences"),
200
284
  canUploadWorkspaceFiles: hasFileAdapterMethod(
@@ -380,7 +464,7 @@ function createIssueManagerInsertReferencesOutcome(input) {
380
464
 
381
465
  // src/services/internal/controllerPlans.ts
382
466
  function createIssueManagerRunTaskPlan(input) {
383
- if (!input.issueDetail || !input.taskDetail) {
467
+ if (!input.issueDetail) {
384
468
  return { kind: "skip" };
385
469
  }
386
470
  const provider = input.providerOverride?.trim() || input.selectedAgentProvider.trim();
@@ -394,6 +478,12 @@ function createIssueManagerRunTaskPlan(input) {
394
478
  };
395
479
  }
396
480
  function createIssueManagerSaveIssuePlan(input) {
481
+ if (!input.activeTopicId) {
482
+ return {
483
+ kind: "blocked",
484
+ notificationKey: "messages.topicListEmpty"
485
+ };
486
+ }
397
487
  const title = input.issueDraft.title.trim();
398
488
  if (!title) {
399
489
  return {
@@ -401,7 +491,7 @@ function createIssueManagerSaveIssuePlan(input) {
401
491
  notificationKey: "messages.titleRequired"
402
492
  };
403
493
  }
404
- return { kind: "ready" };
494
+ return { kind: "ready", activeTopicId: input.activeTopicId };
405
495
  }
406
496
  function createIssueManagerSaveTaskPlan(input) {
407
497
  if (!input.selectedIssueId) {
@@ -470,55 +560,16 @@ function createIssueManagerInsertReferencesPlan(input) {
470
560
 
471
561
  // src/services/internal/run/controllerRunCommands.ts
472
562
  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,
563
+ const result = await input.feature.agentRunner.runTask({
564
+ ...input.executionDirectory?.trim() ? { executionDirectory: input.executionDirectory.trim() } : {},
565
+ issue: input.issue,
566
+ provider: input.provider,
567
+ ...input.task ? { task: input.task } : {},
481
568
  workspaceId: input.workspaceId
482
569
  });
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
- }
570
+ return {
571
+ status: result.status
572
+ };
522
573
  }
523
574
 
524
575
  // src/services/internal/save/controllerSaveCommands.ts
@@ -527,6 +578,7 @@ async function executeIssueManagerSaveIssue(input) {
527
578
  const savedIssue = input.issueEditorMode === "create" ? await input.feature.backend.createIssue({
528
579
  content,
529
580
  title: input.issueDraft.title.trim(),
581
+ topicId: input.activeTopicId,
530
582
  workspaceId: input.workspaceId
531
583
  }) : await input.feature.backend.updateIssue({
532
584
  content,
@@ -848,6 +900,52 @@ function createIssueManagerControllerActions(input) {
848
900
  notifyError(error, "messages.referenceRemoveFailed");
849
901
  }
850
902
  },
903
+ async selectExecutionDirectory() {
904
+ const picker = feature.executionDirectoryPicker;
905
+ if (!picker) {
906
+ return;
907
+ }
908
+ try {
909
+ const selected = await picker.selectDirectory();
910
+ const executionDirectory = selected?.trim() || null;
911
+ if (!executionDirectory) {
912
+ return;
913
+ }
914
+ try {
915
+ await picker.useUserProject?.({ path: executionDirectory });
916
+ } catch {
917
+ }
918
+ updateNodeState(
919
+ (current) => applyIssueManagerSelectedExecutionDirectory(
920
+ current,
921
+ executionDirectory
922
+ )
923
+ );
924
+ } catch (error) {
925
+ notifyTip(
926
+ resolveIssueManagerErrorMessage(
927
+ error,
928
+ copy,
929
+ "messages.executionDirectorySelectFailed"
930
+ )
931
+ );
932
+ }
933
+ },
934
+ async useExecutionDirectory(path) {
935
+ const executionDirectory = path?.trim() || null;
936
+ updateNodeState(
937
+ (current) => applyIssueManagerSelectedExecutionDirectory(current, executionDirectory)
938
+ );
939
+ if (!executionDirectory) {
940
+ return;
941
+ }
942
+ try {
943
+ await feature.executionDirectoryPicker?.useUserProject?.({
944
+ path: executionDirectory
945
+ });
946
+ } catch {
947
+ }
948
+ },
851
949
  async runTask(providerOverride) {
852
950
  const runPlan = createIssueManagerRunTaskPlan({
853
951
  issueDetail: issueDetail.value,
@@ -860,7 +958,7 @@ function createIssueManagerControllerActions(input) {
860
958
  }
861
959
  const currentIssueDetail = issueDetail.value;
862
960
  const currentTaskDetail = taskDetail.value;
863
- if (!currentIssueDetail || !currentTaskDetail) {
961
+ if (!currentIssueDetail) {
864
962
  return;
865
963
  }
866
964
  if (runPlan.shouldUpdateSelectedAgentProvider) {
@@ -871,12 +969,11 @@ function createIssueManagerControllerActions(input) {
871
969
  setIsRunningTask(true);
872
970
  try {
873
971
  const result = await executeIssueManagerRunTask({
874
- copy,
875
972
  feature,
876
973
  issue: currentIssueDetail.issue,
877
- onCreatedRun: refreshDetails,
878
974
  provider: runPlan.provider,
879
- task: currentTaskDetail.task,
975
+ executionDirectory: nodeState.selectedExecutionDirectory,
976
+ task: currentTaskDetail?.task,
880
977
  workspaceId
881
978
  });
882
979
  const outcome = createIssueManagerRunTaskSuccessOutcome({
@@ -892,8 +989,57 @@ function createIssueManagerControllerActions(input) {
892
989
  refreshDetails();
893
990
  }
894
991
  },
992
+ async startTaskBreakdown(providerOverride) {
993
+ const breakdownPlan = createIssueManagerRunTaskPlan({
994
+ issueDetail: issueDetail.value,
995
+ providerOverride,
996
+ selectedAgentProvider: nodeState.selectedAgentProvider,
997
+ taskDetail: taskDetail.value
998
+ });
999
+ if (breakdownPlan.kind !== "ready") {
1000
+ return;
1001
+ }
1002
+ const currentIssueDetail = issueDetail.value;
1003
+ if (!currentIssueDetail) {
1004
+ return;
1005
+ }
1006
+ const breakdownLauncher = feature.agentBreakdownLauncher;
1007
+ if (!breakdownLauncher) {
1008
+ notifyTip(copy.t("messages.breakdownUnavailable"));
1009
+ return;
1010
+ }
1011
+ if (breakdownPlan.shouldUpdateSelectedAgentProvider) {
1012
+ updateNodeState(
1013
+ (current) => applyIssueManagerSelectedAgentProvider(
1014
+ current,
1015
+ breakdownPlan.provider
1016
+ )
1017
+ );
1018
+ }
1019
+ try {
1020
+ const result = await breakdownLauncher.startBreakdown({
1021
+ issueDetail: currentIssueDetail,
1022
+ provider: breakdownPlan.provider,
1023
+ workspaceId
1024
+ });
1025
+ if (result.status === "failed") {
1026
+ notifyTip(
1027
+ result.errorMessage || copy.t("messages.breakdownOpenFailed")
1028
+ );
1029
+ }
1030
+ } catch (error) {
1031
+ notifyTip(
1032
+ resolveIssueManagerErrorMessage(
1033
+ error,
1034
+ copy,
1035
+ "messages.breakdownOpenFailed"
1036
+ )
1037
+ );
1038
+ }
1039
+ },
895
1040
  async saveIssue() {
896
1041
  const savePlan = createIssueManagerSaveIssuePlan({
1042
+ activeTopicId: nodeState.activeTopicId ?? null,
897
1043
  issueDraft
898
1044
  });
899
1045
  if (savePlan.kind === "blocked") {
@@ -902,6 +1048,7 @@ function createIssueManagerControllerActions(input) {
902
1048
  }
903
1049
  try {
904
1050
  const { savedIssue } = await executeIssueManagerSaveIssue({
1051
+ activeTopicId: savePlan.activeTopicId,
905
1052
  feature,
906
1053
  issueDetail: issueDetail.value,
907
1054
  issueDraft,
@@ -1067,9 +1214,6 @@ function createIssueManagerIssueBindings(input) {
1067
1214
  ...current,
1068
1215
  title
1069
1216
  }));
1070
- controllerSession.updateNodeState(
1071
- (current) => persistIssueManagerIssueDraftTitle(current, issueEditorMode, title)
1072
- );
1073
1217
  }
1074
1218
  };
1075
1219
  }
@@ -1127,9 +1271,6 @@ function createIssueManagerTaskBindings(input) {
1127
1271
  ...current,
1128
1272
  title
1129
1273
  }));
1130
- controllerSession.updateNodeState(
1131
- (current) => persistIssueManagerTaskDraftTitle(current, taskEditorMode, title)
1132
- );
1133
1274
  }
1134
1275
  };
1135
1276
  }
@@ -1193,7 +1334,7 @@ import { useDeferredValue, useEffect as useEffect2, useMemo } from "react";
1193
1334
  import { useSnapshot } from "valtio";
1194
1335
 
1195
1336
  // src/ui/react/internal/shell/IssueManagerNoticeState.ts
1196
- var issueManagerNoticeDurationMs = 3200;
1337
+ var issueManagerNoticeDurationMs = 3e3;
1197
1338
  function resolveIssueManagerFloatingNoticeViewState(input) {
1198
1339
  if (!input.notification) {
1199
1340
  return null;
@@ -1285,11 +1426,13 @@ function useIssueManagerController({
1285
1426
  referenceTarget,
1286
1427
  taskDetail,
1287
1428
  taskDraft,
1288
- taskEditorMode
1429
+ taskEditorMode,
1430
+ topics
1289
1431
  } = snapshot;
1290
1432
  const {
1291
1433
  canInviteCollaborators,
1292
1434
  canReferenceWorkspaceFiles,
1435
+ canSelectExecutionDirectory,
1293
1436
  canUploadWorkspaceFiles
1294
1437
  } = useMemo2(
1295
1438
  () => resolveIssueManagerControllerCapabilities(feature),
@@ -1317,13 +1460,62 @@ function useIssueManagerController({
1317
1460
  taskEditorMode,
1318
1461
  workspaceId
1319
1462
  });
1463
+ const notifyTopicOperationFailure = (message) => {
1464
+ feature.notifications?.tips(message);
1465
+ controllerSession.setNotification((current) => ({
1466
+ id: (current?.id ?? 0) + 1,
1467
+ title: message,
1468
+ tone: "destructive"
1469
+ }));
1470
+ };
1320
1471
  return {
1321
1472
  ...actions,
1322
1473
  ...bindings,
1323
1474
  canInviteCollaborators,
1324
1475
  canReferenceWorkspaceFiles,
1476
+ canSelectExecutionDirectory,
1325
1477
  canUploadWorkspaceFiles,
1326
1478
  copy,
1479
+ async createTopic(topicInput) {
1480
+ try {
1481
+ const topic = await feature.backend.createTopic({
1482
+ ...topicInput,
1483
+ workspaceId
1484
+ });
1485
+ controllerSession.updateNodeState((current) => ({
1486
+ ...current,
1487
+ activeTopicId: topic.topicId
1488
+ }));
1489
+ controllerSession.refreshAll();
1490
+ } catch {
1491
+ notifyTopicOperationFailure(copy.t("messages.topicCreateFailed"));
1492
+ }
1493
+ },
1494
+ async deleteTopic(topicId) {
1495
+ const trimmedTopicId = topicId.trim();
1496
+ if (!trimmedTopicId) {
1497
+ return;
1498
+ }
1499
+ try {
1500
+ await feature.backend.deleteTopic({
1501
+ topicId: trimmedTopicId,
1502
+ workspaceId
1503
+ });
1504
+ if (nodeState.activeTopicId === trimmedTopicId) {
1505
+ controllerSession.updateNodeState((current) => ({
1506
+ ...current,
1507
+ activeTopicId: null,
1508
+ selectedIssueId: null,
1509
+ selectedTaskId: null
1510
+ }));
1511
+ }
1512
+ controllerSession.refreshAll();
1513
+ } catch (error) {
1514
+ notifyTopicOperationFailure(
1515
+ resolveIssueManagerTopicDeleteErrorMessage(error, copy)
1516
+ );
1517
+ }
1518
+ },
1327
1519
  issueDetail,
1328
1520
  issueDraft,
1329
1521
  issueEditorMode,
@@ -1333,10 +1525,33 @@ function useIssueManagerController({
1333
1525
  nodeState,
1334
1526
  notification,
1335
1527
  providerOptions: issueManagerProviderOptions,
1528
+ listExecutionDirectoryProjects: () => feature.executionDirectoryPicker?.listUserProjects?.() ?? Promise.resolve({ projects: [] }),
1336
1529
  referenceTarget,
1530
+ selectTopic(topicId) {
1531
+ const trimmedTopicId = topicId.trim();
1532
+ if (!trimmedTopicId) {
1533
+ return;
1534
+ }
1535
+ controllerSession.updateNodeState((current) => ({
1536
+ ...current,
1537
+ activeTopicId: trimmedTopicId
1538
+ }));
1539
+ },
1337
1540
  taskDetail,
1338
1541
  taskDraft,
1339
1542
  taskEditorMode,
1543
+ topics,
1544
+ async updateTopic(topicInput) {
1545
+ try {
1546
+ await feature.backend.updateTopic({
1547
+ ...topicInput,
1548
+ workspaceId
1549
+ });
1550
+ controllerSession.refreshAll();
1551
+ } catch {
1552
+ notifyTopicOperationFailure(copy.t("messages.topicUpdateFailed"));
1553
+ }
1554
+ },
1340
1555
  workspaceId
1341
1556
  };
1342
1557
  }
@@ -1400,1089 +1615,133 @@ function useIssueManagerNodeView({
1400
1615
  };
1401
1616
  }
1402
1617
 
1403
- // src/ui/react/internal/reference/useIssueManagerReferencePickerView.ts
1404
- import { useEffect as useEffect3, useEffectEvent as useEffectEvent2, useMemo as useMemo3, useState as useState2 } from "react";
1618
+ // src/ui/react/index.ts
1405
1619
  import {
1406
- createWorkspaceFilePreviewLoadedState,
1407
- resolveWorkspaceFilePreviewReadiness
1408
- } from "@nextop-os/workspace-file-preview";
1409
- var defaultDirectoryPath = "/";
1410
- function useIssueManagerReferencePickerView({
1411
- fileAdapter,
1412
- onClose,
1413
- onConfirm,
1414
- open,
1415
- workspaceId
1416
- }) {
1417
- const [searchQuery, setSearchQuery] = useState2("");
1418
- const [browseRootPath, setBrowseRootPath] = useState2(null);
1419
- const [searchEntries, setSearchEntries] = useState2([]);
1420
- const [directoryStateByPath, setDirectoryStateByPath] = useState2({});
1421
- const [expandedFolderPaths, setExpandedFolderPaths] = useState2({});
1422
- const [focusedPath, setFocusedPath] = useState2(null);
1423
- const [isLoading, setIsLoading] = useState2(false);
1424
- const [selectedRefs, setSelectedRefs] = useState2(
1425
- []
1426
- );
1427
- const [previewState, setPreviewState] = useState2({ status: "empty" });
1428
- const supportsSearch = hasFileAdapterMethod2(fileAdapter, "searchReferences");
1429
- const supportsTreeSnapshot = hasFileAdapterMethod2(
1430
- fileAdapter,
1431
- "loadReferenceTree"
1620
+ useWorkspaceFileReferencePickerView
1621
+ } from "@nextop-os/workspace-file-reference/react";
1622
+
1623
+ // src/ui/IssueManagerNode.tsx
1624
+ import {
1625
+ useEffect as useEffect10
1626
+ } from "react";
1627
+ import { Button as Button12, PanelIcon, cn as cn11 } from "@nextop-os/ui-system";
1628
+ import { WorkspaceFileReferencePicker } from "@nextop-os/workspace-file-reference/ui";
1629
+
1630
+ // src/ui/internal/shell/IssueManagerShell.tsx
1631
+ import { useEffect as useEffect8, useState as useState9 } from "react";
1632
+ import { Button as Button10, FileCreateIcon as FileCreateIcon4, cn as cn9 } from "@nextop-os/ui-system";
1633
+
1634
+ // src/ui/internal/shell/IssueManagerPanels.tsx
1635
+ import { useState as useState5 } from "react";
1636
+ import { Badge as Badge2, Button as Button4, ConfirmationDialog } from "@nextop-os/ui-system";
1637
+
1638
+ // src/ui/internal/status/IssueManagerStatusBadge.ts
1639
+ function issueManagerStatusBadgeVariant(status) {
1640
+ return status === "running" ? "accent" : "default";
1641
+ }
1642
+
1643
+ // src/ui/internal/issue/IssueManagerIssueSections.tsx
1644
+ import {
1645
+ Badge,
1646
+ Button as Button2,
1647
+ FileCreateIcon as FileCreateIcon2,
1648
+ ScrollArea,
1649
+ cn
1650
+ } from "@nextop-os/ui-system";
1651
+
1652
+ // src/ui/internal/panel/IssueManagerPanelText.ts
1653
+ function summarizeIssueManagerContent(content, fallback) {
1654
+ const plainText = stripIssueManagerDescriptionTerminalPunctuation(
1655
+ extractIssueManagerPlainTextFromContent(content ?? "")
1432
1656
  );
1433
- const mode = searchQuery.trim().length > 0 && supportsSearch ? "search" : "browse";
1434
- const browseDirectoryLoaded = browseRootPath !== null && directoryStateByPath[normalizeDirectoryPath(browseRootPath)]?.loaded === true;
1435
- const finalizeRequestedReferences = useEffectEvent2(
1436
- (refs) => {
1437
- onConfirm(uniqueIssueManagerFileReferences(refs));
1438
- onClose();
1439
- }
1440
- );
1441
- const readDirectoryListing = async (path) => {
1442
- if (!fileAdapter?.listDirectory) {
1443
- return null;
1444
- }
1445
- const listing = await fileAdapter.listDirectory({
1446
- path: path ?? void 0,
1447
- workspaceId
1448
- });
1449
- return {
1450
- displayPath: listing.directoryPath || listing.rootPath || path || defaultDirectoryPath,
1451
- entries: uniqueIssueManagerFileReferences(listing.entries),
1452
- normalizedPath: normalizeDirectoryPath(
1453
- listing.directoryPath || listing.rootPath || path || defaultDirectoryPath
1454
- )
1455
- };
1456
- };
1457
- useEffect3(() => {
1458
- if (!open) {
1459
- return;
1460
- }
1461
- setSearchQuery("");
1462
- setBrowseRootPath(null);
1463
- setSearchEntries([]);
1464
- setDirectoryStateByPath({});
1465
- setExpandedFolderPaths({});
1466
- setFocusedPath(null);
1467
- setSelectedRefs([]);
1468
- }, [open]);
1469
- useEffect3(() => {
1470
- if (!open || !fileAdapter) {
1471
- return;
1472
- }
1473
- let canceled = false;
1474
- const load = async () => {
1475
- setIsLoading(true);
1476
- try {
1477
- if (mode === "search" && fileAdapter.searchReferences) {
1478
- const refs = await fileAdapter.searchReferences({
1479
- query: searchQuery.trim(),
1480
- workspaceId
1481
- });
1482
- if (!canceled) {
1483
- setSearchEntries(uniqueIssueManagerFileReferences(refs));
1484
- }
1485
- return;
1486
- }
1487
- if (mode === "browse" && (fileAdapter.listDirectory || fileAdapter.loadReferenceTree)) {
1488
- if (browseDirectoryLoaded && browseRootPath) {
1489
- return;
1490
- }
1491
- if (supportsTreeSnapshot && fileAdapter.loadReferenceTree) {
1492
- const snapshot = await fileAdapter.loadReferenceTree({
1493
- path: browseRootPath ?? void 0,
1494
- prefetchBudgetMs: 500,
1495
- prefetchDepth: 4,
1496
- workspaceId
1497
- });
1498
- if (!canceled) {
1499
- setBrowseRootPath(
1500
- normalizeDirectoryPath(snapshot.directory.directoryPath)
1501
- );
1502
- setDirectoryStateByPath(
1503
- createReferenceDirectoryStateFromSnapshot(snapshot)
1504
- );
1505
- }
1506
- return;
1507
- }
1508
- const listing = await readDirectoryListing(browseRootPath);
1509
- if (!listing) {
1510
- return;
1511
- }
1512
- if (!canceled) {
1513
- setBrowseRootPath(listing.normalizedPath);
1514
- setDirectoryStateByPath((current) => ({
1515
- ...current,
1516
- [listing.normalizedPath]: {
1517
- displayPath: listing.displayPath,
1518
- entries: listing.entries,
1519
- loaded: true,
1520
- loading: false
1521
- }
1522
- }));
1523
- }
1524
- return;
1525
- }
1526
- if (fileAdapter.requestReferences) {
1527
- const refs = await fileAdapter.requestReferences({ workspaceId });
1528
- if (!canceled) {
1529
- finalizeRequestedReferences(refs);
1530
- }
1531
- return;
1532
- }
1533
- if (!canceled) {
1534
- setSearchEntries([]);
1535
- }
1536
- } finally {
1537
- if (!canceled) {
1538
- setIsLoading(false);
1539
- }
1540
- }
1541
- };
1542
- void load();
1543
- return () => {
1544
- canceled = true;
1545
- };
1546
- }, [
1547
- browseDirectoryLoaded,
1548
- browseRootPath,
1549
- fileAdapter,
1550
- finalizeRequestedReferences,
1551
- mode,
1552
- open,
1553
- searchQuery,
1554
- supportsTreeSnapshot,
1555
- workspaceId
1556
- ]);
1557
- const browseRootEntries = useMemo3(
1558
- () => browseRootPath ? directoryStateByPath[normalizeDirectoryPath(browseRootPath)]?.entries ?? [] : [],
1559
- [browseRootPath, directoryStateByPath]
1560
- );
1561
- const visibleEntries = useMemo3(
1562
- () => mode === "search" ? searchEntries : collectVisibleTreeEntries(
1563
- browseRootEntries,
1564
- directoryStateByPath,
1565
- expandedFolderPaths
1566
- ),
1567
- [
1568
- browseRootEntries,
1569
- directoryStateByPath,
1570
- expandedFolderPaths,
1571
- mode,
1572
- searchEntries
1573
- ]
1574
- );
1575
- useEffect3(() => {
1576
- if (!open) {
1577
- return;
1578
- }
1579
- setFocusedPath((current) => {
1580
- if (current && visibleEntries.some((entry) => entry.path === current)) {
1581
- return current;
1582
- }
1583
- return visibleEntries[0]?.path ?? null;
1584
- });
1585
- }, [open, visibleEntries]);
1586
- const focusedEntry = visibleEntries.find((entry) => entry.path === focusedPath) ?? selectedRefs.find((entry) => entry.path === focusedPath) ?? null;
1587
- useEffect3(() => {
1588
- if (!open || !focusedEntry) {
1589
- setPreviewState({ status: "empty" });
1590
- return;
1591
- }
1592
- const readiness = resolveWorkspaceFilePreviewReadiness(focusedEntry);
1593
- if (readiness.status === "directory") {
1594
- setPreviewState({ reference: focusedEntry, status: "directory" });
1595
- return;
1596
- }
1597
- if (readiness.status === "unsupported") {
1598
- setPreviewState({ reference: focusedEntry, status: "unsupported" });
1599
- return;
1600
- }
1601
- if (readiness.status === "readonly") {
1602
- setPreviewState({
1603
- maxSizeBytes: readiness.maxSizeBytes,
1604
- reason: readiness.reason,
1605
- reference: focusedEntry,
1606
- status: "readonly"
1607
- });
1608
- return;
1609
- }
1610
- if (!fileAdapter?.readReferencePreview) {
1611
- setPreviewState({ reference: focusedEntry, status: "unavailable" });
1612
- return;
1613
- }
1614
- const previewTarget = readiness.target;
1615
- let canceled = false;
1616
- let objectUrl = null;
1617
- setPreviewState({ reference: focusedEntry, status: "loading" });
1618
- const load = async () => {
1619
- try {
1620
- const preview = await fileAdapter.readReferencePreview?.({
1621
- reference: focusedEntry,
1622
- workspaceId
1623
- });
1624
- if (canceled) {
1625
- return;
1626
- }
1627
- if (!preview) {
1628
- setPreviewState({ reference: focusedEntry, status: "unsupported" });
1629
- return;
1630
- }
1631
- const nextState = createReferencePreviewState(
1632
- focusedEntry,
1633
- previewTarget,
1634
- preview
1635
- );
1636
- if (nextState.status === "image") {
1637
- objectUrl = nextState.objectUrl;
1638
- }
1639
- setPreviewState(nextState);
1640
- } catch {
1641
- if (!canceled) {
1642
- setPreviewState({ reference: focusedEntry, status: "error" });
1643
- }
1644
- }
1645
- };
1646
- void load();
1647
- return () => {
1648
- canceled = true;
1649
- if (objectUrl) {
1650
- URL.revokeObjectURL(objectUrl);
1651
- }
1652
- };
1653
- }, [fileAdapter, focusedEntry, open, workspaceId]);
1654
- const toggleRef = (ref) => {
1655
- setSelectedRefs((current) => {
1656
- const existing = current.some((item) => item.path === ref.path);
1657
- return existing ? current.filter((item) => item.path !== ref.path) : uniqueIssueManagerFileReferences([...current, ref]);
1658
- });
1659
- };
1660
- const loadFolderChildren = async (folder) => {
1661
- const folderKey = normalizeDirectoryPath(folder.path);
1662
- if (directoryStateByPath[folderKey]?.loaded) {
1663
- return;
1664
- }
1665
- setDirectoryStateByPath((current) => ({
1666
- ...current,
1667
- [folderKey]: {
1668
- displayPath: folder.path,
1669
- entries: current[folderKey]?.entries ?? [],
1670
- loaded: current[folderKey]?.loaded ?? false,
1671
- loading: true
1672
- }
1673
- }));
1674
- try {
1675
- const listing = await readDirectoryListing(folderKey);
1676
- if (!listing) {
1677
- return;
1678
- }
1679
- setDirectoryStateByPath((current) => ({
1680
- ...current,
1681
- [folderKey]: {
1682
- displayPath: listing.displayPath,
1683
- entries: listing.entries,
1684
- loaded: true,
1685
- loading: false
1686
- }
1687
- }));
1688
- } catch {
1689
- setDirectoryStateByPath((current) => ({
1690
- ...current,
1691
- [folderKey]: {
1692
- displayPath: current[folderKey]?.displayPath ?? folder.path,
1693
- entries: current[folderKey]?.entries ?? [],
1694
- loaded: current[folderKey]?.loaded ?? false,
1695
- loading: false
1696
- }
1697
- }));
1698
- }
1699
- };
1700
- const toggleFolder = (entry) => {
1701
- const folderKey = normalizeDirectoryPath(entry.path);
1702
- const childState = directoryStateByPath[folderKey];
1703
- const nextExpanded = !(expandedFolderPaths[folderKey] ?? false);
1704
- setExpandedFolderPaths((current) => ({
1705
- ...current,
1706
- [folderKey]: nextExpanded
1707
- }));
1708
- if (nextExpanded && !childState?.loaded && !childState?.loading) {
1709
- void loadFolderChildren(entry);
1710
- }
1711
- };
1712
- return {
1713
- browseRootEntries,
1714
- directoryStateByPath,
1715
- expandedFolderPaths,
1716
- focusedEntry,
1717
- focusedPath,
1718
- isLoading,
1719
- mode,
1720
- previewState,
1721
- searchQuery,
1722
- selectedRefs,
1723
- visibleEntries,
1724
- setFocusedPath,
1725
- setSearchQuery,
1726
- toggleFolder,
1727
- toggleRef
1728
- };
1729
- }
1730
- function createReferencePreviewState(reference, target, preview) {
1731
- const loadedState = createWorkspaceFilePreviewLoadedState({
1732
- bytes: preview.bytes,
1733
- contentType: preview.contentType,
1734
- entry: reference,
1735
- target: {
1736
- ...target,
1737
- fileKind: preview.kind
1738
- }
1739
- });
1740
- if (loadedState.status === "image") {
1741
- return {
1742
- objectUrl: URL.createObjectURL(
1743
- new Blob([loadedState.bytes], {
1744
- type: loadedState.contentType
1745
- })
1746
- ),
1747
- reference,
1748
- status: "image"
1749
- };
1750
- }
1751
- if (loadedState.status === "text") {
1752
- return {
1753
- content: loadedState.content,
1754
- reference,
1755
- status: "text"
1756
- };
1757
- }
1758
- return {
1759
- maxSizeBytes: loadedState.maxSizeBytes,
1760
- reason: loadedState.reason,
1761
- reference,
1762
- status: "readonly"
1763
- };
1764
- }
1765
- function hasFileAdapterMethod2(fileAdapter, methodName) {
1766
- return typeof Reflect.get(fileAdapter ?? {}, methodName) === "function";
1767
- }
1768
-
1769
- // src/ui/IssueManagerNode.tsx
1770
- import { Button as Button14, PanelIcon, cn as cn12 } from "@nextop-os/ui-system";
1771
-
1772
- // src/ui/internal/reference/IssueManagerReferencePicker.tsx
1773
- import { createPortal } from "react-dom";
1774
- import {
1775
- Button as Button3,
1776
- Card,
1777
- CardContent,
1778
- CardHeader,
1779
- CardTitle,
1780
- CloseIcon,
1781
- cn as cn2
1782
- } from "@nextop-os/ui-system";
1783
-
1784
- // src/ui/internal/reference/IssueManagerReferencePickerSections.tsx
1785
- import {
1786
- Badge,
1787
- Button as Button2,
1788
- FileIcon as FileIcon2,
1789
- FolderFilledIcon as FolderFilledIcon2,
1790
- LoadingIcon
1791
- } from "@nextop-os/ui-system";
1792
- import { formatWorkspacePreviewByteLimit } from "@nextop-os/workspace-file-preview";
1793
- import { WorkspaceFilePreviewSurface as SharedWorkspaceFilePreviewSurface } from "@nextop-os/workspace-file-preview/react";
1794
-
1795
- // src/ui/internal/reference/IssueManagerReferencePickerTree.tsx
1796
- import { useEffect as useEffect4, useState as useState3 } from "react";
1797
- import {
1798
- ArrowRightIcon,
1799
- Button,
1800
- CheckIcon,
1801
- FileIcon,
1802
- FolderFilledIcon,
1803
- Input,
1804
- ScrollArea,
1805
- SearchIcon,
1806
- Spinner,
1807
- cn
1808
- } from "@nextop-os/ui-system";
1809
- import { AddIcon as AddLinedIcon } from "@nextop-os/ui-system/icons";
1810
- import { jsx, jsxs } from "react/jsx-runtime";
1811
- var issueManagerReferenceTreeIndent = 24;
1812
- var issueManagerReferenceTreeCollapseDurationMs = 200;
1813
- function IssueManagerReferencePickerBrowserPane({
1814
- browseRootEntries,
1815
- copy,
1816
- directoryStateByPath,
1817
- expandedFolderPaths,
1818
- focusedPath,
1819
- isLoading,
1820
- mode,
1821
- searchQuery,
1822
- selectedRefs,
1823
- setSearchQuery,
1824
- visibleEntries,
1825
- onFocusPath,
1826
- onToggleFolder,
1827
- onToggleRef
1828
- }) {
1829
- return /* @__PURE__ */ jsxs("section", { className: "flex min-h-0 flex-col border-b border-[var(--line-1)] lg:border-r lg:border-b-0", children: [
1830
- /* @__PURE__ */ jsx("div", { className: "border-b border-[var(--line-1)] p-3", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1831
- /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]" }),
1832
- /* @__PURE__ */ jsx(
1833
- Input,
1834
- {
1835
- className: "pl-9",
1836
- placeholder: copy.t("referencePicker.searchPlaceholder"),
1837
- value: searchQuery,
1838
- onChange: (event) => setSearchQuery(event.target.value)
1839
- }
1840
- )
1841
- ] }) }),
1842
- isLoading ? /* @__PURE__ */ jsx(IssueManagerReferencePickerFeedback, { children: /* @__PURE__ */ jsx(Spinner, { className: "text-[var(--text-secondary)]", size: 16 }) }) : visibleEntries.length === 0 ? /* @__PURE__ */ jsx(IssueManagerReferencePickerFeedback, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) : /* @__PURE__ */ jsx(ScrollArea, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-[2px] p-3", children: mode === "browse" ? /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: browseRootEntries.map((entry) => /* @__PURE__ */ jsx(
1843
- IssueManagerReferencePickerTreeEntry,
1844
- {
1845
- childDepth: 1,
1846
- copy,
1847
- directoryStateByPath,
1848
- entry,
1849
- expandedFolderPaths,
1850
- focusedPath,
1851
- selectedRefs,
1852
- onFocusPath,
1853
- onToggleFolder,
1854
- onToggleRef
1855
- },
1856
- entry.path
1857
- )) }) : visibleEntries.map((entry) => /* @__PURE__ */ jsx(
1858
- IssueManagerReferencePickerSearchEntry,
1859
- {
1860
- entry,
1861
- focused: focusedPath === entry.path,
1862
- selected: selectedRefs.some(
1863
- (item) => item.path === entry.path
1864
- ),
1865
- onFocusPath,
1866
- onToggleRef
1867
- },
1868
- entry.path
1869
- )) }) })
1870
- ] });
1871
- }
1872
- function IssueManagerReferencePickerTreeEntry({
1873
- childDepth,
1874
- copy,
1875
- directoryStateByPath,
1876
- entry,
1877
- expandedFolderPaths,
1878
- focusedPath,
1879
- selectedRefs,
1880
- onFocusPath,
1881
- onToggleFolder,
1882
- onToggleRef
1883
- }) {
1884
- const selected = selectedRefs.some((item) => item.path === entry.path);
1885
- const focused = focusedPath === entry.path;
1886
- const isFolder = entry.kind === "folder";
1887
- const folderKey = normalizeDirectoryPath(entry.path);
1888
- const expanded = expandedFolderPaths[folderKey] ?? false;
1889
- const childState = directoryStateByPath[folderKey];
1890
- const childEntries = childState?.entries ?? [];
1891
- const [shouldRenderChildContent, setShouldRenderChildContent] = useState3(expanded);
1892
- useEffect4(() => {
1893
- if (expanded) {
1894
- setShouldRenderChildContent(true);
1895
- return;
1896
- }
1897
- const timeoutId = window.setTimeout(() => {
1898
- setShouldRenderChildContent(false);
1899
- }, issueManagerReferenceTreeCollapseDurationMs);
1900
- return () => window.clearTimeout(timeoutId);
1901
- }, [expanded]);
1902
- const shouldBuildChildContent = expanded || shouldRenderChildContent;
1903
- const childContent = shouldBuildChildContent ? childState?.loading ? /* @__PURE__ */ jsxs(
1904
- "div",
1905
- {
1906
- className: "flex items-center gap-2 px-2 py-2 text-xs text-[var(--text-secondary)]",
1907
- style: {
1908
- paddingLeft: `${childDepth * issueManagerReferenceTreeIndent + 12}px`
1909
- },
1910
- children: [
1911
- /* @__PURE__ */ jsx(Spinner, { className: "text-[var(--text-secondary)]", size: 14 }),
1912
- /* @__PURE__ */ jsx("span", { children: copy.t("referencePicker.loading") })
1913
- ]
1914
- }
1915
- ) : childEntries.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: childEntries.map((childEntry) => /* @__PURE__ */ jsx(
1916
- IssueManagerReferencePickerTreeEntry,
1917
- {
1918
- childDepth: childDepth + 1,
1919
- copy,
1920
- directoryStateByPath,
1921
- entry: childEntry,
1922
- expandedFolderPaths,
1923
- focusedPath,
1924
- selectedRefs,
1925
- onFocusPath,
1926
- onToggleFolder,
1927
- onToggleRef
1928
- },
1929
- childEntry.path
1930
- )) }) : childState?.loaded ? /* @__PURE__ */ jsx(
1931
- "div",
1932
- {
1933
- className: "px-2 py-2 text-xs text-[var(--text-secondary)]",
1934
- style: {
1935
- paddingLeft: `${childDepth * issueManagerReferenceTreeIndent + 12}px`
1936
- },
1937
- children: copy.t("referencePicker.emptyDirectory")
1938
- }
1939
- ) : null : null;
1940
- return /* @__PURE__ */ jsxs("div", { children: [
1941
- /* @__PURE__ */ jsxs(
1942
- "div",
1943
- {
1944
- className: cn(
1945
- "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-[6px] py-1.5 pr-1 pl-2 transition-colors",
1946
- focused || selected ? "bg-transparency-block" : "hover:bg-transparency-block"
1947
- ),
1948
- style: {
1949
- paddingLeft: `${(childDepth - 1) * issueManagerReferenceTreeIndent + 8}px`
1950
- },
1951
- children: [
1952
- isFolder ? /* @__PURE__ */ jsx(
1953
- "button",
1954
- {
1955
- "aria-label": resolveIssueManagerReferenceLabel(entry),
1956
- className: "grid size-5 shrink-0 place-items-center rounded-sm text-[var(--text-secondary)] hover:bg-[var(--transparency-hover)]",
1957
- type: "button",
1958
- onClick: () => onToggleFolder(entry),
1959
- children: /* @__PURE__ */ jsx(
1960
- ArrowRightIcon,
1961
- {
1962
- className: cn(
1963
- "size-3.5 transition-transform",
1964
- expanded && "rotate-90"
1965
- )
1966
- }
1967
- )
1968
- }
1969
- ) : /* @__PURE__ */ jsx("span", { className: "block size-5 shrink-0" }),
1970
- /* @__PURE__ */ jsxs(
1971
- "button",
1972
- {
1973
- className: "flex min-w-0 items-center gap-2 text-left",
1974
- type: "button",
1975
- onClick: () => {
1976
- onFocusPath(entry.path);
1977
- if (entry.kind === "folder") {
1978
- onToggleFolder(entry);
1979
- }
1980
- },
1981
- children: [
1982
- isFolder ? /* @__PURE__ */ jsx(FolderFilledIcon, { className: "size-4 shrink-0 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx(FileIcon, { className: "size-4 shrink-0 text-[var(--text-tertiary)]" }),
1983
- /* @__PURE__ */ jsx("span", { className: "truncate text-sm text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(entry) })
1984
- ]
1985
- }
1986
- ),
1987
- /* @__PURE__ */ jsx(
1988
- Button,
1989
- {
1990
- "aria-label": resolveIssueManagerReferenceLabel(entry),
1991
- "aria-pressed": selected,
1992
- size: "icon-sm",
1993
- type: "button",
1994
- variant: "ghost",
1995
- onClick: () => {
1996
- onFocusPath(entry.path);
1997
- onToggleRef(entry);
1998
- },
1999
- children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(AddLinedIcon, { size: 16 })
2000
- }
2001
- )
2002
- ]
2003
- }
2004
- ),
2005
- isFolder ? /* @__PURE__ */ jsx(
2006
- "div",
2007
- {
2008
- className: cn(
2009
- "grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
2010
- expanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
2011
- childContent && "mt-[2px]"
2012
- ),
2013
- children: /* @__PURE__ */ jsx(
2014
- "div",
2015
- {
2016
- "aria-hidden": expanded ? void 0 : "true",
2017
- className: cn(
2018
- "min-h-0 overflow-hidden transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none",
2019
- expanded ? "translate-y-0 opacity-100" : "-translate-y-1 opacity-0"
2020
- ),
2021
- inert: expanded ? void 0 : true,
2022
- children: childContent
2023
- }
2024
- )
2025
- }
2026
- ) : null
2027
- ] });
2028
- }
2029
- function IssueManagerReferencePickerSearchEntry({
2030
- entry,
2031
- focused,
2032
- selected,
2033
- onFocusPath,
2034
- onToggleRef
2035
- }) {
2036
- const isFolder = entry.kind === "folder";
2037
- return /* @__PURE__ */ jsxs(
2038
- "div",
2039
- {
2040
- className: cn(
2041
- "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-[6px] border py-2.5 pr-1 pl-3 transition-colors",
2042
- focused || selected ? "border-border bg-transparency-block" : "border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block"
2043
- ),
2044
- children: [
2045
- /* @__PURE__ */ jsxs(
2046
- "button",
2047
- {
2048
- className: "flex min-w-0 items-center gap-3 text-left",
2049
- type: "button",
2050
- onClick: () => onFocusPath(entry.path),
2051
- children: [
2052
- /* @__PURE__ */ jsx("span", { className: "grid size-9 shrink-0 place-items-center rounded-lg bg-[var(--transparency-block)] text-[var(--text-tertiary)]", children: isFolder ? /* @__PURE__ */ jsx(FolderFilledIcon, { className: "size-4 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx(FileIcon, { className: "size-4 text-[var(--text-tertiary)]" }) }),
2053
- /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
2054
- /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(entry) }),
2055
- /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-[var(--text-secondary)]", children: entry.path })
2056
- ] })
2057
- ]
2058
- }
2059
- ),
2060
- /* @__PURE__ */ jsx(
2061
- Button,
2062
- {
2063
- "aria-label": resolveIssueManagerReferenceLabel(entry),
2064
- "aria-pressed": selected,
2065
- size: "icon-sm",
2066
- type: "button",
2067
- variant: "ghost",
2068
- onClick: () => {
2069
- onFocusPath(entry.path);
2070
- onToggleRef(entry);
2071
- },
2072
- children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(AddLinedIcon, { size: 16 })
2073
- }
2074
- )
2075
- ]
2076
- }
2077
- );
2078
- }
2079
- function IssueManagerReferencePickerFeedback({
2080
- children
2081
- }) {
2082
- return /* @__PURE__ */ jsx("div", { className: "grid min-h-0 flex-1 place-items-center px-4 text-center text-sm text-[var(--text-secondary)]", children });
2083
- }
2084
- function resolveIssueManagerReferenceLabel(ref) {
2085
- return ref.displayName || ref.path.split("/").filter(Boolean).at(-1) || ref.path;
2086
- }
2087
-
2088
- // src/ui/internal/reference/IssueManagerReferencePickerSections.tsx
2089
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2090
- var issueManagerReferencePickerSelectedBadgeClassName = "max-w-[14rem] rounded-[4px] border-transparent bg-[var(--transparency-block)] text-[var(--text-primary)]";
2091
- function IssueManagerReferencePickerPreviewPane({
2092
- copy,
2093
- focusedEntry,
2094
- mode,
2095
- previewState
2096
- }) {
2097
- return /* @__PURE__ */ jsx2("aside", { className: "flex shrink-0 flex-col border-t border-[var(--line-1)] bg-[var(--background-fronted)] 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: [
2098
- /* @__PURE__ */ jsx2(
2099
- IssueManagerReferencePreviewSurface,
2100
- {
2101
- copy,
2102
- focusedEntry,
2103
- previewState
2104
- }
2105
- ),
2106
- /* @__PURE__ */ jsx2("div", { className: "space-y-2 lg:space-y-3", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5", children: [
2107
- /* @__PURE__ */ jsx2("p", { className: "truncate text-[15px] font-semibold text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(focusedEntry) }),
2108
- /* @__PURE__ */ jsx2("p", { className: "line-clamp-3 text-sm text-[var(--text-secondary)] [overflow-wrap:anywhere]", children: focusedEntry.path })
2109
- ] }) })
2110
- ] }) : /* @__PURE__ */ jsx2(IssueManagerReferencePickerFeedback2, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) }) });
2111
- }
2112
- function IssueManagerReferencePreviewSurface({
2113
- copy,
2114
- focusedEntry,
2115
- previewState
2116
- }) {
2117
- return /* @__PURE__ */ jsx2(
2118
- SharedWorkspaceFilePreviewSurface,
2119
- {
2120
- directoryMessage: copy.t("referencePicker.previewFolder"),
2121
- emptyMessage: copy.t("referencePicker.previewUnavailable"),
2122
- frameClassName: "flex min-h-32 flex-col items-center justify-center overflow-hidden rounded-[8px] border border-[var(--line-2,var(--border-2))] bg-[var(--transparency-block)] px-5 py-8 text-center sm:min-h-40 sm:py-10 lg:min-h-56 lg:py-14",
2123
- imageAlt: resolveIssueManagerReferenceLabel,
2124
- imageFrameClassName: "p-4",
2125
- loadingIndicator: /* @__PURE__ */ jsx2("span", { className: "mx-auto grid size-11 place-items-center rounded-[6px] bg-[var(--transparency-block)]", children: /* @__PURE__ */ jsx2(LoadingIcon, { className: "size-4 animate-spin" }) }),
2126
- loadingMessage: copy.t("referencePicker.previewLoading"),
2127
- messageClassName: "mx-auto max-w-[24ch] text-sm leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]",
2128
- renderIcon: (entry) => entry.kind === "folder" ? /* @__PURE__ */ jsx2(FolderFilledIcon2, { className: "mx-auto size-9 text-[var(--rich-text-folder)]" }) : /* @__PURE__ */ jsx2(FileIcon2, { className: "mx-auto size-9 text-[var(--text-tertiary)]" }),
2129
- state: resolveIssueManagerReferenceSurfaceState(
2130
- copy,
2131
- focusedEntry,
2132
- previewState
2133
- ),
2134
- textClassName: "h-full overflow-auto p-4 text-left text-xs leading-5 whitespace-pre-wrap break-words text-[var(--text-primary)]",
2135
- textFrameClassName: "items-stretch justify-stretch"
2136
- }
2137
- );
2138
- }
2139
- function resolveIssueManagerReferenceSurfaceState(copy, focusedEntry, previewState) {
2140
- if (focusedEntry.kind === "folder") {
2141
- return {
2142
- entry: focusedEntry,
2143
- status: "directory"
2144
- };
2145
- }
2146
- if (!("reference" in previewState) || previewState.reference.path !== focusedEntry.path) {
2147
- return {
2148
- entry: focusedEntry,
2149
- message: focusedEntry.path,
2150
- status: "unsupported"
2151
- };
2152
- }
2153
- switch (previewState.status) {
2154
- case "loading":
2155
- case "image":
2156
- case "text":
2157
- return {
2158
- ...previewState,
2159
- entry: focusedEntry
2160
- };
2161
- case "readonly":
2162
- return {
2163
- entry: focusedEntry,
2164
- message: resolveIssueManagerReferencePreviewReadonlyMessage(
2165
- copy,
2166
- previewState
2167
- ),
2168
- status: "readonly"
2169
- };
2170
- case "error":
2171
- return {
2172
- entry: focusedEntry,
2173
- message: copy.t("referencePicker.previewError"),
2174
- status: "error"
2175
- };
2176
- case "unsupported":
2177
- return {
2178
- entry: focusedEntry,
2179
- message: copy.t("referencePicker.previewUnsupported"),
2180
- status: "unsupported"
2181
- };
2182
- case "unavailable":
2183
- return {
2184
- entry: focusedEntry,
2185
- message: copy.t("referencePicker.previewUnavailable"),
2186
- status: "unsupported"
2187
- };
2188
- case "directory":
2189
- return {
2190
- entry: focusedEntry,
2191
- status: "directory"
2192
- };
2193
- }
2194
- }
2195
- function resolveIssueManagerReferencePreviewReadonlyMessage(copy, previewState) {
2196
- switch (previewState.reason) {
2197
- case "binary":
2198
- return copy.t("referencePicker.previewBinary");
2199
- case "decode_failed":
2200
- return copy.t("referencePicker.previewDecodeFailed");
2201
- case "file_too_large":
2202
- return copy.t("referencePicker.previewFileTooLarge", {
2203
- maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)
2204
- });
2205
- case "text_too_large":
2206
- return copy.t("referencePicker.previewTextTooLarge", {
2207
- maxSize: formatWorkspacePreviewByteLimit(previewState.maxSizeBytes ?? 0)
2208
- });
2209
- }
2210
- }
2211
- function IssueManagerReferencePickerFooter({
2212
- copy,
2213
- onClose,
2214
- onConfirm,
2215
- selectedRefs
2216
- }) {
2217
- return /* @__PURE__ */ jsxs2("div", { className: "flex flex-col gap-3 border-t border-[var(--line-1)] px-4 py-4 sm:px-6 lg:flex-row lg:items-center lg:justify-between", children: [
2218
- /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:flex-1", children: [
2219
- /* @__PURE__ */ jsx2("span", { className: "text-sm text-[var(--text-secondary)]", children: copy.t("referencePicker.selectedCount", {
2220
- count: selectedRefs.length
2221
- }) }),
2222
- selectedRefs.slice(0, 2).map((ref) => /* @__PURE__ */ jsx2(
2223
- Badge,
2224
- {
2225
- className: issueManagerReferencePickerSelectedBadgeClassName,
2226
- variant: "secondary",
2227
- children: /* @__PURE__ */ jsx2("span", { className: "truncate", children: resolveIssueManagerReferenceLabel(ref) })
2228
- },
2229
- ref.path
2230
- )),
2231
- selectedRefs.length > 2 ? /* @__PURE__ */ jsxs2(
2232
- Badge,
2233
- {
2234
- className: issueManagerReferencePickerSelectedBadgeClassName,
2235
- variant: "secondary",
2236
- children: [
2237
- "+",
2238
- selectedRefs.length - 2
2239
- ]
2240
- }
2241
- ) : null
2242
- ] }),
2243
- /* @__PURE__ */ jsxs2("div", { className: "flex w-full items-center justify-end gap-2 lg:w-auto lg:shrink-0", children: [
2244
- /* @__PURE__ */ jsx2(Button2, { type: "button", variant: "secondary", onClick: onClose, children: copy.t("actions.cancel") }),
2245
- /* @__PURE__ */ jsx2(
2246
- Button2,
2247
- {
2248
- disabled: selectedRefs.length === 0,
2249
- type: "button",
2250
- onClick: onConfirm,
2251
- children: copy.t("referencePicker.confirm")
2252
- }
2253
- )
2254
- ] })
2255
- ] });
2256
- }
2257
- function IssueManagerReferencePickerFeedback2({
2258
- children
2259
- }) {
2260
- return /* @__PURE__ */ jsx2("div", { className: "grid min-h-0 flex-1 place-items-center px-4 text-center text-sm text-[var(--text-secondary)]", children });
2261
- }
2262
-
2263
- // src/ui/internal/reference/IssueManagerReferencePicker.tsx
2264
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2265
- var issueManagerReferencePickerBackdropMotionClassName = "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none";
2266
- var issueManagerReferencePickerPanelMotionClassName = "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-[0.96] motion-safe:duration-[250ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:animate-none";
2267
- function IssueManagerReferencePicker({
2268
- copy,
2269
- fileAdapter,
2270
- onClose,
2271
- onConfirm,
2272
- open,
2273
- workspaceId
2274
- }) {
2275
- const {
2276
- browseRootEntries,
2277
- directoryStateByPath,
2278
- expandedFolderPaths,
2279
- focusedEntry,
2280
- focusedPath,
2281
- isLoading,
2282
- mode,
2283
- previewState,
2284
- searchQuery,
2285
- selectedRefs,
2286
- visibleEntries,
2287
- setFocusedPath,
2288
- setSearchQuery,
2289
- toggleFolder,
2290
- toggleRef
2291
- } = useIssueManagerReferencePickerView({
2292
- fileAdapter,
2293
- onClose,
2294
- onConfirm,
2295
- open,
2296
- workspaceId
2297
- });
2298
- if (!open) {
2299
- return null;
2300
- }
2301
- const dialog = /* @__PURE__ */ jsx3(
2302
- "div",
2303
- {
2304
- className: cn2(
2305
- "fixed inset-0 grid place-items-center bg-[var(--backdrop)] px-3 py-4 backdrop-blur-md sm:px-6 sm:py-8",
2306
- issueManagerReferencePickerBackdropMotionClassName
2307
- ),
2308
- style: { zIndex: "var(--z-panel)" },
2309
- onClick: onClose,
2310
- children: /* @__PURE__ */ jsxs3(
2311
- Card,
2312
- {
2313
- "aria-modal": "true",
2314
- className: cn2(
2315
- "flex h-[min(88vh,44rem)] w-full max-w-5xl origin-center flex-col gap-0 overflow-hidden border-[var(--line-1)] bg-[var(--background-fronted)] py-0 text-[var(--text-primary)] shadow-panel sm:h-[min(82vh,44rem)]",
2316
- issueManagerReferencePickerPanelMotionClassName
2317
- ),
2318
- role: "dialog",
2319
- onClick: (event) => event.stopPropagation(),
2320
- children: [
2321
- /* @__PURE__ */ jsx3(CardHeader, { className: "border-b border-[var(--line-1)] px-4 py-4 sm:px-6 sm:py-5", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between gap-4", children: [
2322
- /* @__PURE__ */ jsx3("div", { className: "min-w-0", children: /* @__PURE__ */ jsx3(CardTitle, { children: copy.t("referencePicker.title") }) }),
2323
- /* @__PURE__ */ jsx3(
2324
- Button3,
2325
- {
2326
- "aria-label": copy.t("actions.cancel"),
2327
- size: "icon-sm",
2328
- type: "button",
2329
- variant: "ghost",
2330
- onClick: onClose,
2331
- children: /* @__PURE__ */ jsx3(CloseIcon, { size: 16 })
2332
- }
2333
- )
2334
- ] }) }),
2335
- /* @__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: [
2336
- /* @__PURE__ */ jsx3(
2337
- IssueManagerReferencePickerBrowserPane,
2338
- {
2339
- browseRootEntries,
2340
- copy,
2341
- directoryStateByPath,
2342
- expandedFolderPaths,
2343
- focusedPath,
2344
- isLoading,
2345
- mode,
2346
- searchQuery,
2347
- selectedRefs,
2348
- setSearchQuery,
2349
- visibleEntries,
2350
- onFocusPath: setFocusedPath,
2351
- onToggleFolder: toggleFolder,
2352
- onToggleRef: toggleRef
2353
- }
2354
- ),
2355
- /* @__PURE__ */ jsx3(
2356
- IssueManagerReferencePickerPreviewPane,
2357
- {
2358
- copy,
2359
- focusedEntry,
2360
- mode,
2361
- previewState
2362
- }
2363
- )
2364
- ] }),
2365
- /* @__PURE__ */ jsx3(
2366
- IssueManagerReferencePickerFooter,
2367
- {
2368
- copy,
2369
- onClose,
2370
- onConfirm: () => onConfirm(selectedRefs),
2371
- selectedRefs
2372
- }
2373
- )
2374
- ]
2375
- }
2376
- )
2377
- }
2378
- );
2379
- if (typeof document === "undefined") {
2380
- return dialog;
2381
- }
2382
- return createPortal(dialog, document.body);
2383
- }
2384
-
2385
- // src/ui/internal/shell/IssueManagerShell.tsx
2386
- import { Button as Button13, FileCreateIcon as FileCreateIcon4, cn as cn11 } from "@nextop-os/ui-system";
2387
-
2388
- // src/ui/internal/shell/IssueManagerPanels.tsx
2389
- import { useState as useState6 } from "react";
2390
- import { Badge as Badge3, Button as Button7, ConfirmationDialog, Input as Input2 } from "@nextop-os/ui-system";
2391
-
2392
- // src/ui/internal/issue/IssueManagerIssueSections.tsx
2393
- import {
2394
- Badge as Badge2,
2395
- Button as Button5,
2396
- FileCreateIcon as FileCreateIcon2,
2397
- ScrollArea as ScrollArea2,
2398
- cn as cn3
2399
- } from "@nextop-os/ui-system";
2400
-
2401
- // src/ui/internal/panel/IssueManagerPanelText.ts
2402
- function summarizeIssueManagerContent(content, fallback) {
2403
- const plainText = extractIssueManagerPlainTextFromContent(
2404
- content ?? ""
2405
- ).trim();
2406
- if (!plainText) {
2407
- return fallback;
2408
- }
2409
- if (plainText.length <= 120) {
2410
- return plainText;
2411
- }
2412
- return `${plainText.slice(0, 117)}...`;
2413
- }
2414
- function resolveTaskCreatorLabel(task) {
2415
- return resolveIssueManagerCreatorLabel(task);
2416
- }
2417
- function resolveIssueManagerCreatorLabel(entity) {
2418
- return entity.creatorDisplayName?.trim() || entity.creatorUserId;
2419
- }
2420
-
2421
- // src/ui/internal/panel/IssueManagerPanelSurface.tsx
2422
- import { Button as Button4, FileCreateIcon } from "@nextop-os/ui-system";
2423
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2424
- function IssueManagerPaneLoadingState() {
2425
- return /* @__PURE__ */ jsxs4(
2426
- "div",
2427
- {
2428
- "aria-hidden": "true",
2429
- className: "mx-auto flex w-full max-w-4xl flex-col gap-6",
2430
- children: [
2431
- /* @__PURE__ */ jsx4("div", { className: "h-6 w-28 rounded-full bg-muted" }),
2432
- /* @__PURE__ */ jsx4("div", { className: "h-12 w-2/3 rounded-full bg-muted" }),
2433
- /* @__PURE__ */ jsxs4("div", { className: "rounded-[28px] border border-border/70 bg-transparent px-5 py-5", children: [
2434
- /* @__PURE__ */ jsx4("div", { className: "h-4 w-24 rounded-full bg-muted" }),
2435
- /* @__PURE__ */ jsx4("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
2436
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
2437
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-10/12 rounded-full bg-muted" })
2438
- ] }),
2439
- /* @__PURE__ */ jsxs4("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-5 py-5", children: [
2440
- /* @__PURE__ */ jsx4("div", { className: "h-4 w-32 rounded-full bg-muted" }),
2441
- /* @__PURE__ */ jsx4("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
2442
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
2443
- ] })
2444
- ]
1657
+ if (!plainText) {
1658
+ return stripIssueManagerDescriptionTerminalPunctuation(fallback);
1659
+ }
1660
+ if (plainText.length <= 120) {
1661
+ return plainText;
1662
+ }
1663
+ return `${plainText.slice(0, 117)}...`;
1664
+ }
1665
+ function stripIssueManagerDescriptionTerminalPunctuation(value) {
1666
+ const trimmed = value.trim();
1667
+ if (!trimmed || trimmed.endsWith("...") || trimmed.endsWith("\u2026")) {
1668
+ return trimmed;
1669
+ }
1670
+ return trimmed.replace(/[。..]+$/u, "");
1671
+ }
1672
+ function resolveTaskCreatorLabel(task) {
1673
+ return resolveIssueManagerCreatorLabel(task);
1674
+ }
1675
+ function resolveIssueManagerCreatorLabel(entity) {
1676
+ return entity.creatorDisplayName?.trim() || entity.creatorUserId;
1677
+ }
1678
+
1679
+ // src/ui/internal/panel/IssueManagerPanelSurface.tsx
1680
+ import { Button, FileCreateIcon } from "@nextop-os/ui-system";
1681
+ import { jsx, jsxs } from "react/jsx-runtime";
1682
+ function IssueManagerPaneLoadingState() {
1683
+ return /* @__PURE__ */ jsxs(
1684
+ "div",
1685
+ {
1686
+ "aria-hidden": "true",
1687
+ className: "mx-auto flex w-full max-w-4xl flex-col gap-6",
1688
+ children: [
1689
+ /* @__PURE__ */ jsx("div", { className: "h-6 w-28 rounded-full bg-muted" }),
1690
+ /* @__PURE__ */ jsx("div", { className: "h-12 w-2/3 rounded-full bg-muted" }),
1691
+ /* @__PURE__ */ jsxs("div", { className: "rounded-[28px] border border-border/70 bg-transparent px-5 py-5", children: [
1692
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-24 rounded-full bg-muted" }),
1693
+ /* @__PURE__ */ jsx("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
1694
+ /* @__PURE__ */ jsx("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
1695
+ /* @__PURE__ */ jsx("div", { className: "mt-3 h-4 w-10/12 rounded-full bg-muted" })
1696
+ ] }),
1697
+ /* @__PURE__ */ jsxs("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-5 py-5", children: [
1698
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-32 rounded-full bg-muted" }),
1699
+ /* @__PURE__ */ jsx("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
1700
+ /* @__PURE__ */ jsx("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
1701
+ ] })
1702
+ ]
2445
1703
  }
2446
1704
  );
2447
1705
  }
2448
1706
  function IssueManagerTaskDrawerLoadingState() {
2449
- return /* @__PURE__ */ jsxs4("div", { "aria-hidden": "true", className: "grid gap-5", children: [
2450
- /* @__PURE__ */ jsx4("div", { className: "h-12 w-full rounded-2xl bg-muted" }),
2451
- /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-2 gap-3", children: [
2452
- /* @__PURE__ */ jsx4("div", { className: "h-10 rounded-xl bg-muted" }),
2453
- /* @__PURE__ */ jsx4("div", { className: "h-10 rounded-xl bg-muted" })
1707
+ return /* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: "grid gap-5", children: [
1708
+ /* @__PURE__ */ jsx("div", { className: "h-12 w-full rounded-2xl bg-muted" }),
1709
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
1710
+ /* @__PURE__ */ jsx("div", { className: "h-10 rounded-xl bg-muted" }),
1711
+ /* @__PURE__ */ jsx("div", { className: "h-10 rounded-xl bg-muted" })
2454
1712
  ] }),
2455
- /* @__PURE__ */ jsxs4("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-4 py-4", children: [
2456
- /* @__PURE__ */ jsx4("div", { className: "h-4 w-24 rounded-full bg-muted" }),
2457
- /* @__PURE__ */ jsx4("div", { className: "mt-4 h-4 w-full rounded-full bg-muted" }),
2458
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
2459
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
1713
+ /* @__PURE__ */ jsxs("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-4 py-4", children: [
1714
+ /* @__PURE__ */ jsx("div", { className: "h-4 w-24 rounded-full bg-muted" }),
1715
+ /* @__PURE__ */ jsx("div", { className: "mt-4 h-4 w-full rounded-full bg-muted" }),
1716
+ /* @__PURE__ */ jsx("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
1717
+ /* @__PURE__ */ jsx("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
2460
1718
  ] })
2461
1719
  ] });
2462
1720
  }
2463
1721
 
2464
1722
  // src/ui/internal/issue/IssueManagerIssueSections.tsx
2465
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1723
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2466
1724
  function IssueManagerDetailTextSection({
2467
1725
  body,
1726
+ isPlaceholder = false,
2468
1727
  label,
2469
1728
  meta,
2470
1729
  tone = "muted"
2471
1730
  }) {
2472
- return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
2473
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: label }),
2474
- /* @__PURE__ */ jsxs5("div", { className: "grid gap-1.5", children: [
2475
- /* @__PURE__ */ jsx5(
1731
+ return /* @__PURE__ */ jsxs2("section", { className: "grid gap-2.5", children: [
1732
+ /* @__PURE__ */ jsx2("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: label }),
1733
+ /* @__PURE__ */ jsxs2("div", { className: "rounded-[12px] border border-[var(--line-2)] px-4 py-3", children: [
1734
+ /* @__PURE__ */ jsx2(
2476
1735
  "p",
2477
1736
  {
2478
- className: cn3(
2479
- "text-sm font-normal leading-6",
2480
- tone === "destructive" ? "text-[var(--state-danger)]" : "text-[var(--text-secondary)]"
1737
+ className: cn(
1738
+ "truncate text-[14px] leading-5",
1739
+ isPlaceholder ? "font-normal text-[var(--text-secondary)]" : tone === "destructive" ? "font-semibold text-[var(--state-danger)]" : "font-semibold text-[var(--text-primary)]"
2481
1740
  ),
2482
- children: body
1741
+ children: stripIssueManagerDescriptionTerminalPunctuation(body)
2483
1742
  }
2484
1743
  ),
2485
- meta ? /* @__PURE__ */ jsx5("p", { className: "text-xs font-normal leading-5 text-[var(--text-secondary)]", children: meta }) : null
1744
+ meta ? /* @__PURE__ */ jsx2("p", { className: "mt-1 truncate text-xs font-normal text-[var(--text-secondary)]", children: stripIssueManagerDescriptionTerminalPunctuation(meta) }) : null
2486
1745
  ] })
2487
1746
  ] });
2488
1747
  }
@@ -2491,12 +1750,12 @@ function IssueManagerOutputSection({
2491
1750
  onOpen,
2492
1751
  outputs
2493
1752
  }) {
2494
- return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
2495
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: copy.t("labels.executionOutputs") }),
2496
- outputs.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-sm font-normal leading-6 text-[var(--text-secondary)]", children: copy.t("messages.noExecutionOutputs") }) : /* @__PURE__ */ jsx5("div", { className: "grid gap-2", children: outputs.map((output) => /* @__PURE__ */ jsxs5(
1753
+ return /* @__PURE__ */ jsxs2("section", { className: "grid gap-2.5", children: [
1754
+ /* @__PURE__ */ jsx2("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: copy.t("labels.executionOutputs") }),
1755
+ outputs.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "text-sm font-normal leading-6 text-[var(--text-secondary)]", children: copy.t("messages.noExecutionOutputs") }) : /* @__PURE__ */ jsx2("div", { className: "grid gap-2", children: outputs.map((output) => /* @__PURE__ */ jsxs2(
2497
1756
  "button",
2498
1757
  {
2499
- 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",
1758
+ className: "flex items-start justify-between gap-4 rounded-xl border border-border/65 px-4 py-3 text-left transition-colors hover:bg-transparency-hover",
2500
1759
  type: "button",
2501
1760
  onClick: () => {
2502
1761
  void onOpen({
@@ -2506,11 +1765,11 @@ function IssueManagerOutputSection({
2506
1765
  });
2507
1766
  },
2508
1767
  children: [
2509
- /* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1", children: [
2510
- /* @__PURE__ */ jsx5("span", { className: "block truncate text-sm font-semibold text-[var(--text-primary)]", children: output.displayName }),
2511
- /* @__PURE__ */ jsx5("span", { className: "mt-1 block truncate text-xs font-normal text-[var(--text-secondary)]", children: output.path })
1768
+ /* @__PURE__ */ jsxs2("span", { className: "min-w-0 flex-1", children: [
1769
+ /* @__PURE__ */ jsx2("span", { className: "block truncate text-sm font-semibold text-[var(--text-primary)]", children: output.displayName }),
1770
+ /* @__PURE__ */ jsx2("span", { className: "mt-1 block truncate text-xs font-normal text-[var(--text-secondary)]", children: output.path })
2512
1771
  ] }),
2513
- /* @__PURE__ */ jsx5("span", { className: "shrink-0 text-xs font-normal text-[var(--text-secondary)]", children: formatIssueManagerTimestamp(output.createdAtUnix) || "" })
1772
+ /* @__PURE__ */ jsx2("span", { className: "shrink-0 text-xs font-normal text-[var(--text-secondary)]", children: formatIssueManagerTimestamp(output.createdAtUnix) || "" })
2514
1773
  ]
2515
1774
  },
2516
1775
  output.outputId
@@ -2524,35 +1783,35 @@ function IssueManagerSubtaskSection({
2524
1783
  selectedTaskId,
2525
1784
  tasks
2526
1785
  }) {
2527
- return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
2528
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-3", children: [
2529
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: copy.t("labels.subtasks") }),
2530
- /* @__PURE__ */ jsxs5(Button5, { size: "dialog", type: "button", variant: "ghost", onClick: onCreate, children: [
2531
- /* @__PURE__ */ jsx5(FileCreateIcon2, { size: 14 }),
1786
+ return /* @__PURE__ */ jsxs2("section", { className: "grid gap-2.5", children: [
1787
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-3", children: [
1788
+ /* @__PURE__ */ jsx2("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: copy.t("labels.subtasks") }),
1789
+ /* @__PURE__ */ jsxs2(Button2, { size: "dialog", type: "button", variant: "ghost", onClick: onCreate, children: [
1790
+ /* @__PURE__ */ jsx2(FileCreateIcon2, { size: 14 }),
2532
1791
  copy.t("actions.add")
2533
1792
  ] })
2534
1793
  ] }),
2535
- tasks.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-sm font-normal leading-6 text-[var(--text-secondary)]", children: copy.t("messages.noSubtasksForIssue") }) : /* @__PURE__ */ jsx5("div", { className: "grid gap-2", children: tasks.map((task) => /* @__PURE__ */ jsxs5(
1794
+ tasks.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "text-sm font-normal leading-6 text-[var(--text-secondary)]", children: copy.t("messages.noSubtasksForIssue") }) : /* @__PURE__ */ jsx2("div", { className: "overflow-hidden rounded-lg border border-border/70 bg-transparent", children: tasks.map((task) => /* @__PURE__ */ jsxs2(
2536
1795
  "button",
2537
1796
  {
2538
- className: cn3(
2539
- "flex items-start justify-between gap-4 rounded-xl border px-4 py-3 text-left transition-colors",
2540
- selectedTaskId === task.taskId ? "border-border/90 bg-background-fronted" : "border-border/65 hover:bg-accent/18"
1797
+ className: cn(
1798
+ "flex w-full items-start justify-between gap-4 border-b border-border/70 px-4 py-3 text-left transition-colors last:border-b-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25 focus-visible:ring-inset",
1799
+ selectedTaskId === task.taskId ? "bg-transparency-actived" : "bg-transparent hover:bg-transparency-hover"
2541
1800
  ),
2542
1801
  type: "button",
2543
1802
  onClick: () => onSelectTask(task.taskId),
2544
1803
  children: [
2545
- /* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex-1", children: [
2546
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2.5", children: [
2547
- /* @__PURE__ */ jsx5("span", { className: "truncate text-sm font-semibold text-[var(--text-primary)]", children: task.title }),
2548
- /* @__PURE__ */ jsx5(Badge2, { className: "rounded-md px-2 py-1 text-[11px] font-medium", children: resolveIssueManagerStatusLabel(copy, task.status) })
1804
+ /* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
1805
+ /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 items-center gap-2.5", children: [
1806
+ /* @__PURE__ */ jsx2("span", { className: "truncate text-sm font-semibold text-[var(--text-primary)]", children: task.title }),
1807
+ /* @__PURE__ */ jsx2(Badge, { variant: issueManagerStatusBadgeVariant(task.status), children: resolveIssueManagerStatusLabel(copy, task.status) })
2549
1808
  ] }),
2550
- /* @__PURE__ */ jsx5("p", { className: "mt-2 line-clamp-2 text-sm font-normal leading-6 text-[var(--text-secondary)]", children: summarizeIssueManagerContent(
1809
+ /* @__PURE__ */ jsx2("p", { className: "mt-2 line-clamp-2 text-sm font-normal leading-6 text-[var(--text-secondary)]", children: summarizeIssueManagerContent(
2551
1810
  task.content,
2552
1811
  copy.t("messages.taskContentEmpty")
2553
1812
  ) })
2554
1813
  ] }),
2555
- /* @__PURE__ */ jsx5("span", { className: "shrink-0 text-xs font-normal text-[var(--text-secondary)]", children: formatIssueManagerTimestamp(
1814
+ /* @__PURE__ */ jsx2("span", { className: "shrink-0 text-xs font-normal text-[var(--text-secondary)]", children: formatIssueManagerTimestamp(
2556
1815
  task.createdAtUnix ?? task.updatedAtUnix
2557
1816
  ) || "" })
2558
1817
  ]
@@ -2563,10 +1822,10 @@ function IssueManagerSubtaskSection({
2563
1822
  }
2564
1823
 
2565
1824
  // src/ui/internal/content/IssueManagerDescriptionSection.tsx
2566
- import { useEffect as useEffect5, useRef, useState as useState4 } from "react";
1825
+ import { useEffect as useEffect3, useRef, useState as useState2 } from "react";
2567
1826
  import { RichTextReadonlyContent } from "@nextop-os/ui-rich-text/editor";
2568
- import { cn as cn4 } from "@nextop-os/ui-system";
2569
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1827
+ import { cn as cn2 } from "@nextop-os/ui-system";
1828
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2570
1829
  function IssueManagerDescriptionSection({
2571
1830
  content,
2572
1831
  emptyLabel,
@@ -2576,14 +1835,15 @@ function IssueManagerDescriptionSection({
2576
1835
  variant = "card"
2577
1836
  }) {
2578
1837
  const contentRef = useRef(null);
2579
- const [isOverflowing, setIsOverflowing] = useState4(false);
1838
+ const [isOverflowing, setIsOverflowing] = useState2(false);
2580
1839
  const normalizedContent = normalizeIssueManagerContent(content).trim();
2581
- useEffect5(() => {
1840
+ const displayContent = stripIssueManagerDescriptionTerminalPunctuation(normalizedContent);
1841
+ useEffect3(() => {
2582
1842
  if (variant === "plain") {
2583
1843
  setIsOverflowing(false);
2584
1844
  return;
2585
1845
  }
2586
- if (!normalizedContent) {
1846
+ if (!displayContent) {
2587
1847
  setIsOverflowing(false);
2588
1848
  return;
2589
1849
  }
@@ -2607,47 +1867,47 @@ function IssueManagerDescriptionSection({
2607
1867
  return () => {
2608
1868
  observer.disconnect();
2609
1869
  };
2610
- }, [normalizedContent, variant]);
1870
+ }, [displayContent, variant]);
2611
1871
  if (variant === "plain") {
2612
- return /* @__PURE__ */ jsxs6("section", { className: "grid gap-2", children: [
2613
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
2614
- normalizedContent ? /* @__PURE__ */ jsx6("div", { className: "max-w-3xl text-sm font-normal leading-5 text-[var(--text-secondary)]", children: /* @__PURE__ */ jsx6(
1872
+ return /* @__PURE__ */ jsxs3("section", { className: "grid gap-2", children: [
1873
+ /* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
1874
+ displayContent ? /* @__PURE__ */ jsx3("div", { className: "max-w-3xl text-sm font-normal leading-5 text-[var(--text-secondary)]", children: /* @__PURE__ */ jsx3(
2615
1875
  IssueManagerDescriptionContent,
2616
1876
  {
2617
- content: normalizedContent,
1877
+ content: displayContent,
2618
1878
  onOpen
2619
1879
  }
2620
- ) }) : /* @__PURE__ */ jsx6("p", { className: "text-sm font-normal leading-5 text-[var(--text-secondary)]", children: emptyLabel })
1880
+ ) }) : /* @__PURE__ */ jsx3("p", { className: "text-sm font-normal leading-5 text-[var(--text-secondary)]", children: emptyLabel })
2621
1881
  ] });
2622
1882
  }
2623
- return /* @__PURE__ */ jsxs6("section", { className: "grid gap-2", children: [
2624
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
2625
- /* @__PURE__ */ jsxs6(
1883
+ return /* @__PURE__ */ jsxs3("section", { className: "grid gap-2", children: [
1884
+ /* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
1885
+ /* @__PURE__ */ jsxs3(
2626
1886
  "div",
2627
1887
  {
2628
- className: cn4(
1888
+ className: cn2(
2629
1889
  "relative min-w-0 rounded-lg border border-border-1 bg-transparent px-4 py-3",
2630
1890
  minHeightClass
2631
1891
  ),
2632
1892
  children: [
2633
- /* @__PURE__ */ jsx6(
1893
+ /* @__PURE__ */ jsx3(
2634
1894
  "div",
2635
1895
  {
2636
- className: cn4(
1896
+ className: cn2(
2637
1897
  "max-h-[18rem] overflow-y-auto pr-2 text-sm font-normal leading-5 text-[var(--text-secondary)]",
2638
1898
  isOverflowing && "pb-8"
2639
1899
  ),
2640
1900
  ref: contentRef,
2641
- children: normalizedContent ? /* @__PURE__ */ jsx6(
1901
+ children: displayContent ? /* @__PURE__ */ jsx3(
2642
1902
  IssueManagerDescriptionContent,
2643
1903
  {
2644
- content: normalizedContent,
1904
+ content: displayContent,
2645
1905
  onOpen
2646
1906
  }
2647
- ) : /* @__PURE__ */ jsx6("p", { className: "font-normal text-[var(--text-secondary)]", children: emptyLabel })
1907
+ ) : /* @__PURE__ */ jsx3("p", { className: "font-normal text-[var(--text-secondary)]", children: emptyLabel })
2648
1908
  }
2649
1909
  ),
2650
- isOverflowing ? /* @__PURE__ */ jsx6(
1910
+ isOverflowing ? /* @__PURE__ */ jsx3(
2651
1911
  "div",
2652
1912
  {
2653
1913
  className: "pointer-events-none absolute right-0 bottom-1 left-0 h-10",
@@ -2665,7 +1925,7 @@ function IssueManagerDescriptionContent({
2665
1925
  content,
2666
1926
  onOpen
2667
1927
  }) {
2668
- return /* @__PURE__ */ jsx6(
1928
+ return /* @__PURE__ */ jsx3(
2669
1929
  RichTextReadonlyContent,
2670
1930
  {
2671
1931
  value: content,
@@ -2679,10 +1939,10 @@ function IssueManagerDescriptionContent({
2679
1939
  }
2680
1940
 
2681
1941
  // src/ui/internal/content/IssueManagerRichTextTextarea.tsx
2682
- import { useEffect as useEffect6, useMemo as useMemo4, useRef as useRef2, useState as useState5 } from "react";
1942
+ import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef2, useState as useState3 } from "react";
2683
1943
  import { RichTextAtEditor } from "@nextop-os/ui-rich-text/editor";
2684
- import { Button as Button6, LinkIcon, cn as cn5 } from "@nextop-os/ui-system";
2685
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1944
+ import { Button as Button3, LinkIcon, cn as cn3 } from "@nextop-os/ui-system";
1945
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
2686
1946
  var issueManagerRichTextTextareaBaseClassName = "min-h-20 w-full rounded-[8px] border border-transparent bg-[var(--transparency-block)] p-3 text-sm font-normal leading-[1.3] text-[var(--text-primary)] transition-[background-color,border-color,color] outline-none shadow-none placeholder:text-[var(--text-placeholder)] hover:bg-[var(--transparency-hover)] focus:bg-[var(--transparency-hover)] focus-visible:border-transparent focus-visible:bg-[var(--transparency-hover)] focus-visible:ring-0 disabled:cursor-not-allowed disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-disabled)] disabled:opacity-100 aria-invalid:border-[var(--state-danger)] aria-invalid:bg-[var(--transparency-block)] aria-invalid:hover:bg-[var(--transparency-hover)] aria-invalid:focus:bg-[var(--transparency-hover)] aria-invalid:focus-visible:bg-[var(--transparency-hover)] aria-invalid:ring-0 aria-invalid:shadow-none";
2687
1947
  var issueManagerRichTextPlaceholderBaseClassName = "min-h-20 w-full p-3 text-sm font-normal leading-[1.3] text-[var(--text-placeholder)]";
2688
1948
  function IssueManagerRichTextTextarea({
@@ -2693,15 +1953,15 @@ function IssueManagerRichTextTextarea({
2693
1953
  textareaClassName,
2694
1954
  value
2695
1955
  }) {
2696
- const providers = useMemo4(
1956
+ const providers = useMemo3(
2697
1957
  () => controller.resolveRichTextAtProviders(surface),
2698
1958
  [controller, surface]
2699
1959
  );
2700
1960
  const showReferenceAction = controller.canReferenceWorkspaceFiles;
2701
- const [focusSignal, setFocusSignal] = useState5(0);
1961
+ const [focusSignal, setFocusSignal] = useState3(0);
2702
1962
  const previousValueRef = useRef2(value);
2703
1963
  const wasAddingReferenceRef = useRef2(false);
2704
- useEffect6(() => {
1964
+ useEffect4(() => {
2705
1965
  const isAddingReference = controller.referenceTarget?.mode === "insert" && controller.referenceTarget.parentKind === surface;
2706
1966
  if (wasAddingReferenceRef.current && !isAddingReference && value !== previousValueRef.current) {
2707
1967
  setFocusSignal((current) => current + 1);
@@ -2709,7 +1969,7 @@ function IssueManagerRichTextTextarea({
2709
1969
  wasAddingReferenceRef.current = isAddingReference;
2710
1970
  previousValueRef.current = value;
2711
1971
  }, [controller.referenceTarget, surface, value]);
2712
- return /* @__PURE__ */ jsx7(
1972
+ return /* @__PURE__ */ jsx4(
2713
1973
  RichTextAtEditor,
2714
1974
  {
2715
1975
  focusSignal,
@@ -2721,12 +1981,12 @@ function IssueManagerRichTextTextarea({
2721
1981
  noMatchesLabel: controller.copy.t("richTextAt.noMatches"),
2722
1982
  removeReferenceActionLabel: controller.copy.t("actions.removeReference")
2723
1983
  },
2724
- textareaClassName: cn5(
1984
+ textareaClassName: cn3(
2725
1985
  issueManagerRichTextTextareaBaseClassName,
2726
1986
  textareaClassName,
2727
1987
  showReferenceAction && "pb-11"
2728
1988
  ),
2729
- placeholderClassName: cn5(
1989
+ placeholderClassName: cn3(
2730
1990
  issueManagerRichTextPlaceholderBaseClassName,
2731
1991
  textareaClassName,
2732
1992
  showReferenceAction && "pb-11"
@@ -2734,8 +1994,8 @@ function IssueManagerRichTextTextarea({
2734
1994
  placeholder,
2735
1995
  value,
2736
1996
  onChange,
2737
- overlay: showReferenceAction ? /* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute inset-x-3 bottom-3 z-10 flex", children: /* @__PURE__ */ jsxs7(
2738
- Button6,
1997
+ overlay: showReferenceAction ? /* @__PURE__ */ jsx4("div", { className: "pointer-events-none absolute inset-x-3 bottom-3 z-10 flex", children: /* @__PURE__ */ jsxs4(
1998
+ Button3,
2739
1999
  {
2740
2000
  className: "pointer-events-auto",
2741
2001
  size: "default",
@@ -2745,7 +2005,7 @@ function IssueManagerRichTextTextarea({
2745
2005
  void controller.insertReferences(surface);
2746
2006
  },
2747
2007
  children: [
2748
- /* @__PURE__ */ jsx7(LinkIcon, { size: 14 }),
2008
+ /* @__PURE__ */ jsx4(LinkIcon, { size: 14 }),
2749
2009
  controller.copy.t("actions.referenceWorkspaceFiles")
2750
2010
  ]
2751
2011
  }
@@ -2754,16 +2014,65 @@ function IssueManagerRichTextTextarea({
2754
2014
  );
2755
2015
  }
2756
2016
 
2017
+ // src/ui/internal/shell/IssueManagerDraftTitleInput.tsx
2018
+ import {
2019
+ useEffect as useEffect5,
2020
+ useState as useState4
2021
+ } from "react";
2022
+ import { Input } from "@nextop-os/ui-system";
2023
+ import { jsx as jsx5 } from "react/jsx-runtime";
2024
+ function IssueManagerDraftTitleInput({
2025
+ onChange,
2026
+ placeholder,
2027
+ value
2028
+ }) {
2029
+ const [localValue, setLocalValue] = useState4(value);
2030
+ const [isComposing, setIsComposing] = useState4(false);
2031
+ useEffect5(() => {
2032
+ if (!isComposing) {
2033
+ setLocalValue(value);
2034
+ }
2035
+ }, [isComposing, value]);
2036
+ const commitValue = (nextValue) => {
2037
+ setLocalValue(nextValue);
2038
+ onChange(nextValue);
2039
+ };
2040
+ return /* @__PURE__ */ jsx5(
2041
+ Input,
2042
+ {
2043
+ placeholder,
2044
+ variant: "md",
2045
+ value: localValue,
2046
+ onBlur: (event) => {
2047
+ commitValue(event.currentTarget.value);
2048
+ },
2049
+ onChange: (event) => {
2050
+ const nextValue = event.currentTarget.value;
2051
+ setLocalValue(nextValue);
2052
+ if (!isComposing) {
2053
+ onChange(nextValue);
2054
+ }
2055
+ },
2056
+ onCompositionEnd: (event) => {
2057
+ setIsComposing(false);
2058
+ commitValue(event.currentTarget.value);
2059
+ },
2060
+ onCompositionStart: () => {
2061
+ setIsComposing(true);
2062
+ }
2063
+ }
2064
+ );
2065
+ }
2066
+
2757
2067
  // src/ui/internal/shell/IssueManagerEditorMotion.ts
2758
2068
  var issueManagerEditorRiseInClassName = "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-bottom-3 motion-safe:duration-[240ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-safe:[animation-fill-mode:both] motion-reduce:animate-none";
2759
2069
  var issueManagerEditorRiseInDelay0ClassName = "motion-safe:[animation-delay:0ms]";
2760
2070
  var issueManagerEditorRiseInDelay1ClassName = "motion-safe:[animation-delay:55ms]";
2761
2071
  var issueManagerEditorRiseInDelay2ClassName = "motion-safe:[animation-delay:110ms]";
2762
- var issueManagerEditorRiseInDelay3ClassName = "motion-safe:[animation-delay:165ms]";
2763
2072
  var issueManagerEditorFooterFadeInClassName = "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)] motion-safe:[animation-delay:180ms] motion-safe:[animation-fill-mode:both] motion-reduce:animate-none";
2764
2073
 
2765
2074
  // src/ui/internal/shell/IssueManagerPanels.tsx
2766
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2075
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2767
2076
  function IssueManagerIssuePane({
2768
2077
  controller,
2769
2078
  selectedIssue,
@@ -2777,46 +2086,45 @@ function IssueManagerIssuePane({
2777
2086
  const tasks = controller.issueDetail.value?.tasks ?? [];
2778
2087
  const selectedTaskId = controller.nodeState.selectedTaskId;
2779
2088
  const selectedTask = selectedTaskId ? (controller.taskDetail.value?.task?.taskId === selectedTaskId ? controller.taskDetail.value.task : tasks.find((task) => task.taskId === selectedTaskId)) ?? null : null;
2780
- const latestRun = selectedTask ? controller.taskDetail.value?.latestRun ?? controller.taskDetail.value?.recentRuns[0] ?? null : null;
2781
- const latestOutputs = selectedTask ? controller.taskDetail.value?.latestOutputs ?? [] : [];
2782
- const [deleteDialogOpen, setDeleteDialogOpen] = useState6(false);
2783
- const [deleteBusy, setDeleteBusy] = useState6(false);
2089
+ const latestRun = selectedTask ? controller.taskDetail.value?.latestRun ?? controller.taskDetail.value?.recentRuns[0] ?? null : controller.issueDetail.value?.latestRun ?? controller.issueDetail.value?.recentRuns[0] ?? null;
2090
+ const latestOutputs = selectedTask ? controller.taskDetail.value?.latestOutputs ?? [] : controller.issueDetail.value?.latestOutputs ?? [];
2091
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState5(false);
2092
+ const [deleteBusy, setDeleteBusy] = useState5(false);
2784
2093
  if (isCreatingIssue || isEditingIssue) {
2785
- return /* @__PURE__ */ jsxs8("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
2786
- /* @__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: [
2787
- /* @__PURE__ */ jsx8(
2094
+ return /* @__PURE__ */ jsxs5("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
2095
+ /* @__PURE__ */ jsx6("div", { className: "flex min-h-0 flex-1 flex-col gap-[14px] overflow-y-auto px-7 py-8", children: /* @__PURE__ */ jsxs5("div", { className: "flex w-full min-w-0 flex-col gap-3", children: [
2096
+ /* @__PURE__ */ jsx6(
2788
2097
  "div",
2789
2098
  {
2790
2099
  className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay0ClassName}`,
2791
- children: /* @__PURE__ */ jsx8("h2", { className: "m-0 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: isCreatingIssue ? copy.t("actions.createIssue") : copy.t("actions.editIssue") })
2100
+ children: /* @__PURE__ */ jsx6("h2", { className: "m-0 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: isCreatingIssue ? copy.t("actions.createIssue") : copy.t("actions.editIssue") })
2792
2101
  }
2793
2102
  ),
2794
- /* @__PURE__ */ jsxs8("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
2795
- /* @__PURE__ */ jsxs8(
2103
+ /* @__PURE__ */ jsxs5("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
2104
+ /* @__PURE__ */ jsxs5(
2796
2105
  "label",
2797
2106
  {
2798
2107
  className: `flex w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
2799
2108
  children: [
2800
- /* @__PURE__ */ jsx8("span", { className: "leading-5", children: copy.t("labels.title") }),
2801
- /* @__PURE__ */ jsx8(
2802
- Input2,
2109
+ /* @__PURE__ */ jsx6("span", { className: "leading-5", children: copy.t("labels.title") }),
2110
+ /* @__PURE__ */ jsx6(
2111
+ IssueManagerDraftTitleInput,
2803
2112
  {
2804
2113
  placeholder: copy.t("composer.issueTitlePlaceholder"),
2805
- variant: "md",
2806
2114
  value: controller.issueDraft.title,
2807
- onChange: (event) => controller.setIssueTitle(event.target.value)
2115
+ onChange: controller.setIssueTitle
2808
2116
  }
2809
2117
  )
2810
2118
  ]
2811
2119
  }
2812
2120
  ),
2813
- /* @__PURE__ */ jsxs8(
2121
+ /* @__PURE__ */ jsxs5(
2814
2122
  "div",
2815
2123
  {
2816
2124
  className: `flex min-h-0 w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay2ClassName}`,
2817
2125
  children: [
2818
- /* @__PURE__ */ jsx8("span", { className: "leading-5", children: copy.t("labels.content") }),
2819
- /* @__PURE__ */ jsx8(
2126
+ /* @__PURE__ */ jsx6("span", { className: "leading-5", children: copy.t("labels.content") }),
2127
+ /* @__PURE__ */ jsx6(
2820
2128
  IssueManagerRichTextTextarea,
2821
2129
  {
2822
2130
  controller,
@@ -2832,13 +2140,13 @@ function IssueManagerIssuePane({
2832
2140
  )
2833
2141
  ] })
2834
2142
  ] }) }),
2835
- /* @__PURE__ */ jsx8(
2143
+ /* @__PURE__ */ jsx6(
2836
2144
  "div",
2837
2145
  {
2838
2146
  className: `shrink-0 border-t border-border-1 px-7 py-4 ${issueManagerEditorFooterFadeInClassName}`,
2839
- children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-end gap-3", children: [
2840
- /* @__PURE__ */ jsx8(
2841
- Button7,
2147
+ children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-end gap-3", children: [
2148
+ /* @__PURE__ */ jsx6(
2149
+ Button4,
2842
2150
  {
2843
2151
  size: "dialog",
2844
2152
  type: "button",
@@ -2847,8 +2155,8 @@ function IssueManagerIssuePane({
2847
2155
  children: copy.t("actions.cancel")
2848
2156
  }
2849
2157
  ),
2850
- /* @__PURE__ */ jsx8(
2851
- Button7,
2158
+ /* @__PURE__ */ jsx6(
2159
+ Button4,
2852
2160
  {
2853
2161
  disabled: isIssueTitleMissing,
2854
2162
  size: "dialog",
@@ -2863,63 +2171,69 @@ function IssueManagerIssuePane({
2863
2171
  ] });
2864
2172
  }
2865
2173
  if (!selectedIssue) {
2866
- return /* @__PURE__ */ jsx8("div", { className: "h-full min-h-0" });
2174
+ return /* @__PURE__ */ jsx6("div", { className: "h-full min-h-0" });
2867
2175
  }
2868
- 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: [
2869
- /* @__PURE__ */ jsxs8("header", { className: "flex items-start justify-between gap-6", children: [
2870
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
2871
- /* @__PURE__ */ jsx8("h2", { className: "line-clamp-2 text-base font-semibold leading-6 text-[var(--text-primary)]", children: selectedIssue.title }),
2872
- /* @__PURE__ */ jsxs8("div", { className: "mt-3 flex flex-wrap items-center gap-x-2 gap-y-2 text-sm font-normal text-[var(--text-secondary)]", children: [
2873
- /* @__PURE__ */ jsx8(Badge3, { variant: "secondary", children: resolveIssueManagerStatusLabel(copy, selectedIssue.status) }),
2874
- /* @__PURE__ */ jsx8(
2875
- "span",
2176
+ return /* @__PURE__ */ jsx6("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: /* @__PURE__ */ jsx6("div", { className: "min-h-0 flex-1 overflow-y-auto px-8 py-7", children: controller.issueDetail.isLoading && controller.issueDetail.value === null ? /* @__PURE__ */ jsx6(IssueManagerPaneLoadingState, {}) : /* @__PURE__ */ jsxs5("div", { className: "flex w-full min-w-0 flex-col gap-9", children: [
2177
+ /* @__PURE__ */ jsxs5("header", { className: "grid gap-3", children: [
2178
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-6", children: [
2179
+ /* @__PURE__ */ jsx6("h2", { className: "line-clamp-2 text-base font-semibold leading-6 text-[var(--text-primary)]", children: selectedIssue.title }),
2180
+ /* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-2", children: [
2181
+ /* @__PURE__ */ jsx6(
2182
+ Button4,
2876
2183
  {
2877
- "aria-hidden": "true",
2878
- className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
2184
+ type: "button",
2185
+ variant: "ghost",
2186
+ onClick: () => controller.setIssueEditorMode("edit"),
2187
+ children: copy.t("actions.edit")
2879
2188
  }
2880
2189
  ),
2881
- /* @__PURE__ */ jsxs8("span", { children: [
2882
- copy.t("labels.creator"),
2883
- " ",
2884
- resolveIssueManagerCreatorLabel(selectedIssue)
2885
- ] }),
2886
- /* @__PURE__ */ jsx8(
2887
- "span",
2190
+ /* @__PURE__ */ jsx6(
2191
+ Button4,
2888
2192
  {
2889
- "aria-hidden": "true",
2890
- className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
2193
+ className: "text-[var(--state-danger)] hover:bg-[var(--on-danger)] hover:text-[var(--state-danger)]",
2194
+ type: "button",
2195
+ variant: "ghost",
2196
+ onClick: () => setDeleteDialogOpen(true),
2197
+ children: copy.t("actions.delete")
2891
2198
  }
2892
- ),
2893
- /* @__PURE__ */ jsxs8("span", { children: [
2894
- copy.t("labels.createdAt"),
2895
- " ",
2896
- formatIssueManagerTimestamp(selectedIssue.createdAtUnix) || "-"
2897
- ] })
2199
+ )
2898
2200
  ] })
2899
2201
  ] }),
2900
- /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-center gap-2 pt-1", children: [
2901
- /* @__PURE__ */ jsx8(
2902
- Button7,
2202
+ /* @__PURE__ */ jsxs5("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-2 text-sm font-normal text-[var(--text-secondary)]", children: [
2203
+ /* @__PURE__ */ jsx6(
2204
+ Badge2,
2903
2205
  {
2904
- type: "button",
2905
- variant: "ghost",
2906
- onClick: () => controller.setIssueEditorMode("edit"),
2907
- children: copy.t("actions.edit")
2206
+ variant: issueManagerStatusBadgeVariant(selectedIssue.status),
2207
+ children: resolveIssueManagerStatusLabel(copy, selectedIssue.status)
2908
2208
  }
2909
2209
  ),
2910
- /* @__PURE__ */ jsx8(
2911
- Button7,
2210
+ /* @__PURE__ */ jsx6(
2211
+ "span",
2912
2212
  {
2913
- className: "text-[var(--state-danger)] hover:bg-[var(--on-danger)] hover:text-[var(--state-danger)]",
2914
- type: "button",
2915
- variant: "ghost",
2916
- onClick: () => setDeleteDialogOpen(true),
2917
- children: copy.t("actions.delete")
2213
+ "aria-hidden": "true",
2214
+ className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
2918
2215
  }
2919
- )
2216
+ ),
2217
+ /* @__PURE__ */ jsxs5("span", { children: [
2218
+ copy.t("labels.creator"),
2219
+ " ",
2220
+ resolveIssueManagerCreatorLabel(selectedIssue)
2221
+ ] }),
2222
+ /* @__PURE__ */ jsx6(
2223
+ "span",
2224
+ {
2225
+ "aria-hidden": "true",
2226
+ className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
2227
+ }
2228
+ ),
2229
+ /* @__PURE__ */ jsxs5("span", { children: [
2230
+ copy.t("labels.createdAt"),
2231
+ " ",
2232
+ formatIssueManagerTimestamp(selectedIssue.createdAtUnix) || "-"
2233
+ ] })
2920
2234
  ] })
2921
2235
  ] }),
2922
- /* @__PURE__ */ jsx8(
2236
+ /* @__PURE__ */ jsx6(
2923
2237
  ConfirmationDialog,
2924
2238
  {
2925
2239
  cancelLabel: copy.t("actions.cancel"),
@@ -2939,7 +2253,7 @@ function IssueManagerIssuePane({
2939
2253
  onOpenChange: setDeleteDialogOpen
2940
2254
  }
2941
2255
  ),
2942
- /* @__PURE__ */ jsx8(
2256
+ /* @__PURE__ */ jsx6(
2943
2257
  IssueManagerDescriptionSection,
2944
2258
  {
2945
2259
  content: issueContent,
@@ -2949,10 +2263,11 @@ function IssueManagerIssuePane({
2949
2263
  variant: "plain"
2950
2264
  }
2951
2265
  ),
2952
- /* @__PURE__ */ jsx8(
2266
+ /* @__PURE__ */ jsx6(
2953
2267
  IssueManagerDetailTextSection,
2954
2268
  {
2955
2269
  body: latestRun ? latestRun.summary?.trim() || resolveIssueManagerStatusLabel(copy, latestRun.status) : copy.t("messages.noExecutionStatus"),
2270
+ isPlaceholder: !latestRun,
2956
2271
  label: copy.t("labels.latestRunStatus"),
2957
2272
  meta: latestRun ? formatIssueManagerTimestamp(
2958
2273
  latestRun.updatedAtUnix ?? latestRun.createdAtUnix
@@ -2960,7 +2275,7 @@ function IssueManagerIssuePane({
2960
2275
  tone: latestRun?.status === "failed" ? "destructive" : "muted"
2961
2276
  }
2962
2277
  ),
2963
- /* @__PURE__ */ jsx8(
2278
+ /* @__PURE__ */ jsx6(
2964
2279
  IssueManagerOutputSection,
2965
2280
  {
2966
2281
  copy,
@@ -2968,7 +2283,7 @@ function IssueManagerIssuePane({
2968
2283
  onOpen: controller.openReference
2969
2284
  }
2970
2285
  ),
2971
- /* @__PURE__ */ jsx8(
2286
+ /* @__PURE__ */ jsx6(
2972
2287
  IssueManagerSubtaskSection,
2973
2288
  {
2974
2289
  copy,
@@ -2982,204 +2297,346 @@ function IssueManagerIssuePane({
2982
2297
  }
2983
2298
 
2984
2299
  // src/ui/internal/shell/IssueManagerBottomBar.tsx
2985
- import { Button as Button8, cn as cn7 } from "@nextop-os/ui-system";
2300
+ import { Button as Button6, cn as cn5 } from "@nextop-os/ui-system";
2986
2301
 
2987
2302
  // src/ui/internal/task/IssueManagerRunSections.tsx
2988
- import { useState as useState7 } from "react";
2989
- import {
2990
- Badge as Badge4,
2991
- Select,
2992
- SelectContent,
2993
- SelectItem,
2994
- SelectTrigger,
2995
- buttonVariants,
2996
- cn as cn6
2303
+ import { useEffect as useEffect6, useState as useState6 } from "react";
2304
+ import {
2305
+ Badge as Badge3,
2306
+ AgentSessionsIcon,
2307
+ Button as Button5,
2308
+ CheckIcon,
2309
+ ChevronDownIcon,
2310
+ DropdownMenu,
2311
+ DropdownMenuContent,
2312
+ DropdownMenuItem,
2313
+ DropdownMenuSeparator,
2314
+ DropdownMenuTrigger,
2315
+ FolderIcon,
2316
+ IssueIcon,
2317
+ LinkIcon as LinkIcon2,
2318
+ NoWorkspaceLinedIcon,
2319
+ cn as cn4
2997
2320
  } from "@nextop-os/ui-system";
2998
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2321
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2322
+ var executionDirectoryMenuItemClassName = "min-h-7 overflow-hidden rounded-md py-1 pr-7 pl-2.5 text-[13px] font-normal leading-[1.2] text-[var(--text-primary)]";
2323
+ var executionDirectoryMenuItemCheckClassName = "pointer-events-none absolute right-2 top-1/2 shrink-0 -translate-y-1/2";
2999
2324
  function IssueManagerRunActionTrigger({
3000
2325
  controller,
3001
2326
  disabled = false,
3002
- triggerClassName
2327
+ triggerClassName,
2328
+ triggerVariant = "default"
3003
2329
  }) {
3004
- const [resetToken, setResetToken] = useState7(0);
3005
- return /* @__PURE__ */ jsxs9(
3006
- Select,
2330
+ return /* @__PURE__ */ jsxs6(
2331
+ Button5,
3007
2332
  {
2333
+ className: cn4("min-w-0", triggerClassName),
3008
2334
  disabled: controller.isRunningTask || disabled,
3009
- onValueChange: (provider) => {
3010
- setResetToken((current) => current + 1);
3011
- void controller.runTask(provider);
2335
+ size: triggerVariant === "button" ? "dialog" : "default",
2336
+ type: "button",
2337
+ onClick: () => {
2338
+ void controller.runTask();
3012
2339
  },
3013
2340
  children: [
3014
- /* @__PURE__ */ jsx9(
3015
- SelectTrigger,
3016
- {
3017
- "aria-label": controller.copy.t("actions.askAgentToRun"),
3018
- className: cn6(
3019
- buttonVariants({ variant: "secondary", size: "dialog" }),
3020
- "[&>svg]:hidden",
3021
- triggerClassName
3022
- ),
3023
- children: /* @__PURE__ */ jsx9("span", { className: "flex min-w-0 flex-1 items-center gap-2", children: /* @__PURE__ */ jsx9("span", { className: "truncate", children: controller.copy.t("actions.askAgentToRun") }) })
3024
- }
3025
- ),
3026
- /* @__PURE__ */ jsx9(SelectContent, { style: { zIndex: "var(--z-panel-popover)" }, children: controller.providerOptions.map((provider) => /* @__PURE__ */ jsx9(SelectItem, { value: provider, children: provider }, provider)) })
2341
+ /* @__PURE__ */ jsx7(AgentSessionsIcon, { size: 16 }),
2342
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: controller.copy.t("actions.askAgentToRun") })
3027
2343
  ]
3028
- },
3029
- `${controller.nodeState.selectedAgentProvider}:${resetToken}`
2344
+ }
3030
2345
  );
3031
2346
  }
3032
- function IssueManagerRunPanels({
3033
- copy,
3034
- onOpen,
3035
- outputs,
3036
- recentRuns
2347
+ function IssueManagerBreakdownActionTrigger({
2348
+ controller,
2349
+ disabled = false,
2350
+ triggerClassName,
2351
+ triggerVariant = "default"
3037
2352
  }) {
3038
- return /* @__PURE__ */ jsxs9("div", { className: "grid gap-4", children: [
3039
- /* @__PURE__ */ jsxs9("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
3040
- /* @__PURE__ */ jsx9("h4", { className: "mb-3 text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.recentRuns") }),
3041
- recentRuns.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "text-sm leading-5 text-[var(--text-secondary)]", children: copy.t("messages.noRecentRuns") }) : /* @__PURE__ */ jsx9("div", { className: "grid gap-2.5", children: recentRuns.map((run) => /* @__PURE__ */ jsxs9(
3042
- "div",
3043
- {
3044
- className: "rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3",
3045
- children: [
3046
- /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-3", children: [
3047
- /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
3048
- /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: run.summary || run.runId }),
3049
- /* @__PURE__ */ jsx9("p", { className: "mt-1 text-xs leading-[1.55] text-[var(--text-secondary)]", children: formatIssueManagerTimestamp(
3050
- run.updatedAtUnix ?? run.createdAtUnix
3051
- ) })
3052
- ] }),
3053
- /* @__PURE__ */ jsx9(Badge4, { className: "rounded-full border-transparent bg-transparency-block px-2.5 py-1 text-xs text-[var(--text-secondary)]", children: resolveIssueManagerStatusLabel(copy, run.status) })
3054
- ] }),
3055
- run.errorMessage ? /* @__PURE__ */ jsx9("p", { className: "mt-2 text-xs text-[var(--state-danger)]", children: run.errorMessage }) : null
3056
- ]
3057
- },
3058
- run.runId
3059
- )) })
3060
- ] }),
3061
- /* @__PURE__ */ jsxs9("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
3062
- /* @__PURE__ */ jsx9("h4", { className: "mb-3 text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.outputs") }),
3063
- outputs.length === 0 ? /* @__PURE__ */ jsx9("p", { className: "text-sm leading-5 text-[var(--text-secondary)]", children: copy.t("messages.noOutputs") }) : /* @__PURE__ */ jsx9("div", { className: "grid gap-2.5", children: outputs.map((output) => /* @__PURE__ */ jsxs9(
3064
- "button",
3065
- {
3066
- className: "rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3 text-left transition-colors hover:bg-transparency-hover",
3067
- type: "button",
3068
- onClick: () => {
3069
- void onOpen({
3070
- displayName: output.displayName,
3071
- kind: "file",
3072
- path: output.path
3073
- });
3074
- },
3075
- children: [
3076
- /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: output.displayName }),
3077
- /* @__PURE__ */ jsx9("p", { className: "mt-1 truncate text-xs leading-[1.55] text-[var(--text-secondary)]", children: output.path })
3078
- ]
3079
- },
3080
- output.outputId
3081
- )) })
3082
- ] })
2353
+ return /* @__PURE__ */ jsxs6(
2354
+ Button5,
2355
+ {
2356
+ className: cn4("min-w-0", triggerClassName),
2357
+ disabled,
2358
+ size: triggerVariant === "button" ? "dialog" : "default",
2359
+ type: "button",
2360
+ variant: "secondary",
2361
+ onClick: () => {
2362
+ void controller.startTaskBreakdown();
2363
+ },
2364
+ children: [
2365
+ /* @__PURE__ */ jsx7(IssueIcon, { size: 16 }),
2366
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: controller.copy.t("actions.askAgentToBreakdown") })
2367
+ ]
2368
+ }
2369
+ );
2370
+ }
2371
+ function IssueManagerExecutionDirectoryTrigger({
2372
+ className,
2373
+ controller,
2374
+ disabled = false
2375
+ }) {
2376
+ const [projects, setProjects] = useState6([]);
2377
+ const [isLoading, setIsLoading] = useState6(false);
2378
+ const selectedPath = controller.nodeState.selectedExecutionDirectory?.trim() ?? "";
2379
+ const selectedProject = projects.find((project) => project.path === selectedPath) ?? null;
2380
+ const triggerLabel = selectedProject ? selectedProject.label : selectedPath ? controller.copy.t("labels.customExecutionDirectory") : controller.copy.t("labels.noProject");
2381
+ useEffect6(() => {
2382
+ let canceled = false;
2383
+ setIsLoading(true);
2384
+ void controller.listExecutionDirectoryProjects().then((response) => {
2385
+ if (!canceled) {
2386
+ setProjects(response.projects);
2387
+ }
2388
+ }).catch(() => {
2389
+ if (!canceled) {
2390
+ setProjects([]);
2391
+ }
2392
+ }).finally(() => {
2393
+ if (!canceled) {
2394
+ setIsLoading(false);
2395
+ }
2396
+ });
2397
+ return () => {
2398
+ canceled = true;
2399
+ };
2400
+ }, [controller.workspaceId]);
2401
+ const refreshProjects = () => {
2402
+ void controller.listExecutionDirectoryProjects().then((response) => setProjects(response.projects)).catch(() => setProjects([]));
2403
+ };
2404
+ if (!controller.canSelectExecutionDirectory) {
2405
+ return null;
2406
+ }
2407
+ return /* @__PURE__ */ jsxs6(DropdownMenu, { children: [
2408
+ /* @__PURE__ */ jsx7(DropdownMenuTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs6(
2409
+ "button",
2410
+ {
2411
+ "aria-label": controller.copy.t("actions.selectExecutionDirectory"),
2412
+ className: cn4(
2413
+ "group inline-flex min-h-7 max-w-[240px] min-w-0 items-center gap-1.5 overflow-hidden rounded-md border-0 bg-transparent px-0.5 py-0 text-[13px] font-normal leading-[1.2] text-[var(--text-secondary)] shadow-none outline-none hover:bg-transparent hover:text-[var(--text-primary)] focus:bg-transparent focus:text-[var(--text-primary)] focus-visible:bg-transparent focus-visible:ring-0 disabled:bg-transparent disabled:text-[var(--text-disabled)]",
2414
+ className
2415
+ ),
2416
+ disabled,
2417
+ type: "button",
2418
+ children: [
2419
+ selectedPath ? /* @__PURE__ */ jsx7(FolderIcon, { className: "shrink-0", size: 15 }) : /* @__PURE__ */ jsx7(NoWorkspaceLinedIcon, { className: "shrink-0", size: 15 }),
2420
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 truncate text-left font-normal", children: triggerLabel }),
2421
+ /* @__PURE__ */ jsx7(
2422
+ ChevronDownIcon,
2423
+ {
2424
+ className: "shrink-0 text-[var(--text-secondary)] transition-transform group-data-[state=open]:rotate-180",
2425
+ size: 14
2426
+ }
2427
+ )
2428
+ ]
2429
+ }
2430
+ ) }),
2431
+ /* @__PURE__ */ jsxs6(
2432
+ DropdownMenuContent,
2433
+ {
2434
+ align: "end",
2435
+ className: "w-[240px] min-w-[240px]",
2436
+ style: { zIndex: "var(--z-panel-popover)" },
2437
+ children: [
2438
+ selectedPath && !selectedProject ? /* @__PURE__ */ jsx7(
2439
+ DropdownMenuItem,
2440
+ {
2441
+ className: executionDirectoryMenuItemClassName,
2442
+ onSelect: () => {
2443
+ void controller.useExecutionDirectory(selectedPath).then(refreshProjects);
2444
+ },
2445
+ children: /* @__PURE__ */ jsxs6("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
2446
+ /* @__PURE__ */ jsx7(FolderIcon, { "aria-hidden": true, size: 15 }),
2447
+ /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
2448
+ /* @__PURE__ */ jsx7("span", { children: controller.copy.t("labels.customExecutionDirectory") }),
2449
+ /* @__PURE__ */ jsxs6("span", { className: "text-[var(--text-secondary)]", children: [
2450
+ " ",
2451
+ "/ ",
2452
+ selectedPath
2453
+ ] })
2454
+ ] }),
2455
+ /* @__PURE__ */ jsx7(
2456
+ CheckIcon,
2457
+ {
2458
+ className: executionDirectoryMenuItemCheckClassName,
2459
+ size: 15
2460
+ }
2461
+ )
2462
+ ] })
2463
+ }
2464
+ ) : null,
2465
+ projects.map((project) => /* @__PURE__ */ jsx7(
2466
+ DropdownMenuItem,
2467
+ {
2468
+ className: executionDirectoryMenuItemClassName,
2469
+ onSelect: () => {
2470
+ void controller.useExecutionDirectory(project.path).then(refreshProjects);
2471
+ },
2472
+ children: /* @__PURE__ */ jsxs6("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
2473
+ /* @__PURE__ */ jsx7(FolderIcon, { "aria-hidden": true, size: 15 }),
2474
+ /* @__PURE__ */ jsxs6("span", { className: "min-w-0 flex-1 truncate", children: [
2475
+ /* @__PURE__ */ jsx7("span", { children: project.label }),
2476
+ /* @__PURE__ */ jsxs6("span", { className: "text-[var(--text-secondary)]", children: [
2477
+ " ",
2478
+ "/ ",
2479
+ project.path
2480
+ ] })
2481
+ ] }),
2482
+ project.path === selectedPath ? /* @__PURE__ */ jsx7(
2483
+ CheckIcon,
2484
+ {
2485
+ className: executionDirectoryMenuItemCheckClassName,
2486
+ size: 15
2487
+ }
2488
+ ) : null
2489
+ ] })
2490
+ },
2491
+ project.id || project.path
2492
+ )),
2493
+ isLoading ? /* @__PURE__ */ jsx7(
2494
+ DropdownMenuItem,
2495
+ {
2496
+ className: executionDirectoryMenuItemClassName,
2497
+ disabled: true,
2498
+ children: controller.copy.t("labels.loadingExecutionDirectories")
2499
+ }
2500
+ ) : null,
2501
+ projects.length > 0 || selectedPath || isLoading ? /* @__PURE__ */ jsx7(DropdownMenuSeparator, {}) : null,
2502
+ /* @__PURE__ */ jsx7(
2503
+ DropdownMenuItem,
2504
+ {
2505
+ className: executionDirectoryMenuItemClassName,
2506
+ onSelect: () => {
2507
+ void controller.selectExecutionDirectory().then(refreshProjects);
2508
+ },
2509
+ children: /* @__PURE__ */ jsxs6("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
2510
+ /* @__PURE__ */ jsx7(LinkIcon2, { "aria-hidden": true, size: 15 }),
2511
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: controller.copy.t("actions.linkExistingExecutionDirectory") })
2512
+ ] })
2513
+ }
2514
+ ),
2515
+ /* @__PURE__ */ jsx7(
2516
+ DropdownMenuItem,
2517
+ {
2518
+ className: executionDirectoryMenuItemClassName,
2519
+ onSelect: () => {
2520
+ void controller.useExecutionDirectory(null).then(refreshProjects);
2521
+ },
2522
+ children: /* @__PURE__ */ jsxs6("span", { className: "flex min-w-0 flex-1 items-center gap-2 pr-1", children: [
2523
+ /* @__PURE__ */ jsx7(NoWorkspaceLinedIcon, { "aria-hidden": true, size: 15 }),
2524
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: controller.copy.t("labels.noProject") }),
2525
+ !selectedPath ? /* @__PURE__ */ jsx7(
2526
+ CheckIcon,
2527
+ {
2528
+ className: executionDirectoryMenuItemCheckClassName,
2529
+ size: 15
2530
+ }
2531
+ ) : null
2532
+ ] })
2533
+ }
2534
+ )
2535
+ ]
2536
+ }
2537
+ )
3083
2538
  ] });
3084
2539
  }
3085
2540
 
3086
2541
  // src/ui/internal/shell/IssueManagerBottomBar.tsx
3087
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2542
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
3088
2543
  function IssueManagerBottomBar({
3089
2544
  controller,
3090
2545
  isNarrowLayout,
3091
2546
  selectedIssue,
3092
- selectedTask,
3093
2547
  visible
3094
2548
  }) {
3095
2549
  const copy = controller.copy;
3096
2550
  if (!visible || !selectedIssue) {
3097
2551
  return null;
3098
2552
  }
3099
- return /* @__PURE__ */ jsx10("div", { className: "border-t border-[var(--border-1)] bg-transparent px-6 py-4 backdrop-blur", children: /* @__PURE__ */ jsxs10(
2553
+ return /* @__PURE__ */ jsx8("div", { className: "border-t border-[var(--border-1)] bg-transparent px-6 py-4 backdrop-blur", children: /* @__PURE__ */ jsxs7(
3100
2554
  "div",
3101
2555
  {
3102
- className: cn7(
2556
+ className: cn5(
3103
2557
  "flex gap-3",
3104
2558
  isNarrowLayout ? "flex-wrap items-center justify-end" : "items-center justify-end"
3105
2559
  ),
3106
2560
  children: [
3107
- /* @__PURE__ */ jsx10(
3108
- IssueManagerRunActionTrigger,
2561
+ /* @__PURE__ */ jsx8(
2562
+ IssueManagerExecutionDirectoryTrigger,
3109
2563
  {
2564
+ className: "mr-auto min-w-0 max-w-[240px] justify-start overflow-hidden",
3110
2565
  controller,
3111
- disabled: !selectedTask
2566
+ disabled: controller.isRunningTask
3112
2567
  }
3113
2568
  ),
3114
- controller.canInviteCollaborators ? /* @__PURE__ */ jsx10(
3115
- Button8,
3116
- {
3117
- className: "px-4",
3118
- disabled: !selectedIssue,
3119
- size: "dialog",
3120
- type: "button",
3121
- onClick: () => {
3122
- void controller.shareSelection();
3123
- },
3124
- children: copy.t("actions.inviteCollaborator")
3125
- }
3126
- ) : null
2569
+ /* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 flex-nowrap items-center justify-end gap-3", children: [
2570
+ /* @__PURE__ */ jsx8(
2571
+ IssueManagerBreakdownActionTrigger,
2572
+ {
2573
+ controller,
2574
+ disabled: !selectedIssue,
2575
+ triggerVariant: "button"
2576
+ }
2577
+ ),
2578
+ /* @__PURE__ */ jsx8(
2579
+ IssueManagerRunActionTrigger,
2580
+ {
2581
+ controller,
2582
+ disabled: !selectedIssue,
2583
+ triggerVariant: "button"
2584
+ }
2585
+ ),
2586
+ controller.canInviteCollaborators ? /* @__PURE__ */ jsx8(
2587
+ Button6,
2588
+ {
2589
+ className: "px-4",
2590
+ disabled: !selectedIssue,
2591
+ size: "dialog",
2592
+ type: "button",
2593
+ onClick: () => {
2594
+ void controller.shareSelection();
2595
+ },
2596
+ children: copy.t("actions.inviteCollaborator")
2597
+ }
2598
+ ) : null
2599
+ ] })
3127
2600
  ]
3128
2601
  }
3129
2602
  ) });
3130
2603
  }
3131
2604
 
3132
2605
  // src/ui/internal/shell/IssueManagerFloatingNotice.tsx
3133
- import {
3134
- FailedFilledIcon,
3135
- Spinner as Spinner2,
3136
- toastVariants,
3137
- cn as cn8
3138
- } from "@nextop-os/ui-system";
3139
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
2606
+ import { ToastProvider, ToastRoot, ToastTitle } from "@nextop-os/ui-system";
2607
+ import { jsx as jsx9 } from "react/jsx-runtime";
3140
2608
  function IssueManagerFloatingNotice({
3141
2609
  notice
3142
2610
  }) {
3143
2611
  const variant = notice.tone === "destructive" ? "destructive" : "default";
3144
- 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(
3145
- "div",
2612
+ return /* @__PURE__ */ jsx9(ToastProvider, { children: /* @__PURE__ */ jsx9(
2613
+ ToastRoot,
3146
2614
  {
3147
- "aria-busy": notice.isLoading,
3148
- "aria-live": variant === "destructive" ? "assertive" : "polite",
3149
- className: cn8(
3150
- toastVariants({ variant }),
3151
- "w-fit max-w-[min(72vw,40rem)] px-4 py-3 shadow-lg"
3152
- ),
3153
- role: variant === "destructive" ? "alert" : "status",
3154
- 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: [
3155
- notice.isLoading ? /* @__PURE__ */ jsx11(
3156
- Spinner2,
3157
- {
3158
- className: "shrink-0 text-current",
3159
- size: 16,
3160
- strokeWidth: 3,
3161
- trackColor: "color-mix(in srgb, currentColor 28%, transparent)"
3162
- }
3163
- ) : notice.tone === "destructive" ? /* @__PURE__ */ jsx11(FailedFilledIcon, { className: "size-4 shrink-0 text-current" }) : null,
3164
- /* @__PURE__ */ jsx11("span", { className: "min-w-0 max-w-full truncate whitespace-nowrap", children: notice.title })
3165
- ] })
3166
- }
2615
+ open: true,
2616
+ anchor: "node",
2617
+ busy: notice.isLoading,
2618
+ className: "z-30 w-fit max-w-[min(72vw,40rem)] px-4 py-3 shadow-lg",
2619
+ nodeInsetTopPx: 16,
2620
+ variant,
2621
+ children: /* @__PURE__ */ jsx9(ToastTitle, { className: "whitespace-nowrap", children: notice.title })
2622
+ },
2623
+ notice.id
3167
2624
  ) });
3168
2625
  }
3169
2626
 
3170
2627
  // src/ui/internal/shell/IssueManagerSidebar.tsx
3171
- import { cn as cn10 } from "@nextop-os/ui-system";
2628
+ import { cn as cn7 } from "@nextop-os/ui-system";
3172
2629
 
3173
2630
  // src/ui/internal/shell/IssueManagerSidebarSections.tsx
3174
2631
  import {
3175
- Badge as Badge5,
3176
- Button as Button9,
3177
- CloseIcon as CloseIcon2,
2632
+ Badge as Badge4,
2633
+ Button as Button7,
2634
+ CloseIcon,
3178
2635
  FileCreateIcon as FileCreateIcon3,
3179
- Input as Input3,
3180
- ScrollArea as ScrollArea3,
2636
+ Input as Input2,
2637
+ ScrollArea as ScrollArea2,
3181
2638
  UnderlineTabs,
3182
- cn as cn9
2639
+ cn as cn6
3183
2640
  } from "@nextop-os/ui-system";
3184
2641
 
3185
2642
  // src/ui/internal/shell/IssueManagerShellState.ts
@@ -3256,20 +2713,20 @@ function resolveIssueManagerShellContentViewState(input) {
3256
2713
  isIssueEditing,
3257
2714
  isTaskCreating,
3258
2715
  isTaskDrawerOpen,
3259
- showBottomBar: input.selectedIssue !== null && input.issueEditorMode === "read" && input.taskEditorMode === "read"
2716
+ showBottomBar: input.selectedIssue !== null && input.issueEditorMode === "read" && input.taskEditorMode !== "create"
3260
2717
  };
3261
2718
  }
3262
2719
 
3263
2720
  // src/ui/internal/shell/IssueManagerSidebarSections.tsx
3264
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2721
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
3265
2722
  function IssueManagerSidebarHeader({
3266
2723
  copy,
3267
2724
  issueSearchQuery,
3268
2725
  onCreateIssue,
3269
2726
  onIssueSearchQueryChange
3270
2727
  }) {
3271
- return /* @__PURE__ */ jsx12("div", { className: "px-4 py-4", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2.5", children: [
3272
- /* @__PURE__ */ jsx12(
2728
+ return /* @__PURE__ */ jsx10("div", { className: "px-4 py-4", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2.5", children: [
2729
+ /* @__PURE__ */ jsx10(
3273
2730
  IssueManagerSearchField,
3274
2731
  {
3275
2732
  clearLabel: copy.t("actions.clearSearch"),
@@ -3278,8 +2735,8 @@ function IssueManagerSidebarHeader({
3278
2735
  onChange: onIssueSearchQueryChange
3279
2736
  }
3280
2737
  ),
3281
- /* @__PURE__ */ jsxs12(
3282
- Button9,
2738
+ /* @__PURE__ */ jsxs8(
2739
+ Button7,
3283
2740
  {
3284
2741
  className: "gap-2 px-3",
3285
2742
  size: "dialog",
@@ -3287,7 +2744,7 @@ function IssueManagerSidebarHeader({
3287
2744
  variant: "secondary",
3288
2745
  onClick: onCreateIssue,
3289
2746
  children: [
3290
- /* @__PURE__ */ jsx12(FileCreateIcon3, { size: 16 }),
2747
+ /* @__PURE__ */ jsx10(FileCreateIcon3, { size: 16 }),
3291
2748
  copy.t("actions.createIssue")
3292
2749
  ]
3293
2750
  }
@@ -3300,7 +2757,7 @@ function IssueManagerSidebarStatusTabs({
3300
2757
  statusCounts,
3301
2758
  onIssueStatusFilterChange
3302
2759
  }) {
3303
- return /* @__PURE__ */ jsx12(
2760
+ return /* @__PURE__ */ jsx10(
3304
2761
  UnderlineTabs,
3305
2762
  {
3306
2763
  ariaLabel: copy.t("labels.status"),
@@ -3325,18 +2782,18 @@ function IssueManagerSidebarBody({
3325
2782
  onRetry,
3326
2783
  onSelectIssue
3327
2784
  }) {
3328
- return /* @__PURE__ */ jsx12(
3329
- ScrollArea3,
2785
+ return /* @__PURE__ */ jsx10(
2786
+ ScrollArea2,
3330
2787
  {
3331
- className: cn9("min-h-0", isNarrowLayout ? "flex-none" : "h-full flex-1"),
3332
- children: /* @__PURE__ */ jsx12(
2788
+ className: cn6("min-h-0", isNarrowLayout ? "flex-none" : "h-full flex-1"),
2789
+ children: /* @__PURE__ */ jsx10(
3333
2790
  "div",
3334
2791
  {
3335
- className: cn9(
2792
+ className: cn6(
3336
2793
  "flex min-h-full flex-col gap-2.5 px-4 pt-1.5 pb-4",
3337
2794
  isNarrowLayout ? "min-h-0" : "h-full"
3338
2795
  ),
3339
- children: sidebarViewState.kind === "loading" ? /* @__PURE__ */ jsx12(IssueManagerSidebarLoadingState, { isNarrowLayout }) : sidebarViewState.kind === "error" ? /* @__PURE__ */ jsx12(
2796
+ children: sidebarViewState.kind === "loading" ? /* @__PURE__ */ jsx10(IssueManagerSidebarLoadingState, { isNarrowLayout }) : sidebarViewState.kind === "error" ? /* @__PURE__ */ jsx10(
3340
2797
  IssueManagerSidebarErrorState,
3341
2798
  {
3342
2799
  isNarrowLayout,
@@ -3344,14 +2801,14 @@ function IssueManagerSidebarBody({
3344
2801
  title: sidebarViewState.title,
3345
2802
  onRetry
3346
2803
  }
3347
- ) : sidebarViewState.kind === "empty" ? /* @__PURE__ */ jsx12(
2804
+ ) : sidebarViewState.kind === "empty" ? /* @__PURE__ */ jsx10(
3348
2805
  IssueManagerSidebarEmptyState,
3349
2806
  {
3350
2807
  body: sidebarViewState.body,
3351
2808
  isNarrowLayout,
3352
2809
  title: sidebarViewState.title
3353
2810
  }
3354
- ) : /* @__PURE__ */ jsx12(
2811
+ ) : /* @__PURE__ */ jsx10(
3355
2812
  IssueManagerSidebarIssueList,
3356
2813
  {
3357
2814
  copy,
@@ -3375,7 +2832,7 @@ function IssueManagerSidebarStandalonePane({
3375
2832
  onRetry
3376
2833
  }) {
3377
2834
  if (kind === "error" && retryLabel) {
3378
- return /* @__PURE__ */ jsx12(
2835
+ return /* @__PURE__ */ jsx10(
3379
2836
  IssueManagerSidebarErrorState,
3380
2837
  {
3381
2838
  isNarrowLayout,
@@ -3385,7 +2842,7 @@ function IssueManagerSidebarStandalonePane({
3385
2842
  }
3386
2843
  );
3387
2844
  }
3388
- return /* @__PURE__ */ jsx12(
2845
+ return /* @__PURE__ */ jsx10(
3389
2846
  IssueManagerSidebarEmptyState,
3390
2847
  {
3391
2848
  body: body ?? "",
@@ -3400,17 +2857,17 @@ function IssueManagerSearchField({
3400
2857
  placeholder,
3401
2858
  value
3402
2859
  }) {
3403
- return /* @__PURE__ */ jsxs12(
2860
+ return /* @__PURE__ */ jsxs8(
3404
2861
  "div",
3405
2862
  {
3406
2863
  className: "relative min-w-0 flex-1",
3407
2864
  "data-has-value": value ? "true" : "false",
3408
2865
  children: [
3409
- /* @__PURE__ */ jsx12(
3410
- Input3,
2866
+ /* @__PURE__ */ jsx10(
2867
+ Input2,
3411
2868
  {
3412
2869
  "aria-label": placeholder,
3413
- className: cn9(
2870
+ className: cn6(
3414
2871
  "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",
3415
2872
  "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
3416
2873
  value ? "pr-9" : "pr-3"
@@ -3421,7 +2878,7 @@ function IssueManagerSearchField({
3421
2878
  onChange: (event) => onChange(event.target.value)
3422
2879
  }
3423
2880
  ),
3424
- value ? /* @__PURE__ */ jsx12(
2881
+ value ? /* @__PURE__ */ jsx10(
3425
2882
  "button",
3426
2883
  {
3427
2884
  "aria-label": clearLabel,
@@ -3429,7 +2886,7 @@ function IssueManagerSearchField({
3429
2886
  type: "button",
3430
2887
  onClick: () => onChange(""),
3431
2888
  onMouseDown: (event) => event.preventDefault(),
3432
- children: /* @__PURE__ */ jsx12(CloseIcon2, { className: "size-3.5" })
2889
+ children: /* @__PURE__ */ jsx10(CloseIcon, { className: "size-3.5" })
3433
2890
  }
3434
2891
  ) : null
3435
2892
  ]
@@ -3443,14 +2900,14 @@ function IssueManagerSidebarIssueList({
3443
2900
  selectedIssueId,
3444
2901
  onSelectIssue
3445
2902
  }) {
3446
- return /* @__PURE__ */ jsx12(
2903
+ return /* @__PURE__ */ jsx10(
3447
2904
  "div",
3448
2905
  {
3449
- className: cn9(
2906
+ className: cn6(
3450
2907
  "flex gap-2.5",
3451
2908
  isNarrowLayout ? "flex-row flex-nowrap items-start overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" : "flex-col"
3452
2909
  ),
3453
- children: issues.map((issue) => /* @__PURE__ */ jsx12(
2910
+ children: issues.map((issue) => /* @__PURE__ */ jsx10(
3454
2911
  IssueManagerSidebarItem,
3455
2912
  {
3456
2913
  copy,
@@ -3471,25 +2928,30 @@ function IssueManagerSidebarItem({
3471
2928
  onSelect,
3472
2929
  selected
3473
2930
  }) {
3474
- return /* @__PURE__ */ jsxs12(
2931
+ return /* @__PURE__ */ jsxs8(
3475
2932
  "button",
3476
2933
  {
3477
- className: cn9(
3478
- "rounded-lg border px-3.5 py-3.5 text-left transition-colors",
2934
+ className: cn6(
2935
+ "relative rounded-lg border px-3.5 py-3.5 text-left transition-colors",
3479
2936
  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",
3480
2937
  selected ? "border-[var(--border-1)] bg-[var(--background-fronted)]" : "border-[var(--border-1)] bg-transparent hover:bg-[var(--transparency-block)]"
3481
2938
  ),
3482
2939
  type: "button",
3483
2940
  onClick: () => onSelect(issue.issueId),
3484
2941
  children: [
3485
- /* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
3486
- /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1 space-y-2", children: [
3487
- /* @__PURE__ */ jsx12("p", { className: "text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: formatIssueManagerDate(issue.updatedAtUnix ?? issue.createdAtUnix) }),
3488
- /* @__PURE__ */ jsx12("p", { className: "line-clamp-4 text-[14px] font-semibold leading-[1.35rem] text-[var(--text-primary)]", children: issue.title })
3489
- ] }),
3490
- /* @__PURE__ */ jsx12(Badge5, { className: "shrink-0", variant: "secondary", children: resolveIssueManagerStatusLabel(copy, issue.status) })
2942
+ /* @__PURE__ */ jsx10(
2943
+ Badge4,
2944
+ {
2945
+ className: "absolute top-3.5 right-3.5",
2946
+ variant: issueManagerStatusBadgeVariant(issue.status),
2947
+ children: resolveIssueManagerStatusLabel(copy, issue.status)
2948
+ }
2949
+ ),
2950
+ /* @__PURE__ */ jsxs8("div", { className: "min-w-0 space-y-2", children: [
2951
+ /* @__PURE__ */ jsx10("p", { className: "pr-28 text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: formatIssueManagerDate(issue.updatedAtUnix ?? issue.createdAtUnix) }),
2952
+ /* @__PURE__ */ jsx10("p", { className: "line-clamp-4 text-[14px] font-semibold leading-[1.35rem] text-[var(--text-primary)]", children: issue.title })
3491
2953
  ] }),
3492
- /* @__PURE__ */ jsx12("div", { className: "mt-2 text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: copy.t("labels.taskCount", { count: issue.taskCount ?? 0 }) })
2954
+ /* @__PURE__ */ jsx10("div", { className: "mt-2 text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: copy.t("labels.taskCount", { count: issue.taskCount ?? 0 }) })
3493
2955
  ]
3494
2956
  }
3495
2957
  );
@@ -3497,25 +2959,25 @@ function IssueManagerSidebarItem({
3497
2959
  function IssueManagerSidebarLoadingState({
3498
2960
  isNarrowLayout
3499
2961
  }) {
3500
- return /* @__PURE__ */ jsx12(
2962
+ return /* @__PURE__ */ jsx10(
3501
2963
  "div",
3502
2964
  {
3503
2965
  "aria-hidden": "true",
3504
- className: cn9(
2966
+ className: cn6(
3505
2967
  "gap-2.5",
3506
2968
  isNarrowLayout ? "flex flex-row flex-nowrap overflow-x-hidden" : "grid"
3507
2969
  ),
3508
- children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxs12(
2970
+ children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxs8(
3509
2971
  "div",
3510
2972
  {
3511
- className: cn9(
2973
+ className: cn6(
3512
2974
  "rounded-lg bg-transparent px-3.5 py-3.5",
3513
2975
  isNarrowLayout && "h-24 max-h-24 min-h-24 w-[clamp(220px,58vw,320px)] flex-[0_0_clamp(220px,58vw,320px)]"
3514
2976
  ),
3515
2977
  children: [
3516
- /* @__PURE__ */ jsx12("div", { className: "h-3.5 w-20 rounded-full bg-[var(--transparency-block)]" }),
3517
- /* @__PURE__ */ jsx12("div", { className: "mt-3 h-4 w-4/5 rounded-full bg-[var(--transparency-block)]" }),
3518
- /* @__PURE__ */ jsx12("div", { className: "mt-4 h-3.5 w-24 rounded-full bg-[var(--transparency-block)]" })
2978
+ /* @__PURE__ */ jsx10("div", { className: "h-3.5 w-20 rounded-full bg-[var(--transparency-block)]" }),
2979
+ /* @__PURE__ */ jsx10("div", { className: "mt-3 h-4 w-4/5 rounded-full bg-[var(--transparency-block)]" }),
2980
+ /* @__PURE__ */ jsx10("div", { className: "mt-4 h-3.5 w-24 rounded-full bg-[var(--transparency-block)]" })
3519
2981
  ]
3520
2982
  },
3521
2983
  index
@@ -3529,25 +2991,25 @@ function IssueManagerSidebarEmptyState({
3529
2991
  title,
3530
2992
  tone = "default"
3531
2993
  }) {
3532
- return /* @__PURE__ */ jsxs12(
2994
+ return /* @__PURE__ */ jsxs8(
3533
2995
  "div",
3534
2996
  {
3535
- className: cn9(
2997
+ className: cn6(
3536
2998
  "relative flex flex-1 flex-col items-center justify-center self-stretch overflow-hidden p-0 text-center",
3537
2999
  isNarrowLayout ? "h-24 max-h-24 min-h-24 w-full flex-[0_0_100%]" : "min-h-full"
3538
3000
  ),
3539
3001
  children: [
3540
- /* @__PURE__ */ jsx12(
3002
+ /* @__PURE__ */ jsx10(
3541
3003
  "p",
3542
3004
  {
3543
- className: cn9(
3005
+ className: cn6(
3544
3006
  "text-sm font-semibold leading-5 text-[var(--text-primary)]",
3545
3007
  tone === "destructive" ? "text-[var(--state-danger)]" : "text-[var(--text-primary)]"
3546
3008
  ),
3547
3009
  children: title
3548
3010
  }
3549
3011
  ),
3550
- /* @__PURE__ */ jsx12("p", { className: "mt-1.5 max-w-sm text-sm leading-5 text-[var(--text-secondary)]", children: body })
3012
+ /* @__PURE__ */ jsx10("p", { className: "mt-1.5 max-w-sm text-sm leading-5 text-[var(--text-secondary)]", children: body })
3551
3013
  ]
3552
3014
  }
3553
3015
  );
@@ -3558,17 +3020,17 @@ function IssueManagerSidebarErrorState({
3558
3020
  title,
3559
3021
  onRetry
3560
3022
  }) {
3561
- return /* @__PURE__ */ jsxs12(
3023
+ return /* @__PURE__ */ jsxs8(
3562
3024
  "div",
3563
3025
  {
3564
- className: cn9(
3026
+ className: cn6(
3565
3027
  "relative flex flex-1 flex-col items-center justify-center self-stretch overflow-hidden px-4 py-6 text-center",
3566
3028
  isNarrowLayout ? "h-24 max-h-24 min-h-24 w-full flex-[0_0_100%]" : "min-h-full"
3567
3029
  ),
3568
3030
  children: [
3569
- /* @__PURE__ */ jsx12("p", { className: "text-sm font-semibold leading-5 text-[var(--state-danger)]", children: title }),
3570
- /* @__PURE__ */ jsx12(
3571
- Button9,
3031
+ /* @__PURE__ */ jsx10("p", { className: "text-sm font-semibold leading-5 text-[var(--state-danger)]", children: title }),
3032
+ /* @__PURE__ */ jsx10(
3033
+ Button7,
3572
3034
  {
3573
3035
  className: "mt-3",
3574
3036
  size: "sm",
@@ -3607,7 +3069,7 @@ function resolveIssueManagerSidebarPresentationState(input) {
3607
3069
  }
3608
3070
 
3609
3071
  // src/ui/internal/shell/IssueManagerSidebar.tsx
3610
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
3072
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
3611
3073
  function IssueManagerSidebar({
3612
3074
  controller,
3613
3075
  isCollapsed,
@@ -3621,18 +3083,18 @@ function IssueManagerSidebar({
3621
3083
  showStandaloneState,
3622
3084
  sidebarViewState
3623
3085
  });
3624
- return /* @__PURE__ */ jsxs13(
3086
+ return /* @__PURE__ */ jsxs9(
3625
3087
  "aside",
3626
3088
  {
3627
3089
  "aria-hidden": isCollapsed ? "true" : void 0,
3628
- className: cn10(
3090
+ className: cn7(
3629
3091
  "relative isolate flex h-full min-h-0 min-w-0 flex-col overflow-hidden bg-transparent opacity-100 transition-[border-color] duration-[140ms] ease-in-out 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-[160ms] after:delay-[70ms] motion-reduce:transition-none motion-reduce:after:transition-none [&>*]:transition-[opacity,filter] [&>*]:duration-[160ms] [&>*]:delay-[70ms] [&>*]:ease-in-out motion-reduce:[&>*]:transition-none",
3630
3092
  isNarrowLayout ? "border-b border-[var(--border-1)]" : "border-r border-[var(--border-1)]",
3631
3093
  isCollapsed && "pointer-events-none border-r-transparent after:opacity-100 after:delay-0 [&>*]:opacity-0 [&>*]:blur-[1px] [&>*]:delay-0 motion-reduce:[&>*]:blur-none"
3632
3094
  ),
3633
3095
  inert: isCollapsed ? true : void 0,
3634
3096
  children: [
3635
- /* @__PURE__ */ jsx13(
3097
+ /* @__PURE__ */ jsx11(
3636
3098
  IssueManagerSidebarHeader,
3637
3099
  {
3638
3100
  copy,
@@ -3641,7 +3103,7 @@ function IssueManagerSidebar({
3641
3103
  onIssueSearchQueryChange: controller.setIssueSearchQuery
3642
3104
  }
3643
3105
  ),
3644
- /* @__PURE__ */ jsx13(
3106
+ /* @__PURE__ */ jsx11(
3645
3107
  IssueManagerSidebarStatusTabs,
3646
3108
  {
3647
3109
  copy,
@@ -3650,15 +3112,15 @@ function IssueManagerSidebar({
3650
3112
  onIssueStatusFilterChange: controller.setIssueStatusFilter
3651
3113
  }
3652
3114
  ),
3653
- /* @__PURE__ */ jsx13("div", { "aria-hidden": "true", className: "h-2.5 flex-none" }),
3654
- /* @__PURE__ */ jsx13(
3115
+ /* @__PURE__ */ jsx11("div", { "aria-hidden": "true", className: "h-2.5 flex-none" }),
3116
+ /* @__PURE__ */ jsx11(
3655
3117
  "div",
3656
3118
  {
3657
- className: cn10(
3119
+ className: cn7(
3658
3120
  "relative flex min-h-0 flex-col",
3659
3121
  isNarrowLayout ? "flex-none" : "flex-1"
3660
3122
  ),
3661
- 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(
3123
+ children: presentation.kind !== "none" ? /* @__PURE__ */ jsx11("div", { className: "flex h-full min-h-0 items-center justify-center px-4 pt-1.5 pb-4", children: /* @__PURE__ */ jsx11(
3662
3124
  IssueManagerSidebarStandalonePane,
3663
3125
  {
3664
3126
  body: presentation.kind === "empty" ? presentation.body : void 0,
@@ -3668,7 +3130,7 @@ function IssueManagerSidebar({
3668
3130
  title: presentation.title,
3669
3131
  onRetry: () => controller.refreshAll()
3670
3132
  }
3671
- ) }) : /* @__PURE__ */ jsx13(
3133
+ ) }) : /* @__PURE__ */ jsx11(
3672
3134
  IssueManagerSidebarBody,
3673
3135
  {
3674
3136
  copy,
@@ -3687,8 +3149,8 @@ function IssueManagerSidebar({
3687
3149
  }
3688
3150
 
3689
3151
  // src/ui/internal/shell/IssueManagerTaskComposerPane.tsx
3690
- import { Button as Button10, Input as Input4 } from "@nextop-os/ui-system";
3691
- import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
3152
+ import { Button as Button8 } from "@nextop-os/ui-system";
3153
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3692
3154
  function IssueManagerTaskComposerPane({
3693
3155
  controller,
3694
3156
  onCancel,
@@ -3696,41 +3158,40 @@ function IssueManagerTaskComposerPane({
3696
3158
  }) {
3697
3159
  const copy = controller.copy;
3698
3160
  const isTaskTitleMissing = controller.taskDraft.title.trim().length === 0;
3699
- return /* @__PURE__ */ jsxs14("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
3700
- /* @__PURE__ */ jsx14("div", { className: "flex min-h-0 flex-1 flex-col gap-[14px] overflow-y-auto px-7 py-8", children: /* @__PURE__ */ jsxs14("div", { className: "flex w-full min-w-0 flex-col gap-3", children: [
3701
- /* @__PURE__ */ jsx14(
3161
+ return /* @__PURE__ */ jsxs10("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
3162
+ /* @__PURE__ */ jsx12("div", { className: "flex min-h-0 flex-1 flex-col gap-[14px] overflow-y-auto px-7 py-8", children: /* @__PURE__ */ jsxs10("div", { className: "flex w-full min-w-0 flex-col gap-3", children: [
3163
+ /* @__PURE__ */ jsx12(
3702
3164
  "div",
3703
3165
  {
3704
3166
  className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay0ClassName}`,
3705
- children: /* @__PURE__ */ jsx14("h2", { className: "m-0 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: copy.t("actions.addSubtask") })
3167
+ children: /* @__PURE__ */ jsx12("h2", { className: "m-0 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: copy.t("actions.addSubtask") })
3706
3168
  }
3707
3169
  ),
3708
- /* @__PURE__ */ jsxs14("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
3709
- /* @__PURE__ */ jsxs14(
3170
+ /* @__PURE__ */ jsxs10("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
3171
+ /* @__PURE__ */ jsxs10(
3710
3172
  "label",
3711
3173
  {
3712
3174
  className: `flex w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
3713
3175
  children: [
3714
- /* @__PURE__ */ jsx14("span", { className: "leading-5", children: copy.t("labels.title") }),
3715
- /* @__PURE__ */ jsx14(
3716
- Input4,
3176
+ /* @__PURE__ */ jsx12("span", { className: "leading-5", children: copy.t("labels.title") }),
3177
+ /* @__PURE__ */ jsx12(
3178
+ IssueManagerDraftTitleInput,
3717
3179
  {
3718
3180
  placeholder: copy.t("composer.subtaskTitlePlaceholder"),
3719
- variant: "md",
3720
3181
  value: controller.taskDraft.title,
3721
- onChange: (event) => controller.setTaskTitle(event.target.value)
3182
+ onChange: controller.setTaskTitle
3722
3183
  }
3723
3184
  )
3724
3185
  ]
3725
3186
  }
3726
3187
  ),
3727
- /* @__PURE__ */ jsxs14(
3188
+ /* @__PURE__ */ jsxs10(
3728
3189
  "div",
3729
3190
  {
3730
3191
  className: `flex min-h-0 w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay2ClassName}`,
3731
3192
  children: [
3732
- /* @__PURE__ */ jsx14("span", { className: "leading-5", children: copy.t("labels.requirementDescription") }),
3733
- /* @__PURE__ */ jsx14(
3193
+ /* @__PURE__ */ jsx12("span", { className: "leading-5", children: copy.t("labels.requirementDescription") }),
3194
+ /* @__PURE__ */ jsx12(
3734
3195
  IssueManagerRichTextTextarea,
3735
3196
  {
3736
3197
  controller,
@@ -3746,13 +3207,13 @@ function IssueManagerTaskComposerPane({
3746
3207
  )
3747
3208
  ] })
3748
3209
  ] }) }),
3749
- /* @__PURE__ */ jsx14(
3210
+ /* @__PURE__ */ jsx12(
3750
3211
  "div",
3751
3212
  {
3752
3213
  className: `shrink-0 border-t border-border-1 px-7 py-4 ${issueManagerEditorFooterFadeInClassName}`,
3753
- children: /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-end gap-3", children: [
3754
- /* @__PURE__ */ jsx14(
3755
- Button10,
3214
+ children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-3", children: [
3215
+ /* @__PURE__ */ jsx12(
3216
+ Button8,
3756
3217
  {
3757
3218
  size: "default",
3758
3219
  type: "button",
@@ -3761,8 +3222,8 @@ function IssueManagerTaskComposerPane({
3761
3222
  children: copy.t("actions.cancel")
3762
3223
  }
3763
3224
  ),
3764
- /* @__PURE__ */ jsx14(
3765
- Button10,
3225
+ /* @__PURE__ */ jsx12(
3226
+ Button8,
3766
3227
  {
3767
3228
  disabled: !selectedIssue || isTaskTitleMissing,
3768
3229
  size: "default",
@@ -3778,109 +3239,11 @@ function IssueManagerTaskComposerPane({
3778
3239
  }
3779
3240
 
3780
3241
  // src/ui/internal/shell/IssueManagerTaskDrawer.tsx
3781
- import { ScrollArea as ScrollArea4 } from "@nextop-os/ui-system";
3242
+ import { ScrollArea as ScrollArea3, cn as cn8 } from "@nextop-os/ui-system";
3782
3243
 
3783
3244
  // src/ui/internal/shell/IssueManagerTaskDrawerSections.tsx
3784
- import {
3785
- Badge as Badge6,
3786
- Button as Button12,
3787
- CloseIcon as CloseIcon3,
3788
- DropdownMenu,
3789
- DropdownMenuContent,
3790
- DropdownMenuItem,
3791
- DropdownMenuTrigger,
3792
- Input as Input5,
3793
- Select as Select2,
3794
- SelectContent as SelectContent2,
3795
- SelectItem as SelectItem2,
3796
- SelectTrigger as SelectTrigger2,
3797
- SelectValue,
3798
- CapabilityIcon
3799
- } from "@nextop-os/ui-system";
3800
-
3801
- // src/ui/internal/content/IssueManagerContextSection.tsx
3802
- import { Button as Button11, DirectoryIcon, FileIcon as FileIcon3 } from "@nextop-os/ui-system";
3803
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
3804
- function IssueManagerContextSection({
3805
- copy,
3806
- emptyLabel,
3807
- onAdd,
3808
- onOpen,
3809
- onRemove,
3810
- refs
3811
- }) {
3812
- return /* @__PURE__ */ jsxs15("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
3813
- /* @__PURE__ */ jsxs15("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
3814
- /* @__PURE__ */ jsx15("h4", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.contextReferences") }),
3815
- /* @__PURE__ */ jsx15(
3816
- Button11,
3817
- {
3818
- className: "px-3",
3819
- size: "dialog",
3820
- type: "button",
3821
- variant: "secondary",
3822
- onClick: onAdd,
3823
- children: copy.t("actions.addReferences")
3824
- }
3825
- )
3826
- ] }),
3827
- refs.length === 0 ? /* @__PURE__ */ jsx15("p", { className: "text-sm leading-5 text-[var(--text-secondary)]", children: emptyLabel }) : /* @__PURE__ */ jsx15("div", { className: "grid gap-2.5", children: refs.map((ref) => /* @__PURE__ */ jsxs15(
3828
- "div",
3829
- {
3830
- className: "flex items-center justify-between gap-3 rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3",
3831
- children: [
3832
- /* @__PURE__ */ jsxs15(
3833
- "button",
3834
- {
3835
- className: "flex min-w-0 flex-1 items-center gap-3 text-left",
3836
- type: "button",
3837
- onClick: () => {
3838
- void onOpen({
3839
- displayName: ref.displayName,
3840
- kind: ref.path.endsWith("/") ? "folder" : "file",
3841
- path: ref.path
3842
- });
3843
- },
3844
- children: [
3845
- ref.path.endsWith("/") ? /* @__PURE__ */ jsx15(
3846
- DirectoryIcon,
3847
- {
3848
- className: "shrink-0 text-[var(--text-secondary)]",
3849
- size: 16
3850
- }
3851
- ) : /* @__PURE__ */ jsx15(
3852
- FileIcon3,
3853
- {
3854
- className: "shrink-0 text-[var(--text-secondary)]",
3855
- size: 16
3856
- }
3857
- ),
3858
- /* @__PURE__ */ jsxs15("span", { className: "min-w-0", children: [
3859
- /* @__PURE__ */ jsx15("span", { className: "block truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: ref.displayName }),
3860
- /* @__PURE__ */ jsx15("span", { className: "block truncate text-xs leading-[1.55] text-[var(--text-secondary)]", children: ref.path })
3861
- ] })
3862
- ]
3863
- }
3864
- ),
3865
- /* @__PURE__ */ jsx15(
3866
- Button11,
3867
- {
3868
- className: "h-7 rounded-md px-2 text-[13px] font-semibold text-[var(--text-secondary)] hover:text-[var(--text-primary)]",
3869
- size: "sm",
3870
- type: "button",
3871
- variant: "ghost",
3872
- onClick: () => {
3873
- void onRemove(ref);
3874
- },
3875
- children: copy.t("actions.removeReference")
3876
- }
3877
- )
3878
- ]
3879
- },
3880
- ref.contextRefId
3881
- )) })
3882
- ] });
3883
- }
3245
+ import { useState as useState7 } from "react";
3246
+ import { Badge as Badge5, Button as Button9, ConfirmationDialog as ConfirmationDialog2 } from "@nextop-os/ui-system";
3884
3247
 
3885
3248
  // src/ui/internal/shell/IssueManagerTaskDrawerState.ts
3886
3249
  function resolveIssueManagerTaskDrawerViewState(input) {
@@ -3903,193 +3266,173 @@ function resolveIssueManagerTaskDrawerViewState(input) {
3903
3266
  title: isCreate || isEdit ? isCreate ? controller.copy.t("actions.createTask") : controller.copy.t("actions.editTask") : selectedTask?.title || controller.copy.t("labels.taskDetails")
3904
3267
  };
3905
3268
  }
3906
- function resolveIssueManagerTaskRefs(input) {
3907
- return input.controller.taskDetail.value?.contextRefs.filter(
3908
- (ref) => ref.parentKind === "task"
3909
- ) ?? [];
3910
- }
3911
3269
  function canIssueManagerSaveTask(input) {
3912
3270
  return input.selectedIssue !== null && input.view.isTaskTitleMissing === false;
3913
3271
  }
3914
3272
 
3915
3273
  // src/ui/internal/shell/IssueManagerTaskDrawerSections.tsx
3916
- import { Fragment, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
3917
- var taskPriorityOptions = ["high", "medium", "low"];
3274
+ import { Fragment, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3918
3275
  function IssueManagerTaskDrawerHeader({
3919
3276
  controller,
3920
3277
  selectedTask,
3921
- view,
3922
- onClose
3278
+ view
3923
3279
  }) {
3924
3280
  const copy = controller.copy;
3925
- return /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-4 border-b border-border-1 px-7 py-5", children: [
3926
- /* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1", children: [
3927
- 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 }),
3928
- view.showTaskMetadata && selectedTask ? /* @__PURE__ */ jsxs16("div", { className: "mt-2 flex min-w-0 items-center overflow-hidden text-sm leading-[1.55] text-[var(--text-secondary)]", children: [
3929
- /* @__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) }),
3930
- /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
3931
- /* @__PURE__ */ jsx16(Badge6, { className: "shrink-0 rounded-full border-transparent bg-transparency-block px-2.5 py-1 text-xs text-[var(--text-secondary)]", children: resolveIssueManagerPriorityLabel(copy, selectedTask.priority) }),
3932
- /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
3933
- /* @__PURE__ */ jsxs16("span", { children: [
3934
- copy.t("labels.updatedAt"),
3935
- " ",
3936
- formatIssueManagerTimestamp(
3937
- selectedTask.updatedAtUnix ?? selectedTask.createdAtUnix
3938
- ) || "-"
3939
- ] }),
3940
- /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
3941
- /* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: resolveTaskCreatorLabel(selectedTask) })
3942
- ] }) : null
3943
- ] }),
3944
- /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
3945
- view.showTaskActions && selectedTask ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
3946
- /* @__PURE__ */ jsx16(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx16(
3947
- Button12,
3948
- {
3949
- "aria-label": copy.t("actions.moreActions"),
3950
- size: "icon-sm",
3951
- type: "button",
3952
- variant: "ghost",
3953
- children: /* @__PURE__ */ jsx16(
3954
- "span",
3955
- {
3956
- "aria-hidden": "true",
3957
- className: "text-base leading-none tracking-[0.18em] text-[var(--text-secondary)]",
3958
- children: "..."
3959
- }
3960
- )
3961
- }
3962
- ) }),
3963
- /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", sideOffset: 8, children: [
3964
- /* @__PURE__ */ jsx16(
3965
- DropdownMenuItem,
3281
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState7(false);
3282
+ const [deleteBusy, setDeleteBusy] = useState7(false);
3283
+ return /* @__PURE__ */ jsxs11(Fragment, { children: [
3284
+ /* @__PURE__ */ jsxs11("div", { className: "grid gap-3 px-6 py-7", children: [
3285
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-6", children: [
3286
+ view.showTaskMetadata && selectedTask ? /* @__PURE__ */ jsx13("h3", { className: "line-clamp-2 min-w-0 flex-1 text-base font-semibold leading-6 text-[var(--text-primary)]", children: view.title }) : /* @__PURE__ */ jsx13("h3", { className: "line-clamp-2 min-w-0 flex-1 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: view.title }),
3287
+ /* @__PURE__ */ jsx13("div", { className: "flex shrink-0 items-center gap-2", children: view.showTaskActions && selectedTask ? /* @__PURE__ */ jsxs11(Fragment, { children: [
3288
+ /* @__PURE__ */ jsx13(
3289
+ Button9,
3966
3290
  {
3291
+ type: "button",
3292
+ variant: "ghost",
3967
3293
  onClick: () => controller.setTaskEditorMode("edit"),
3968
- children: copy.t("actions.editTask")
3294
+ children: copy.t("actions.edit")
3969
3295
  }
3970
3296
  ),
3971
- /* @__PURE__ */ jsx16(
3972
- DropdownMenuItem,
3297
+ /* @__PURE__ */ jsx13(
3298
+ Button9,
3973
3299
  {
3974
- variant: "destructive",
3975
- onClick: () => {
3976
- void controller.deleteTask();
3977
- },
3978
- children: copy.t("actions.deleteTask")
3300
+ className: "text-[var(--state-danger)] hover:bg-[var(--on-danger)] hover:text-[var(--state-danger)]",
3301
+ type: "button",
3302
+ variant: "ghost",
3303
+ onClick: () => setDeleteDialogOpen(true),
3304
+ children: copy.t("actions.delete")
3979
3305
  }
3980
3306
  )
3307
+ ] }) : null })
3308
+ ] }),
3309
+ view.showTaskMetadata && selectedTask ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-2 text-sm font-normal text-[var(--text-secondary)]", children: [
3310
+ /* @__PURE__ */ jsx13(
3311
+ Badge5,
3312
+ {
3313
+ variant: issueManagerStatusBadgeVariant(selectedTask.status),
3314
+ children: resolveIssueManagerStatusLabel(copy, selectedTask.status)
3315
+ }
3316
+ ),
3317
+ /* @__PURE__ */ jsx13(
3318
+ "span",
3319
+ {
3320
+ "aria-hidden": "true",
3321
+ className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
3322
+ }
3323
+ ),
3324
+ /* @__PURE__ */ jsxs11("span", { children: [
3325
+ copy.t("labels.creator"),
3326
+ " ",
3327
+ resolveTaskCreatorLabel(selectedTask)
3328
+ ] }),
3329
+ /* @__PURE__ */ jsx13(
3330
+ "span",
3331
+ {
3332
+ "aria-hidden": "true",
3333
+ className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
3334
+ }
3335
+ ),
3336
+ /* @__PURE__ */ jsxs11("span", { children: [
3337
+ copy.t("labels.createdAt"),
3338
+ " ",
3339
+ formatIssueManagerTimestamp(selectedTask.createdAtUnix) || "-"
3981
3340
  ] })
3982
- ] }) : null,
3983
- /* @__PURE__ */ jsx16(
3984
- Button12,
3985
- {
3986
- "aria-label": copy.t("actions.cancel"),
3987
- size: "icon-sm",
3988
- type: "button",
3989
- variant: "ghost",
3990
- onClick: onClose,
3991
- children: /* @__PURE__ */ jsx16(CloseIcon3, { size: 16 })
3992
- }
3993
- )
3994
- ] })
3341
+ ] }) : null
3342
+ ] }),
3343
+ selectedTask ? /* @__PURE__ */ jsx13(
3344
+ ConfirmationDialog2,
3345
+ {
3346
+ cancelLabel: copy.t("actions.cancel"),
3347
+ confirmBusy: deleteBusy,
3348
+ confirmLabel: copy.t("actions.delete"),
3349
+ description: selectedTask.title,
3350
+ open: deleteDialogOpen,
3351
+ title: copy.t("confirmations.deleteTask"),
3352
+ tone: "destructive",
3353
+ onConfirm: () => {
3354
+ setDeleteBusy(true);
3355
+ void controller.deleteTask({ skipConfirmation: true }).finally(() => {
3356
+ setDeleteBusy(false);
3357
+ setDeleteDialogOpen(false);
3358
+ });
3359
+ },
3360
+ onOpenChange: setDeleteDialogOpen
3361
+ }
3362
+ ) : null
3995
3363
  ] });
3996
3364
  }
3997
3365
  function IssueManagerTaskDrawerLoadingBody() {
3998
- return /* @__PURE__ */ jsx16(IssueManagerTaskDrawerLoadingState, {});
3366
+ return /* @__PURE__ */ jsx13(IssueManagerTaskDrawerLoadingState, {});
3999
3367
  }
4000
3368
  function IssueManagerTaskDrawerBody({
4001
3369
  controller,
4002
3370
  taskContent,
4003
- taskRefs,
4004
3371
  view
4005
3372
  }) {
4006
3373
  if (view.bodyKind === "loading") {
4007
- return /* @__PURE__ */ jsx16(IssueManagerTaskDrawerLoadingBody, {});
3374
+ return /* @__PURE__ */ jsx13(IssueManagerTaskDrawerLoadingBody, {});
4008
3375
  }
4009
3376
  if (view.bodyKind === "edit") {
4010
- return /* @__PURE__ */ jsx16(
3377
+ return /* @__PURE__ */ jsx13(
4011
3378
  IssueManagerTaskDrawerEditBody,
4012
3379
  {
4013
3380
  controller,
4014
- isCreate: view.isCreate,
4015
- taskRefs
3381
+ title: view.title
4016
3382
  }
4017
3383
  );
4018
3384
  }
4019
- return /* @__PURE__ */ jsx16(
3385
+ return /* @__PURE__ */ jsx13(
4020
3386
  IssueManagerTaskDrawerReadBody,
4021
3387
  {
4022
3388
  controller,
4023
- taskContent,
4024
- taskRefs
3389
+ taskContent
4025
3390
  }
4026
3391
  );
4027
3392
  }
4028
3393
  function IssueManagerTaskDrawerEditBody({
4029
3394
  controller,
4030
- isCreate,
4031
- taskRefs
3395
+ title
4032
3396
  }) {
4033
3397
  const copy = controller.copy;
4034
- return /* @__PURE__ */ jsxs16(Fragment, { children: [
4035
- /* @__PURE__ */ jsxs16("div", { className: "grid gap-5", children: [
4036
- /* @__PURE__ */ jsxs16(
3398
+ return /* @__PURE__ */ jsxs11("div", { className: "flex w-full min-w-0 flex-col gap-3", children: [
3399
+ /* @__PURE__ */ jsx13(
3400
+ "div",
3401
+ {
3402
+ className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay0ClassName}`,
3403
+ children: /* @__PURE__ */ jsx13("h2", { className: "m-0 text-[17px] font-semibold leading-[1.35] text-[var(--text-primary)]", children: title })
3404
+ }
3405
+ ),
3406
+ /* @__PURE__ */ jsxs11("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
3407
+ /* @__PURE__ */ jsxs11(
4037
3408
  "label",
4038
3409
  {
4039
- className: `grid gap-2 ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay0ClassName}`,
3410
+ className: `flex w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
4040
3411
  children: [
4041
- /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.title") }),
4042
- /* @__PURE__ */ jsx16(
4043
- Input5,
3412
+ /* @__PURE__ */ jsx13("span", { className: "leading-5", children: copy.t("labels.title") }),
3413
+ /* @__PURE__ */ jsx13(
3414
+ IssueManagerDraftTitleInput,
4044
3415
  {
4045
3416
  placeholder: copy.t("composer.taskTitlePlaceholder"),
4046
- variant: "md",
4047
3417
  value: controller.taskDraft.title,
4048
- onChange: (event) => controller.setTaskTitle(event.target.value)
3418
+ onChange: controller.setTaskTitle
4049
3419
  }
4050
3420
  )
4051
3421
  ]
4052
3422
  }
4053
3423
  ),
4054
- /* @__PURE__ */ jsx16(
4055
- "div",
4056
- {
4057
- className: `flex flex-wrap items-center gap-3 ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
4058
- children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
4059
- /* @__PURE__ */ jsx16("span", { className: "text-sm font-medium text-[var(--text-secondary)]", children: copy.t("labels.priority") }),
4060
- /* @__PURE__ */ jsxs16(
4061
- Select2,
4062
- {
4063
- value: controller.taskDraft.priority,
4064
- onValueChange: (value) => controller.setTaskPriority(value),
4065
- children: [
4066
- /* @__PURE__ */ jsx16(
4067
- SelectTrigger2,
4068
- {
4069
- "aria-label": copy.t("labels.priority"),
4070
- className: "min-w-28 rounded-lg border-border-1 bg-transparency-block text-sm",
4071
- children: /* @__PURE__ */ jsx16(SelectValue, {})
4072
- }
4073
- ),
4074
- /* @__PURE__ */ jsx16(SelectContent2, { style: { zIndex: "var(--z-panel-popover)" }, children: taskPriorityOptions.map((priority) => /* @__PURE__ */ jsx16(SelectItem2, { value: priority, children: resolveIssueManagerPriorityLabel(copy, priority) }, priority)) })
4075
- ]
4076
- }
4077
- )
4078
- ] })
4079
- }
4080
- ),
4081
- /* @__PURE__ */ jsxs16(
3424
+ /* @__PURE__ */ jsxs11(
4082
3425
  "div",
4083
3426
  {
4084
- className: `grid gap-2 ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay2ClassName}`,
3427
+ className: `flex min-h-0 w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay2ClassName}`,
4085
3428
  children: [
4086
- /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.content") }),
4087
- /* @__PURE__ */ jsx16(
3429
+ /* @__PURE__ */ jsx13("span", { className: "leading-5", children: copy.t("labels.content") }),
3430
+ /* @__PURE__ */ jsx13(
4088
3431
  IssueManagerRichTextTextarea,
4089
3432
  {
4090
3433
  controller,
4091
3434
  surface: "task",
4092
- textareaClassName: "min-h-[12rem] resize-none",
3435
+ textareaClassName: "min-h-[180px] resize-none",
4093
3436
  placeholder: copy.t("composer.taskContentPlaceholder"),
4094
3437
  value: controller.taskDraft.content,
4095
3438
  onChange: controller.setTaskContent
@@ -4098,73 +3441,44 @@ function IssueManagerTaskDrawerEditBody({
4098
3441
  ]
4099
3442
  }
4100
3443
  )
4101
- ] }),
4102
- /* @__PURE__ */ jsx16(
4103
- "div",
4104
- {
4105
- className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay3ClassName}`,
4106
- children: /* @__PURE__ */ jsx16(
4107
- IssueManagerContextSection,
4108
- {
4109
- copy,
4110
- emptyLabel: copy.t("messages.noTaskReferences"),
4111
- refs: taskRefs,
4112
- onAdd: () => {
4113
- void controller.attachReferences("task");
4114
- },
4115
- onOpen: controller.openReference,
4116
- onRemove: controller.removeContextRef
4117
- }
4118
- )
4119
- }
4120
- ),
4121
- !isCreate ? /* @__PURE__ */ jsx16(
4122
- IssueManagerRunPanels,
4123
- {
4124
- copy,
4125
- outputs: controller.taskDetail.value?.latestOutputs ?? [],
4126
- recentRuns: controller.taskDetail.value?.recentRuns ?? [],
4127
- onOpen: controller.openReference
4128
- }
4129
- ) : null
3444
+ ] })
4130
3445
  ] });
4131
3446
  }
4132
3447
  function IssueManagerTaskDrawerReadBody({
4133
3448
  controller,
4134
- taskContent,
4135
- taskRefs
3449
+ taskContent
4136
3450
  }) {
4137
3451
  const copy = controller.copy;
4138
- return /* @__PURE__ */ jsxs16(Fragment, { children: [
4139
- /* @__PURE__ */ jsx16(
3452
+ const latestRun = controller.taskDetail.value?.latestRun ?? controller.taskDetail.value?.recentRuns[0] ?? null;
3453
+ const latestOutputs = controller.taskDetail.value?.latestOutputs ?? [];
3454
+ return /* @__PURE__ */ jsxs11(Fragment, { children: [
3455
+ /* @__PURE__ */ jsx13(
4140
3456
  IssueManagerDescriptionSection,
4141
3457
  {
4142
3458
  content: taskContent,
4143
3459
  emptyLabel: copy.t("messages.taskContentEmpty"),
4144
- label: copy.t("labels.content"),
4145
- minHeightClass: "min-h-[8rem]",
4146
- onOpen: controller.openReference
3460
+ label: copy.t("labels.description"),
3461
+ onOpen: controller.openReference,
3462
+ variant: "plain"
4147
3463
  }
4148
3464
  ),
4149
- /* @__PURE__ */ jsx16(
4150
- IssueManagerContextSection,
3465
+ /* @__PURE__ */ jsx13(
3466
+ IssueManagerDetailTextSection,
4151
3467
  {
4152
- copy,
4153
- emptyLabel: copy.t("messages.noTaskReferences"),
4154
- refs: taskRefs,
4155
- onAdd: () => {
4156
- void controller.attachReferences("task");
4157
- },
4158
- onOpen: controller.openReference,
4159
- onRemove: controller.removeContextRef
3468
+ body: latestRun ? latestRun.summary?.trim() || resolveIssueManagerStatusLabel(copy, latestRun.status) : copy.t("messages.noExecutionStatus"),
3469
+ isPlaceholder: !latestRun,
3470
+ label: copy.t("labels.latestRunStatus"),
3471
+ meta: latestRun ? formatIssueManagerTimestamp(
3472
+ latestRun.updatedAtUnix ?? latestRun.createdAtUnix
3473
+ ) || void 0 : void 0,
3474
+ tone: latestRun?.status === "failed" ? "destructive" : "muted"
4160
3475
  }
4161
3476
  ),
4162
- /* @__PURE__ */ jsx16(
4163
- IssueManagerRunPanels,
3477
+ /* @__PURE__ */ jsx13(
3478
+ IssueManagerOutputSection,
4164
3479
  {
4165
3480
  copy,
4166
- outputs: controller.taskDetail.value?.latestOutputs ?? [],
4167
- recentRuns: controller.taskDetail.value?.recentRuns ?? [],
3481
+ outputs: latestOutputs,
4168
3482
  onOpen: controller.openReference
4169
3483
  }
4170
3484
  )
@@ -4178,18 +3492,26 @@ function IssueManagerTaskDrawerFooter({
4178
3492
  }) {
4179
3493
  const copy = controller.copy;
4180
3494
  if (view.showReadFooter && selectedTask) {
4181
- 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: [
4182
- /* @__PURE__ */ jsx16(
3495
+ return /* @__PURE__ */ jsx13("div", { className: "border-t border-[var(--border-1)] bg-transparent px-6 py-4 backdrop-blur", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-end gap-3", children: [
3496
+ /* @__PURE__ */ jsx13(
3497
+ IssueManagerExecutionDirectoryTrigger,
3498
+ {
3499
+ className: "mr-auto",
3500
+ controller,
3501
+ disabled: controller.isRunningTask
3502
+ }
3503
+ ),
3504
+ /* @__PURE__ */ jsx13(
4183
3505
  IssueManagerRunActionTrigger,
4184
3506
  {
4185
3507
  controller,
4186
- triggerClassName: "min-w-[11rem]"
3508
+ triggerVariant: "button"
4187
3509
  }
4188
3510
  ),
4189
- controller.canInviteCollaborators ? /* @__PURE__ */ jsx16(
4190
- Button12,
3511
+ controller.canInviteCollaborators ? /* @__PURE__ */ jsx13(
3512
+ Button9,
4191
3513
  {
4192
- className: "shrink-0 px-4",
3514
+ disabled: !selectedIssue,
4193
3515
  size: "dialog",
4194
3516
  type: "button",
4195
3517
  onClick: () => {
@@ -4201,51 +3523,34 @@ function IssueManagerTaskDrawerFooter({
4201
3523
  ] }) });
4202
3524
  }
4203
3525
  if (view.showEditFooter) {
4204
- return /* @__PURE__ */ jsx16(
3526
+ return /* @__PURE__ */ jsx13(
4205
3527
  "div",
4206
3528
  {
4207
- className: `border-t border-border-1 px-7 py-4 ${issueManagerEditorFooterFadeInClassName}`,
4208
- children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-3", children: [
4209
- /* @__PURE__ */ jsx16("div", { className: "flex items-center gap-2", children: !view.isCreate && selectedTask ? /* @__PURE__ */ jsx16(
4210
- Button12,
3529
+ className: `border-t border-border-1 px-6 py-4 ${issueManagerEditorFooterFadeInClassName}`,
3530
+ children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-end gap-3", children: [
3531
+ /* @__PURE__ */ jsx13(
3532
+ Button9,
4211
3533
  {
4212
- size: "default",
3534
+ size: "dialog",
4213
3535
  type: "button",
4214
- variant: "destructive",
4215
- onClick: () => {
4216
- void controller.deleteTask();
4217
- },
4218
- children: copy.t("actions.deleteTask")
3536
+ variant: "secondary",
3537
+ onClick: () => controller.setTaskEditorMode("read"),
3538
+ children: copy.t("actions.cancel")
4219
3539
  }
4220
- ) : null }),
4221
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
4222
- /* @__PURE__ */ jsx16(
4223
- Button12,
4224
- {
4225
- size: "default",
4226
- type: "button",
4227
- variant: "secondary",
4228
- onClick: () => controller.setTaskEditorMode("read"),
4229
- children: copy.t("actions.cancel")
4230
- }
4231
- ),
4232
- /* @__PURE__ */ jsxs16(
4233
- Button12,
4234
- {
4235
- disabled: canIssueManagerSaveTask({
4236
- selectedIssue,
4237
- view
4238
- }) === false,
4239
- size: "default",
4240
- type: "button",
4241
- onClick: () => void controller.saveTask(),
4242
- children: [
4243
- /* @__PURE__ */ jsx16(CapabilityIcon, { size: 16 }),
4244
- copy.t("actions.saveTask")
4245
- ]
4246
- }
4247
- )
4248
- ] })
3540
+ ),
3541
+ /* @__PURE__ */ jsx13(
3542
+ Button9,
3543
+ {
3544
+ disabled: canIssueManagerSaveTask({
3545
+ selectedIssue,
3546
+ view
3547
+ }) === false,
3548
+ size: "dialog",
3549
+ type: "button",
3550
+ onClick: () => void controller.saveTask(),
3551
+ children: copy.t("actions.saveTask")
3552
+ }
3553
+ )
4249
3554
  ] })
4250
3555
  }
4251
3556
  );
@@ -4254,9 +3559,10 @@ function IssueManagerTaskDrawerFooter({
4254
3559
  }
4255
3560
 
4256
3561
  // src/ui/internal/shell/IssueManagerTaskDrawer.tsx
4257
- import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
3562
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
4258
3563
  function IssueManagerTaskDrawer({
4259
3564
  controller,
3565
+ isClosing,
4260
3566
  selectedIssue,
4261
3567
  selectedTask,
4262
3568
  onClose
@@ -4265,38 +3571,58 @@ function IssueManagerTaskDrawer({
4265
3571
  controller,
4266
3572
  selectedTask
4267
3573
  });
4268
- const taskRefs = resolveIssueManagerTaskRefs({ controller });
4269
3574
  const taskContent = selectedTask?.content ?? "";
4270
- return /* @__PURE__ */ jsx17(
3575
+ return /* @__PURE__ */ jsx14(
4271
3576
  "div",
4272
3577
  {
4273
- className: "absolute inset-0 z-20 flex justify-end bg-[var(--backdrop)] backdrop-blur-[1px]",
3578
+ className: cn8(
3579
+ "absolute inset-0 z-20 flex justify-end overscroll-contain bg-[var(--backdrop)] backdrop-blur-[1px] motion-reduce:animate-none",
3580
+ isClosing ? "motion-safe:animate-out motion-safe:fade-out-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.4,0,0.2,1)]" : "motion-safe:animate-in motion-safe:fade-in-0 motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.4,0,0.2,1)]"
3581
+ ),
4274
3582
  onClick: onClose,
4275
- children: /* @__PURE__ */ jsxs17(
3583
+ onTouchMove: (event) => {
3584
+ event.preventDefault();
3585
+ },
3586
+ onWheel: (event) => {
3587
+ event.preventDefault();
3588
+ },
3589
+ children: /* @__PURE__ */ jsxs12(
4276
3590
  "aside",
4277
3591
  {
4278
- 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)]",
3592
+ className: cn8(
3593
+ "flex h-full w-[min(360px,92cqw)] flex-col overscroll-contain border-l border-border-1 bg-background-panel text-[var(--text-primary)] shadow-[-20px_0_60px_var(--shadow-elevated)] @min-[960px]/issue-manager-content:w-[480px] motion-reduce:animate-none",
3594
+ isClosing ? "motion-safe:animate-out motion-safe:slide-out-to-right-full motion-safe:duration-[180ms] motion-safe:ease-[cubic-bezier(0.4,0,0.2,1)]" : "motion-safe:animate-in motion-safe:slide-in-from-right-full motion-safe:duration-[220ms] motion-safe:ease-[cubic-bezier(0.22,1,0.36,1)]"
3595
+ ),
4279
3596
  onClick: (event) => event.stopPropagation(),
3597
+ onTouchMove: (event) => event.stopPropagation(),
3598
+ onWheel: (event) => event.stopPropagation(),
4280
3599
  children: [
4281
- /* @__PURE__ */ jsx17(
3600
+ view.bodyKind === "edit" ? null : /* @__PURE__ */ jsx14(
4282
3601
  IssueManagerTaskDrawerHeader,
4283
3602
  {
4284
3603
  controller,
4285
3604
  selectedTask,
4286
- view,
4287
- onClose
3605
+ view
4288
3606
  }
4289
3607
  ),
4290
- /* @__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(
4291
- IssueManagerTaskDrawerBody,
3608
+ /* @__PURE__ */ jsx14(ScrollArea3, { className: "min-h-0 flex-1 [&_[data-slot=scroll-area-viewport]]:overscroll-contain", children: /* @__PURE__ */ jsx14(
3609
+ "div",
4292
3610
  {
4293
- controller,
4294
- taskContent,
4295
- taskRefs,
4296
- view
3611
+ className: cn8(
3612
+ "flex flex-col",
3613
+ view.bodyKind === "edit" ? "gap-[14px] px-6 py-8" : "gap-9 px-6 py-7"
3614
+ ),
3615
+ children: /* @__PURE__ */ jsx14(
3616
+ IssueManagerTaskDrawerBody,
3617
+ {
3618
+ controller,
3619
+ taskContent,
3620
+ view
3621
+ }
3622
+ )
4297
3623
  }
4298
- ) }) }),
4299
- /* @__PURE__ */ jsx17(
3624
+ ) }),
3625
+ /* @__PURE__ */ jsx14(
4300
3626
  IssueManagerTaskDrawerFooter,
4301
3627
  {
4302
3628
  controller,
@@ -4315,7 +3641,7 @@ function IssueManagerTaskDrawer({
4315
3641
  // src/ui/internal/shell/useIssueManagerShellView.ts
4316
3642
  import {
4317
3643
  useEffect as useEffect7,
4318
- useEffectEvent as useEffectEvent3,
3644
+ useEffectEvent as useEffectEvent2,
4319
3645
  useRef as useRef3,
4320
3646
  useState as useState8
4321
3647
  } from "react";
@@ -4330,7 +3656,7 @@ function useIssueManagerShellView({
4330
3656
  issueManagerSidebarDefaultWidth
4331
3657
  );
4332
3658
  const [isNarrowLayout, setIsNarrowLayout] = useState8(false);
4333
- const dismissNotification = useEffectEvent3(() => {
3659
+ const dismissNotification = useEffectEvent2(() => {
4334
3660
  controller.dismissNotification();
4335
3661
  });
4336
3662
  const floatingNotice = controller.floatingNotice;
@@ -4467,7 +3793,8 @@ function useIssueManagerShellView({
4467
3793
  }
4468
3794
 
4469
3795
  // src/ui/internal/shell/IssueManagerShell.tsx
4470
- import { jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
3796
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
3797
+ var issueManagerTaskDrawerExitDurationMs = 180;
4471
3798
  function IssueManagerShell({
4472
3799
  controller,
4473
3800
  emptyIllustration,
@@ -4481,7 +3808,32 @@ function IssueManagerShell({
4481
3808
  selectedIssue,
4482
3809
  selectedTask
4483
3810
  });
4484
- return /* @__PURE__ */ jsxs18(
3811
+ const [renderedTaskDrawerTask, setRenderedTaskDrawerTask] = useState9(selectedTask);
3812
+ const [isTaskDrawerClosing, setIsTaskDrawerClosing] = useState9(false);
3813
+ useEffect8(() => {
3814
+ if (shellView.content.isTaskDrawerOpen) {
3815
+ setRenderedTaskDrawerTask(selectedTask);
3816
+ setIsTaskDrawerClosing(false);
3817
+ return void 0;
3818
+ }
3819
+ if (!renderedTaskDrawerTask) {
3820
+ return void 0;
3821
+ }
3822
+ setIsTaskDrawerClosing(true);
3823
+ const timeout = window.setTimeout(() => {
3824
+ setRenderedTaskDrawerTask(null);
3825
+ setIsTaskDrawerClosing(false);
3826
+ }, issueManagerTaskDrawerExitDurationMs);
3827
+ return () => {
3828
+ window.clearTimeout(timeout);
3829
+ };
3830
+ }, [
3831
+ renderedTaskDrawerTask,
3832
+ selectedTask,
3833
+ shellView.content.isTaskDrawerOpen
3834
+ ]);
3835
+ const taskDrawerTask = shellView.content.isTaskDrawerOpen ? selectedTask : renderedTaskDrawerTask;
3836
+ return /* @__PURE__ */ jsxs13(
4485
3837
  "div",
4486
3838
  {
4487
3839
  className: "relative grid min-h-0 flex-1 grid-rows-[minmax(0,1fr)] overflow-hidden bg-transparent transition-[grid-template-columns] duration-[180ms] ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none",
@@ -4490,8 +3842,8 @@ function IssueManagerShell({
4490
3842
  ref: shellView.layoutRef,
4491
3843
  style: shellView.layoutStyle,
4492
3844
  children: [
4493
- shellView.floatingNotice ? /* @__PURE__ */ jsx18(IssueManagerFloatingNotice, { notice: shellView.floatingNotice }) : null,
4494
- /* @__PURE__ */ jsx18(
3845
+ shellView.floatingNotice ? /* @__PURE__ */ jsx15(IssueManagerFloatingNotice, { notice: shellView.floatingNotice }) : null,
3846
+ /* @__PURE__ */ jsx15(
4495
3847
  IssueManagerSidebar,
4496
3848
  {
4497
3849
  controller,
@@ -4502,7 +3854,7 @@ function IssueManagerShell({
4502
3854
  statusCounts: shellView.sidebar.statusCounts
4503
3855
  }
4504
3856
  ),
4505
- shellView.sidebar.isAutoCollapsed ? null : /* @__PURE__ */ jsx18(
3857
+ shellView.sidebar.isAutoCollapsed ? null : /* @__PURE__ */ jsx15(
4506
3858
  "div",
4507
3859
  {
4508
3860
  "aria-label": controller.copy.t("labels.resizeIssueList"),
@@ -4510,7 +3862,7 @@ function IssueManagerShell({
4510
3862
  "aria-valuemax": shellView.resizeHandle.ariaValueMax,
4511
3863
  "aria-valuemin": shellView.resizeHandle.ariaValueMin,
4512
3864
  "aria-valuenow": shellView.resizeHandle.ariaValueNow,
4513
- className: cn11(
3865
+ className: cn9(
4514
3866
  "group absolute top-0 bottom-0 left-[calc(var(--issue-manager-sidebar-width)-6px)] z-20 w-3 cursor-col-resize touch-none opacity-100 transition-[left,opacity] duration-[180ms,120ms] ease-[cubic-bezier(0.4,0,0.2,1),ease] motion-reduce:transition-none",
4515
3867
  shellView.sidebar.isCollapsed && "pointer-events-none left-[-6px] opacity-0"
4516
3868
  ),
@@ -4521,56 +3873,56 @@ function IssueManagerShell({
4521
3873
  onPointerDown: shellView.resizeHandle.onPointerDown,
4522
3874
  onPointerMove: shellView.resizeHandle.onPointerMove,
4523
3875
  onPointerUp: shellView.resizeHandle.onPointerUp,
4524
- 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)]" })
3876
+ children: /* @__PURE__ */ jsx15("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)]" })
4525
3877
  }
4526
3878
  ),
4527
- /* @__PURE__ */ jsxs18("div", { className: "relative h-full min-h-0 overflow-hidden bg-transparent", children: [
4528
- /* @__PURE__ */ jsxs18("div", { className: "flex h-full min-h-0 flex-col", children: [
4529
- /* @__PURE__ */ jsx18("div", { className: "min-h-0 flex-1 overflow-hidden", children: shellView.content.isIssueEditing ? /* @__PURE__ */ jsx18(
3879
+ /* @__PURE__ */ jsxs13("div", { className: "relative h-full min-h-0 overflow-hidden bg-transparent @container/issue-manager-content", children: [
3880
+ /* @__PURE__ */ jsxs13("div", { className: "flex h-full min-h-0 flex-col", children: [
3881
+ /* @__PURE__ */ jsx15("div", { className: "min-h-0 flex-1 overflow-hidden", children: shellView.content.isIssueEditing ? /* @__PURE__ */ jsx15(
4530
3882
  IssueManagerIssuePane,
4531
3883
  {
4532
3884
  controller,
4533
3885
  selectedIssue,
4534
3886
  onDismissCreate: onDismissIssueCreate
4535
3887
  }
4536
- ) : shellView.content.isTaskCreating ? /* @__PURE__ */ jsx18(
3888
+ ) : shellView.content.isTaskCreating ? /* @__PURE__ */ jsx15(
4537
3889
  IssueManagerTaskComposerPane,
4538
3890
  {
4539
3891
  controller,
4540
3892
  selectedIssue,
4541
3893
  onCancel: () => controller.setTaskEditorMode("read")
4542
3894
  }
4543
- ) : selectedIssue ? /* @__PURE__ */ jsx18(
3895
+ ) : selectedIssue ? /* @__PURE__ */ jsx15(
4544
3896
  IssueManagerIssuePane,
4545
3897
  {
4546
3898
  controller,
4547
3899
  selectedIssue,
4548
3900
  onDismissCreate: onDismissIssueCreate
4549
3901
  }
4550
- ) : /* @__PURE__ */ jsx18(
3902
+ ) : /* @__PURE__ */ jsx15(
4551
3903
  IssueManagerShellEmptyState,
4552
3904
  {
4553
3905
  controller,
4554
3906
  emptyIllustration
4555
3907
  }
4556
3908
  ) }),
4557
- /* @__PURE__ */ jsx18(
3909
+ /* @__PURE__ */ jsx15(
4558
3910
  IssueManagerBottomBar,
4559
3911
  {
4560
3912
  controller,
4561
3913
  isNarrowLayout: shellView.isNarrowLayout,
4562
3914
  selectedIssue,
4563
- selectedTask,
4564
3915
  visible: shellView.content.showBottomBar
4565
3916
  }
4566
3917
  )
4567
3918
  ] }),
4568
- shellView.content.isTaskDrawerOpen ? /* @__PURE__ */ jsx18(
3919
+ taskDrawerTask ? /* @__PURE__ */ jsx15(
4569
3920
  IssueManagerTaskDrawer,
4570
3921
  {
4571
3922
  controller,
3923
+ isClosing: isTaskDrawerClosing,
4572
3924
  selectedIssue,
4573
- selectedTask,
3925
+ selectedTask: taskDrawerTask,
4574
3926
  onClose: onCloseTaskDrawer
4575
3927
  }
4576
3928
  ) : null
@@ -4583,18 +3935,18 @@ function IssueManagerShellEmptyState({
4583
3935
  controller,
4584
3936
  emptyIllustration
4585
3937
  }) {
4586
- 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: [
3938
+ return /* @__PURE__ */ jsx15("div", { className: "flex h-full min-h-[320px] items-center justify-center px-10 py-10", children: /* @__PURE__ */ jsxs13("div", { className: "grid max-w-[420px] justify-items-center gap-2 text-center", children: [
4587
3939
  emptyIllustration ?? null,
4588
- /* @__PURE__ */ jsx18("h2", { className: "text-lg font-semibold leading-[1.35] text-[var(--text-primary)]", children: controller.copy.t("messages.noIssues") }),
4589
- /* @__PURE__ */ jsx18("p", { className: "max-w-[420px] text-base leading-[1.3] text-[var(--text-secondary)]", children: controller.copy.t("emptyState") }),
4590
- /* @__PURE__ */ jsxs18(
4591
- Button13,
3940
+ /* @__PURE__ */ jsx15("h2", { className: "text-lg font-semibold leading-[1.35] text-[var(--text-primary)]", children: controller.copy.t("messages.noIssues") }),
3941
+ /* @__PURE__ */ jsx15("p", { className: "max-w-[420px] text-base leading-[1.3] text-[var(--text-secondary)]", children: controller.copy.t("emptyState") }),
3942
+ /* @__PURE__ */ jsxs13(
3943
+ Button10,
4592
3944
  {
4593
3945
  className: "mt-2 gap-2",
4594
3946
  type: "button",
4595
3947
  onClick: () => controller.setIssueEditorMode("create"),
4596
3948
  children: [
4597
- /* @__PURE__ */ jsx18(FileCreateIcon4, { size: 16 }),
3949
+ /* @__PURE__ */ jsx15(FileCreateIcon4, { size: 16 }),
4598
3950
  controller.copy.t("actions.createIssue")
4599
3951
  ]
4600
3952
  }
@@ -4602,8 +3954,330 @@ function IssueManagerShellEmptyState({
4602
3954
  ] }) });
4603
3955
  }
4604
3956
 
3957
+ // src/ui/internal/shell/IssueManagerTopicSelector.tsx
3958
+ import { useEffect as useEffect9, useState as useState10 } from "react";
3959
+ import {
3960
+ AddIcon,
3961
+ Button as Button11,
3962
+ CheckIcon as CheckIcon2,
3963
+ ChevronDownIcon as ChevronDownIcon2,
3964
+ ConfirmationDialog as ConfirmationDialog3,
3965
+ Dialog,
3966
+ DialogContent,
3967
+ DialogFooter,
3968
+ DialogHeader,
3969
+ DialogTitle,
3970
+ DeleteIcon,
3971
+ DropdownMenu as DropdownMenu2,
3972
+ DropdownMenuContent as DropdownMenuContent2,
3973
+ DropdownMenuItem as DropdownMenuItem2,
3974
+ DropdownMenuSeparator as DropdownMenuSeparator2,
3975
+ DropdownMenuTrigger as DropdownMenuTrigger2,
3976
+ EditIcon,
3977
+ Input as Input3,
3978
+ MoreHorizontalIcon,
3979
+ PinIcon,
3980
+ Textarea,
3981
+ cn as cn10
3982
+ } from "@nextop-os/ui-system";
3983
+ import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
3984
+ function IssueManagerTopicSelector({
3985
+ activeTopicId,
3986
+ className,
3987
+ copy,
3988
+ onCreateTopic,
3989
+ onDeleteTopic,
3990
+ onSelectTopic,
3991
+ onUpdateTopic,
3992
+ topics
3993
+ }) {
3994
+ const [dialogMode, setDialogMode] = useState10(null);
3995
+ const [deleteTopic, setDeleteTopic] = useState10(
3996
+ null
3997
+ );
3998
+ const [menuOpen, setMenuOpen] = useState10(false);
3999
+ const activeTopic = topics.find((topic) => topic.topicId === activeTopicId);
4000
+ const openTopicDialog = (mode) => {
4001
+ setMenuOpen(false);
4002
+ setDialogMode(mode);
4003
+ };
4004
+ return /* @__PURE__ */ jsxs14(Fragment2, { children: [
4005
+ /* @__PURE__ */ jsxs14(DropdownMenu2, { open: menuOpen, onOpenChange: setMenuOpen, children: [
4006
+ /* @__PURE__ */ jsx16(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs14(
4007
+ Button11,
4008
+ {
4009
+ "aria-label": copy.t("labels.topic"),
4010
+ className: cn10(
4011
+ "h-8 max-w-[220px] min-w-[128px] justify-between gap-2 rounded-md border border-[var(--border-1)] bg-transparent px-2.5 text-[13px] font-normal shadow-none hover:bg-transparent focus-visible:ring-0",
4012
+ className
4013
+ ),
4014
+ type: "button",
4015
+ variant: "ghost",
4016
+ children: [
4017
+ /* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: activeTopic?.title ?? copy.t("labels.topic") }),
4018
+ /* @__PURE__ */ jsx16(ChevronDownIcon2, { className: "size-4 shrink-0 text-[var(--text-tertiary)]" })
4019
+ ]
4020
+ }
4021
+ ) }),
4022
+ /* @__PURE__ */ jsxs14(DropdownMenuContent2, { align: "start", className: "min-w-72", children: [
4023
+ topics.map((topic) => {
4024
+ const isPinned = (topic.pinnedAtUnix ?? 0) > 0;
4025
+ const isActive = topic.topicId === activeTopicId;
4026
+ const pinLabel = isPinned ? copy.t("actions.unpinTopic") : copy.t("actions.pinTopic");
4027
+ return /* @__PURE__ */ jsx16("div", { className: "min-w-0", children: /* @__PURE__ */ jsxs14("div", { className: "relative flex min-h-8 min-w-0 items-center gap-1 rounded-sm pr-1 pl-1 hover:bg-[var(--transparency-block)]", children: [
4028
+ /* @__PURE__ */ jsxs14(
4029
+ "button",
4030
+ {
4031
+ className: "flex h-8 min-w-0 flex-1 cursor-pointer items-center gap-2 rounded-sm pr-2 pl-1 text-left text-sm outline-none",
4032
+ type: "button",
4033
+ onClick: () => {
4034
+ setMenuOpen(false);
4035
+ onSelectTopic(topic.topicId);
4036
+ },
4037
+ children: [
4038
+ /* @__PURE__ */ jsx16("span", { className: "flex size-4 shrink-0 items-center justify-center text-[var(--accent)]", children: isActive ? /* @__PURE__ */ jsx16(CheckIcon2, { className: "size-4" }) : null }),
4039
+ /* @__PURE__ */ jsxs14("span", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
4040
+ /* @__PURE__ */ jsx16("span", { className: "truncate", children: topic.title }),
4041
+ topic.isDefault ? /* @__PURE__ */ jsx16("span", { className: "shrink-0 text-[11px] text-[var(--text-tertiary)]", children: copy.t("labels.topicDefault") }) : null
4042
+ ] })
4043
+ ]
4044
+ }
4045
+ ),
4046
+ /* @__PURE__ */ jsx16(
4047
+ Button11,
4048
+ {
4049
+ "aria-label": pinLabel,
4050
+ className: cn10(
4051
+ "shrink-0 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]",
4052
+ isPinned && "text-[var(--text-primary)]"
4053
+ ),
4054
+ size: "icon-xs",
4055
+ title: pinLabel,
4056
+ type: "button",
4057
+ variant: "ghost",
4058
+ onClick: (event) => {
4059
+ event.preventDefault();
4060
+ event.stopPropagation();
4061
+ onUpdateTopic({
4062
+ pinned: !isPinned,
4063
+ topicId: topic.topicId
4064
+ });
4065
+ },
4066
+ children: /* @__PURE__ */ jsx16(PinIcon, { className: "size-3.5" })
4067
+ }
4068
+ ),
4069
+ /* @__PURE__ */ jsxs14(DropdownMenu2, { modal: false, children: [
4070
+ /* @__PURE__ */ jsx16(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsx16(
4071
+ Button11,
4072
+ {
4073
+ "aria-label": copy.t("actions.moreActions"),
4074
+ className: "shrink-0 text-[var(--text-tertiary)] hover:text-[var(--text-primary)]",
4075
+ size: "icon-xs",
4076
+ title: copy.t("actions.moreActions"),
4077
+ type: "button",
4078
+ variant: "ghost",
4079
+ onClick: (event) => {
4080
+ event.preventDefault();
4081
+ event.stopPropagation();
4082
+ },
4083
+ children: /* @__PURE__ */ jsx16(MoreHorizontalIcon, { className: "size-3.5" })
4084
+ }
4085
+ ) }),
4086
+ /* @__PURE__ */ jsxs14(
4087
+ DropdownMenuContent2,
4088
+ {
4089
+ align: "end",
4090
+ className: "w-32",
4091
+ sideOffset: 6,
4092
+ children: [
4093
+ /* @__PURE__ */ jsxs14(
4094
+ DropdownMenuItem2,
4095
+ {
4096
+ onSelect: (event) => {
4097
+ event.preventDefault();
4098
+ openTopicDialog({
4099
+ kind: "edit",
4100
+ topic
4101
+ });
4102
+ },
4103
+ children: [
4104
+ /* @__PURE__ */ jsx16(EditIcon, { className: "size-3.5" }),
4105
+ /* @__PURE__ */ jsx16("span", { children: copy.t("actions.editTopic") })
4106
+ ]
4107
+ }
4108
+ ),
4109
+ /* @__PURE__ */ jsxs14(
4110
+ DropdownMenuItem2,
4111
+ {
4112
+ disabled: topic.isDefault,
4113
+ variant: "destructive",
4114
+ onSelect: (event) => {
4115
+ event.preventDefault();
4116
+ setMenuOpen(false);
4117
+ setDeleteTopic(topic);
4118
+ },
4119
+ children: [
4120
+ /* @__PURE__ */ jsx16(DeleteIcon, { className: "size-3.5" }),
4121
+ /* @__PURE__ */ jsx16("span", { children: copy.t("actions.delete") })
4122
+ ]
4123
+ }
4124
+ )
4125
+ ]
4126
+ }
4127
+ )
4128
+ ] })
4129
+ ] }) }, topic.topicId);
4130
+ }),
4131
+ topics.length === 0 ? /* @__PURE__ */ jsx16("div", { className: "px-3 py-2 text-xs leading-4 text-[var(--text-tertiary)]", children: copy.t("messages.topicListEmpty") }) : null,
4132
+ /* @__PURE__ */ jsx16(DropdownMenuSeparator2, {}),
4133
+ /* @__PURE__ */ jsx16("div", { className: "p-1", children: /* @__PURE__ */ jsxs14(
4134
+ Button11,
4135
+ {
4136
+ className: "w-full justify-start gap-2 px-2 text-left",
4137
+ size: "sm",
4138
+ type: "button",
4139
+ variant: "ghost",
4140
+ onClick: (event) => {
4141
+ event.preventDefault();
4142
+ event.stopPropagation();
4143
+ },
4144
+ onPointerDown: (event) => {
4145
+ event.preventDefault();
4146
+ event.stopPropagation();
4147
+ openTopicDialog({
4148
+ kind: "create",
4149
+ topic: null
4150
+ });
4151
+ },
4152
+ children: [
4153
+ /* @__PURE__ */ jsx16(AddIcon, { className: "size-3.5" }),
4154
+ /* @__PURE__ */ jsx16("span", { className: "truncate", children: copy.t("actions.createTopic") })
4155
+ ]
4156
+ }
4157
+ ) })
4158
+ ] })
4159
+ ] }),
4160
+ /* @__PURE__ */ jsx16(
4161
+ IssueManagerTopicDialog,
4162
+ {
4163
+ copy,
4164
+ mode: dialogMode,
4165
+ open: dialogMode !== null,
4166
+ onCreateTopic,
4167
+ onOpenChange: (open) => {
4168
+ if (!open) {
4169
+ setDialogMode(null);
4170
+ }
4171
+ },
4172
+ onUpdateTopic
4173
+ }
4174
+ ),
4175
+ /* @__PURE__ */ jsx16(
4176
+ ConfirmationDialog3,
4177
+ {
4178
+ cancelLabel: copy.t("actions.cancel"),
4179
+ confirmLabel: copy.t("actions.delete"),
4180
+ description: deleteTopic?.title,
4181
+ open: deleteTopic !== null,
4182
+ title: copy.t("confirmations.deleteTopic"),
4183
+ tone: "destructive",
4184
+ onConfirm: () => {
4185
+ const topicId = deleteTopic?.topicId;
4186
+ setDeleteTopic(null);
4187
+ if (topicId) {
4188
+ onDeleteTopic(topicId);
4189
+ }
4190
+ },
4191
+ onOpenChange: (open) => {
4192
+ if (!open) {
4193
+ setDeleteTopic(null);
4194
+ }
4195
+ }
4196
+ }
4197
+ )
4198
+ ] });
4199
+ }
4200
+ function IssueManagerTopicDialog({
4201
+ copy,
4202
+ mode,
4203
+ onCreateTopic,
4204
+ onOpenChange,
4205
+ onUpdateTopic,
4206
+ open
4207
+ }) {
4208
+ const [summaryDraft, setSummaryDraft] = useState10("");
4209
+ const [titleDraft, setTitleDraft] = useState10("");
4210
+ useEffect9(() => {
4211
+ setTitleDraft(mode?.topic?.title ?? "");
4212
+ setSummaryDraft(mode?.topic?.summary ?? "");
4213
+ }, [mode]);
4214
+ const title = titleDraft.trim();
4215
+ const dialogTitle = mode?.kind === "edit" ? copy.t("labels.editTopicDialogTitle") : copy.t("labels.createTopicDialogTitle");
4216
+ const submit = (event) => {
4217
+ event.preventDefault();
4218
+ if (!mode || !title) {
4219
+ return;
4220
+ }
4221
+ if (mode.kind === "edit") {
4222
+ onUpdateTopic({
4223
+ summary: summaryDraft,
4224
+ title,
4225
+ topicId: mode.topic.topicId
4226
+ });
4227
+ } else {
4228
+ onCreateTopic({
4229
+ summary: summaryDraft,
4230
+ title
4231
+ });
4232
+ }
4233
+ onOpenChange(false);
4234
+ };
4235
+ return /* @__PURE__ */ jsx16(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs14(DialogContent, { className: "sm:max-w-[420px]", children: [
4236
+ /* @__PURE__ */ jsx16(DialogHeader, { children: /* @__PURE__ */ jsx16(DialogTitle, { children: dialogTitle }) }),
4237
+ /* @__PURE__ */ jsxs14("form", { className: "grid gap-3", onSubmit: submit, children: [
4238
+ /* @__PURE__ */ jsxs14("label", { className: "grid gap-1.5", children: [
4239
+ /* @__PURE__ */ jsx16("span", { className: "text-xs font-medium leading-4 text-[var(--text-secondary)]", children: copy.t("labels.topicTitle") }),
4240
+ /* @__PURE__ */ jsx16(
4241
+ Input3,
4242
+ {
4243
+ autoFocus: true,
4244
+ placeholder: copy.t("labels.topicTitle"),
4245
+ value: titleDraft,
4246
+ onChange: (event) => setTitleDraft(event.target.value)
4247
+ }
4248
+ )
4249
+ ] }),
4250
+ /* @__PURE__ */ jsxs14("label", { className: "grid gap-1.5", children: [
4251
+ /* @__PURE__ */ jsx16("span", { className: "text-xs font-medium leading-4 text-[var(--text-secondary)]", children: copy.t("labels.topicSummary") }),
4252
+ /* @__PURE__ */ jsx16(
4253
+ Textarea,
4254
+ {
4255
+ className: "min-h-24 resize-none",
4256
+ placeholder: copy.t("labels.topicSummary"),
4257
+ value: summaryDraft,
4258
+ onChange: (event) => setSummaryDraft(event.target.value)
4259
+ }
4260
+ )
4261
+ ] }),
4262
+ /* @__PURE__ */ jsxs14(DialogFooter, { className: "pt-2", children: [
4263
+ /* @__PURE__ */ jsx16(
4264
+ Button11,
4265
+ {
4266
+ size: "dialog",
4267
+ type: "button",
4268
+ variant: "ghost",
4269
+ onClick: () => onOpenChange(false),
4270
+ children: copy.t("actions.cancel")
4271
+ }
4272
+ ),
4273
+ /* @__PURE__ */ jsx16(Button11, { disabled: !title, size: "dialog", type: "submit", children: copy.t("actions.saveTopic") })
4274
+ ] })
4275
+ ] })
4276
+ ] }) });
4277
+ }
4278
+
4605
4279
  // src/ui/IssueManagerNode.tsx
4606
- import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
4280
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
4607
4281
  function IssueManagerNode({
4608
4282
  emptyIllustration,
4609
4283
  feature,
@@ -4623,7 +4297,27 @@ function IssueManagerNode({
4623
4297
  state,
4624
4298
  workspaceId
4625
4299
  });
4626
- return /* @__PURE__ */ jsxs19(
4300
+ useEffect10(() => {
4301
+ dispatchIssueManagerTopicHeaderState({
4302
+ activeTopicId: controller.nodeState.activeTopicId ?? null,
4303
+ nodeId,
4304
+ topics: controller.topics.value
4305
+ });
4306
+ }, [controller.nodeState.activeTopicId, controller.topics.value, nodeId]);
4307
+ useIssueManagerTopicHeaderCommandSync({
4308
+ nodeId,
4309
+ onCreateTopic: (topicInput) => {
4310
+ void controller.createTopic(topicInput);
4311
+ },
4312
+ onDeleteTopic: (topicId) => {
4313
+ void controller.deleteTopic(topicId);
4314
+ },
4315
+ onSelectTopic: controller.selectTopic,
4316
+ onUpdateTopic: (topicInput) => {
4317
+ void controller.updateTopic(topicInput);
4318
+ }
4319
+ });
4320
+ return /* @__PURE__ */ jsxs15(
4627
4321
  "section",
4628
4322
  {
4629
4323
  "aria-label": controller.copy.t("title"),
@@ -4631,7 +4325,7 @@ function IssueManagerNode({
4631
4325
  "data-issue-manager-node-id": nodeId,
4632
4326
  "data-issue-manager-workspace-id": workspaceId,
4633
4327
  children: [
4634
- /* @__PURE__ */ jsx19(
4328
+ /* @__PURE__ */ jsx17(
4635
4329
  IssueManagerShell,
4636
4330
  {
4637
4331
  controller,
@@ -4642,8 +4336,8 @@ function IssueManagerNode({
4642
4336
  selectedTask
4643
4337
  }
4644
4338
  ),
4645
- /* @__PURE__ */ jsx19(
4646
- IssueManagerReferencePicker,
4339
+ /* @__PURE__ */ jsx17(
4340
+ WorkspaceFileReferencePicker,
4647
4341
  {
4648
4342
  copy: controller.copy,
4649
4343
  fileAdapter: feature.fileAdapter,
@@ -4658,6 +4352,7 @@ function IssueManagerNode({
4658
4352
  );
4659
4353
  }
4660
4354
  function IssueManagerNodeHeader({
4355
+ activeTopicId = null,
4661
4356
  className,
4662
4357
  copy,
4663
4358
  defaultActions,
@@ -4675,19 +4370,64 @@ function IssueManagerNodeHeader({
4675
4370
  nodeId,
4676
4371
  onToggleSidebar
4677
4372
  });
4678
- return /* @__PURE__ */ jsxs19(
4373
+ const topicState = useIssueManagerTopicHeaderStateSync({
4374
+ activeTopicId,
4375
+ nodeId
4376
+ });
4377
+ return /* @__PURE__ */ jsxs15(
4679
4378
  "header",
4680
4379
  {
4681
4380
  ...headerProps,
4682
- className: cn12(
4381
+ className: cn11(
4683
4382
  "flex h-full min-h-0 items-center justify-between gap-3 bg-[var(--background-panel)] px-2 pl-3",
4684
4383
  className
4685
4384
  ),
4686
4385
  children: [
4687
- /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 items-center gap-2", children: [
4688
- /* @__PURE__ */ jsx19("span", { className: "min-w-0 truncate text-[13px] font-semibold leading-5 text-[var(--text-primary)]", children: title?.trim() || copy.t("title") }),
4689
- /* @__PURE__ */ jsx19(
4690
- Button14,
4386
+ /* @__PURE__ */ jsxs15("div", { className: "flex min-w-0 items-center gap-2", children: [
4387
+ /* @__PURE__ */ jsx17("span", { className: "min-w-0 truncate text-[13px] font-semibold leading-5 text-[var(--text-primary)]", children: title?.trim() || copy.t("title") }),
4388
+ /* @__PURE__ */ jsx17(
4389
+ "div",
4390
+ {
4391
+ className: "flex min-w-0 flex-none",
4392
+ onDoubleClick: (event) => event.stopPropagation(),
4393
+ onPointerDown: (event) => event.stopPropagation(),
4394
+ children: /* @__PURE__ */ jsx17(
4395
+ IssueManagerTopicSelector,
4396
+ {
4397
+ activeTopicId: topicState.activeTopicId,
4398
+ className: "flex-none",
4399
+ copy,
4400
+ topics: topicState.topics,
4401
+ onCreateTopic: (input) => {
4402
+ dispatchIssueManagerTopicCreate({
4403
+ input,
4404
+ nodeId
4405
+ });
4406
+ },
4407
+ onDeleteTopic: (topicId) => {
4408
+ dispatchIssueManagerTopicDelete({
4409
+ nodeId,
4410
+ topicId
4411
+ });
4412
+ },
4413
+ onSelectTopic: (topicId) => {
4414
+ dispatchIssueManagerTopicSelection({
4415
+ nodeId,
4416
+ topicId
4417
+ });
4418
+ },
4419
+ onUpdateTopic: (input) => {
4420
+ dispatchIssueManagerTopicUpdate({
4421
+ input,
4422
+ nodeId
4423
+ });
4424
+ }
4425
+ }
4426
+ )
4427
+ }
4428
+ ),
4429
+ /* @__PURE__ */ jsx17(
4430
+ Button12,
4691
4431
  {
4692
4432
  "aria-label": toggleLabel,
4693
4433
  className: "cursor-pointer rounded-md",
@@ -4703,11 +4443,11 @@ function IssueManagerNodeHeader({
4703
4443
  },
4704
4444
  onDoubleClick: (event) => event.stopPropagation(),
4705
4445
  onPointerDown: (event) => event.stopPropagation(),
4706
- children: /* @__PURE__ */ jsx19(PanelIcon, { className: "size-[18px]" })
4446
+ children: /* @__PURE__ */ jsx17(PanelIcon, { className: "size-[18px]" })
4707
4447
  }
4708
4448
  )
4709
4449
  ] }),
4710
- /* @__PURE__ */ jsx19(
4450
+ /* @__PURE__ */ jsx17(
4711
4451
  "div",
4712
4452
  {
4713
4453
  className: "flex flex-none items-center gap-1",
@@ -4726,4 +4466,4 @@ export {
4726
4466
  IssueManagerNode,
4727
4467
  IssueManagerNodeHeader
4728
4468
  };
4729
- //# sourceMappingURL=chunk-5V4DIEWZ.js.map
4469
+ //# sourceMappingURL=chunk-UT34M3FS.js.map