@nextop-os/workspace-issue-manager 0.0.26 → 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-34KSO5F6.js → chunk-I7SVY3KV.js} +159 -25
  2. package/dist/chunk-I7SVY3KV.js.map +1 -0
  3. package/dist/{chunk-JOUBY4J6.js → chunk-MJXXZPDJ.js} +111 -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-RJ6HZRQU.js → chunk-SUCZIXKI.js} +66 -20
  8. package/dist/chunk-SUCZIXKI.js.map +1 -0
  9. package/dist/{chunk-K3F67IRA.js → chunk-UT34M3FS.js} +1636 -1679
  10. package/dist/chunk-UT34M3FS.js.map +1 -0
  11. package/dist/contracts/index.d.ts +100 -57
  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 -5
  31. package/dist/chunk-34KSO5F6.js.map +0 -1
  32. package/dist/chunk-JOUBY4J6.js.map +0 -1
  33. package/dist/chunk-K3F67IRA.js.map +0 -1
  34. package/dist/chunk-RJ6HZRQU.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-34KSO5F6.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-RJ6HZRQU.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,800 +1615,60 @@ 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";
1405
- var defaultDirectoryPath = "/";
1406
- function useIssueManagerReferencePickerView({
1407
- fileAdapter,
1408
- onClose,
1409
- onConfirm,
1410
- open,
1411
- workspaceId
1412
- }) {
1413
- const [searchQuery, setSearchQuery] = useState2("");
1414
- const [browseRootPath, setBrowseRootPath] = useState2(null);
1415
- const [searchEntries, setSearchEntries] = useState2([]);
1416
- const [directoryStateByPath, setDirectoryStateByPath] = useState2({});
1417
- const [expandedFolderPaths, setExpandedFolderPaths] = useState2({});
1418
- const [focusedPath, setFocusedPath] = useState2(null);
1419
- const [isLoading, setIsLoading] = useState2(false);
1420
- const [selectedRefs, setSelectedRefs] = useState2(
1421
- []
1422
- );
1423
- const supportsSearch = hasFileAdapterMethod2(fileAdapter, "searchReferences");
1424
- const supportsTreeSnapshot = hasFileAdapterMethod2(
1425
- fileAdapter,
1426
- "loadReferenceTree"
1427
- );
1428
- const mode = searchQuery.trim().length > 0 && supportsSearch ? "search" : "browse";
1429
- const browseDirectoryLoaded = browseRootPath !== null && directoryStateByPath[normalizeDirectoryPath(browseRootPath)]?.loaded === true;
1430
- const finalizeRequestedReferences = useEffectEvent2(
1431
- (refs) => {
1432
- onConfirm(uniqueIssueManagerFileReferences(refs));
1433
- onClose();
1434
- }
1435
- );
1436
- const readDirectoryListing = async (path) => {
1437
- if (!fileAdapter?.listDirectory) {
1438
- return null;
1439
- }
1440
- const listing = await fileAdapter.listDirectory({
1441
- path: path ?? void 0,
1442
- workspaceId
1443
- });
1444
- return {
1445
- displayPath: listing.directoryPath || listing.rootPath || path || defaultDirectoryPath,
1446
- entries: uniqueIssueManagerFileReferences(listing.entries),
1447
- normalizedPath: normalizeDirectoryPath(
1448
- listing.directoryPath || listing.rootPath || path || defaultDirectoryPath
1449
- )
1450
- };
1451
- };
1452
- useEffect3(() => {
1453
- if (!open) {
1454
- return;
1455
- }
1456
- setSearchQuery("");
1457
- setBrowseRootPath(null);
1458
- setSearchEntries([]);
1459
- setDirectoryStateByPath({});
1460
- setExpandedFolderPaths({});
1461
- setFocusedPath(null);
1462
- setSelectedRefs([]);
1463
- }, [open]);
1464
- useEffect3(() => {
1465
- if (!open || !fileAdapter) {
1466
- return;
1467
- }
1468
- let canceled = false;
1469
- const load = async () => {
1470
- setIsLoading(true);
1471
- try {
1472
- if (mode === "search" && fileAdapter.searchReferences) {
1473
- const refs = await fileAdapter.searchReferences({
1474
- query: searchQuery.trim(),
1475
- workspaceId
1476
- });
1477
- if (!canceled) {
1478
- setSearchEntries(uniqueIssueManagerFileReferences(refs));
1479
- }
1480
- return;
1481
- }
1482
- if (mode === "browse" && (fileAdapter.listDirectory || fileAdapter.loadReferenceTree)) {
1483
- if (browseDirectoryLoaded && browseRootPath) {
1484
- return;
1485
- }
1486
- if (supportsTreeSnapshot && fileAdapter.loadReferenceTree) {
1487
- const snapshot = await fileAdapter.loadReferenceTree({
1488
- path: browseRootPath ?? void 0,
1489
- prefetchBudgetMs: 500,
1490
- prefetchDepth: 4,
1491
- workspaceId
1492
- });
1493
- if (!canceled) {
1494
- setBrowseRootPath(
1495
- normalizeDirectoryPath(snapshot.directory.directoryPath)
1496
- );
1497
- setDirectoryStateByPath(
1498
- createReferenceDirectoryStateFromSnapshot(snapshot)
1499
- );
1500
- }
1501
- return;
1502
- }
1503
- const listing = await readDirectoryListing(browseRootPath);
1504
- if (!listing) {
1505
- return;
1506
- }
1507
- if (!canceled) {
1508
- setBrowseRootPath(listing.normalizedPath);
1509
- setDirectoryStateByPath((current) => ({
1510
- ...current,
1511
- [listing.normalizedPath]: {
1512
- displayPath: listing.displayPath,
1513
- entries: listing.entries,
1514
- loaded: true,
1515
- loading: false
1516
- }
1517
- }));
1518
- }
1519
- return;
1520
- }
1521
- if (fileAdapter.requestReferences) {
1522
- const refs = await fileAdapter.requestReferences({ workspaceId });
1523
- if (!canceled) {
1524
- finalizeRequestedReferences(refs);
1525
- }
1526
- return;
1527
- }
1528
- if (!canceled) {
1529
- setSearchEntries([]);
1530
- }
1531
- } finally {
1532
- if (!canceled) {
1533
- setIsLoading(false);
1534
- }
1535
- }
1536
- };
1537
- void load();
1538
- return () => {
1539
- canceled = true;
1540
- };
1541
- }, [
1542
- browseDirectoryLoaded,
1543
- browseRootPath,
1544
- fileAdapter,
1545
- finalizeRequestedReferences,
1546
- mode,
1547
- open,
1548
- searchQuery,
1549
- supportsTreeSnapshot,
1550
- workspaceId
1551
- ]);
1552
- const browseRootEntries = useMemo3(
1553
- () => browseRootPath ? directoryStateByPath[normalizeDirectoryPath(browseRootPath)]?.entries ?? [] : [],
1554
- [browseRootPath, directoryStateByPath]
1555
- );
1556
- const visibleEntries = useMemo3(
1557
- () => mode === "search" ? searchEntries : collectVisibleTreeEntries(
1558
- browseRootEntries,
1559
- directoryStateByPath,
1560
- expandedFolderPaths
1561
- ),
1562
- [
1563
- browseRootEntries,
1564
- directoryStateByPath,
1565
- expandedFolderPaths,
1566
- mode,
1567
- searchEntries
1568
- ]
1569
- );
1570
- useEffect3(() => {
1571
- if (!open) {
1572
- return;
1573
- }
1574
- setFocusedPath((current) => {
1575
- if (current && visibleEntries.some((entry) => entry.path === current)) {
1576
- return current;
1577
- }
1578
- return visibleEntries[0]?.path ?? null;
1579
- });
1580
- }, [open, visibleEntries]);
1581
- const focusedEntry = visibleEntries.find((entry) => entry.path === focusedPath) ?? selectedRefs.find((entry) => entry.path === focusedPath) ?? null;
1582
- const toggleRef = (ref) => {
1583
- setSelectedRefs((current) => {
1584
- const existing = current.some((item) => item.path === ref.path);
1585
- return existing ? current.filter((item) => item.path !== ref.path) : uniqueIssueManagerFileReferences([...current, ref]);
1586
- });
1587
- };
1588
- const loadFolderChildren = async (folder) => {
1589
- const folderKey = normalizeDirectoryPath(folder.path);
1590
- if (directoryStateByPath[folderKey]?.loaded) {
1591
- return;
1592
- }
1593
- setDirectoryStateByPath((current) => ({
1594
- ...current,
1595
- [folderKey]: {
1596
- displayPath: folder.path,
1597
- entries: current[folderKey]?.entries ?? [],
1598
- loaded: current[folderKey]?.loaded ?? false,
1599
- loading: true
1600
- }
1601
- }));
1602
- try {
1603
- const listing = await readDirectoryListing(folderKey);
1604
- if (!listing) {
1605
- return;
1606
- }
1607
- setDirectoryStateByPath((current) => ({
1608
- ...current,
1609
- [folderKey]: {
1610
- displayPath: listing.displayPath,
1611
- entries: listing.entries,
1612
- loaded: true,
1613
- loading: false
1614
- }
1615
- }));
1616
- } catch {
1617
- setDirectoryStateByPath((current) => ({
1618
- ...current,
1619
- [folderKey]: {
1620
- displayPath: current[folderKey]?.displayPath ?? folder.path,
1621
- entries: current[folderKey]?.entries ?? [],
1622
- loaded: current[folderKey]?.loaded ?? false,
1623
- loading: false
1624
- }
1625
- }));
1626
- }
1627
- };
1628
- const toggleFolder = (entry) => {
1629
- const folderKey = normalizeDirectoryPath(entry.path);
1630
- const childState = directoryStateByPath[folderKey];
1631
- const nextExpanded = !(expandedFolderPaths[folderKey] ?? false);
1632
- setExpandedFolderPaths((current) => ({
1633
- ...current,
1634
- [folderKey]: nextExpanded
1635
- }));
1636
- if (nextExpanded && !childState?.loaded && !childState?.loading) {
1637
- void loadFolderChildren(entry);
1638
- }
1639
- };
1640
- return {
1641
- browseRootEntries,
1642
- directoryStateByPath,
1643
- expandedFolderPaths,
1644
- focusedEntry,
1645
- focusedPath,
1646
- isLoading,
1647
- mode,
1648
- searchQuery,
1649
- selectedRefs,
1650
- visibleEntries,
1651
- setFocusedPath,
1652
- setSearchQuery,
1653
- toggleFolder,
1654
- toggleRef
1655
- };
1656
- }
1657
- function hasFileAdapterMethod2(fileAdapter, methodName) {
1658
- return typeof Reflect.get(fileAdapter ?? {}, methodName) === "function";
1659
- }
1618
+ // src/ui/react/index.ts
1619
+ import {
1620
+ useWorkspaceFileReferencePickerView
1621
+ } from "@nextop-os/workspace-file-reference/react";
1660
1622
 
1661
1623
  // src/ui/IssueManagerNode.tsx
1662
- import { Button as Button14, PanelIcon, cn as cn12 } from "@nextop-os/ui-system";
1663
-
1664
- // src/ui/internal/reference/IssueManagerReferencePicker.tsx
1665
- import { createPortal } from "react-dom";
1666
1624
  import {
1667
- Button as Button3,
1668
- Card,
1669
- CardContent,
1670
- CardHeader,
1671
- CardTitle,
1672
- CloseIcon,
1673
- cn as cn2
1674
- } from "@nextop-os/ui-system";
1675
-
1676
- // src/ui/internal/reference/IssueManagerReferencePickerSections.tsx
1677
- import {
1678
- Badge,
1679
- Button as Button2,
1680
- FileIcon as FileIcon2,
1681
- FolderFilledIcon as FolderFilledIcon2
1682
- } from "@nextop-os/ui-system";
1683
-
1684
- // src/ui/internal/reference/IssueManagerReferencePickerTree.tsx
1685
- import { useEffect as useEffect4, useState as useState3 } from "react";
1686
- import {
1687
- ArrowRightIcon,
1688
- Button,
1689
- CheckIcon,
1690
- FileIcon,
1691
- FolderFilledIcon,
1692
- Input,
1693
- ScrollArea,
1694
- SearchIcon,
1695
- Spinner,
1696
- cn
1697
- } from "@nextop-os/ui-system";
1698
- import { AddIcon as AddLinedIcon } from "@nextop-os/ui-system/icons";
1699
- import { jsx, jsxs } from "react/jsx-runtime";
1700
- var issueManagerReferenceTreeIndent = 24;
1701
- var issueManagerReferenceTreeCollapseDurationMs = 200;
1702
- function IssueManagerReferencePickerBrowserPane({
1703
- browseRootEntries,
1704
- copy,
1705
- directoryStateByPath,
1706
- expandedFolderPaths,
1707
- focusedPath,
1708
- isLoading,
1709
- mode,
1710
- searchQuery,
1711
- selectedRefs,
1712
- setSearchQuery,
1713
- visibleEntries,
1714
- onFocusPath,
1715
- onToggleFolder,
1716
- onToggleRef
1717
- }) {
1718
- 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: [
1719
- /* @__PURE__ */ jsx("div", { className: "border-b border-[var(--line-1)] p-3", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1720
- /* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-[var(--text-tertiary)]" }),
1721
- /* @__PURE__ */ jsx(
1722
- Input,
1723
- {
1724
- className: "pl-9",
1725
- placeholder: copy.t("referencePicker.searchPlaceholder"),
1726
- value: searchQuery,
1727
- onChange: (event) => setSearchQuery(event.target.value)
1728
- }
1729
- )
1730
- ] }) }),
1731
- 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(
1732
- IssueManagerReferencePickerTreeEntry,
1733
- {
1734
- childDepth: 1,
1735
- copy,
1736
- directoryStateByPath,
1737
- entry,
1738
- expandedFolderPaths,
1739
- focusedPath,
1740
- selectedRefs,
1741
- onFocusPath,
1742
- onToggleFolder,
1743
- onToggleRef
1744
- },
1745
- entry.path
1746
- )) }) : visibleEntries.map((entry) => /* @__PURE__ */ jsx(
1747
- IssueManagerReferencePickerSearchEntry,
1748
- {
1749
- entry,
1750
- focused: focusedPath === entry.path,
1751
- selected: selectedRefs.some(
1752
- (item) => item.path === entry.path
1753
- ),
1754
- onFocusPath,
1755
- onToggleRef
1756
- },
1757
- entry.path
1758
- )) }) })
1759
- ] });
1760
- }
1761
- function IssueManagerReferencePickerTreeEntry({
1762
- childDepth,
1763
- copy,
1764
- directoryStateByPath,
1765
- entry,
1766
- expandedFolderPaths,
1767
- focusedPath,
1768
- selectedRefs,
1769
- onFocusPath,
1770
- onToggleFolder,
1771
- onToggleRef
1772
- }) {
1773
- const selected = selectedRefs.some((item) => item.path === entry.path);
1774
- const focused = focusedPath === entry.path;
1775
- const isFolder = entry.kind === "folder";
1776
- const folderKey = normalizeDirectoryPath(entry.path);
1777
- const expanded = expandedFolderPaths[folderKey] ?? false;
1778
- const childState = directoryStateByPath[folderKey];
1779
- const childEntries = childState?.entries ?? [];
1780
- const [shouldRenderChildContent, setShouldRenderChildContent] = useState3(expanded);
1781
- useEffect4(() => {
1782
- if (expanded) {
1783
- setShouldRenderChildContent(true);
1784
- return;
1785
- }
1786
- const timeoutId = window.setTimeout(() => {
1787
- setShouldRenderChildContent(false);
1788
- }, issueManagerReferenceTreeCollapseDurationMs);
1789
- return () => window.clearTimeout(timeoutId);
1790
- }, [expanded]);
1791
- const shouldBuildChildContent = expanded || shouldRenderChildContent;
1792
- const childContent = shouldBuildChildContent ? childState?.loading ? /* @__PURE__ */ jsxs(
1793
- "div",
1794
- {
1795
- className: "flex items-center gap-2 px-2 py-2 text-xs text-[var(--text-secondary)]",
1796
- style: {
1797
- paddingLeft: `${childDepth * issueManagerReferenceTreeIndent + 12}px`
1798
- },
1799
- children: [
1800
- /* @__PURE__ */ jsx(Spinner, { className: "text-[var(--text-secondary)]", size: 14 }),
1801
- /* @__PURE__ */ jsx("span", { children: copy.t("referencePicker.loading") })
1802
- ]
1803
- }
1804
- ) : childEntries.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: childEntries.map((childEntry) => /* @__PURE__ */ jsx(
1805
- IssueManagerReferencePickerTreeEntry,
1806
- {
1807
- childDepth: childDepth + 1,
1808
- copy,
1809
- directoryStateByPath,
1810
- entry: childEntry,
1811
- expandedFolderPaths,
1812
- focusedPath,
1813
- selectedRefs,
1814
- onFocusPath,
1815
- onToggleFolder,
1816
- onToggleRef
1817
- },
1818
- childEntry.path
1819
- )) }) : childState?.loaded ? /* @__PURE__ */ jsx(
1820
- "div",
1821
- {
1822
- className: "px-2 py-2 text-xs text-[var(--text-secondary)]",
1823
- style: {
1824
- paddingLeft: `${childDepth * issueManagerReferenceTreeIndent + 12}px`
1825
- },
1826
- children: copy.t("referencePicker.emptyDirectory")
1827
- }
1828
- ) : null : null;
1829
- return /* @__PURE__ */ jsxs("div", { children: [
1830
- /* @__PURE__ */ jsxs(
1831
- "div",
1832
- {
1833
- className: cn(
1834
- "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-2 rounded-[6px] py-1.5 pr-1 pl-2 transition-colors",
1835
- focused || selected ? "bg-transparency-block" : "hover:bg-transparency-block"
1836
- ),
1837
- style: {
1838
- paddingLeft: `${(childDepth - 1) * issueManagerReferenceTreeIndent + 8}px`
1839
- },
1840
- children: [
1841
- isFolder ? /* @__PURE__ */ jsx(
1842
- "button",
1843
- {
1844
- "aria-label": resolveIssueManagerReferenceLabel(entry),
1845
- className: "grid size-5 shrink-0 place-items-center rounded-sm text-[var(--text-secondary)] hover:bg-[var(--transparency-hover)]",
1846
- type: "button",
1847
- onClick: () => onToggleFolder(entry),
1848
- children: /* @__PURE__ */ jsx(
1849
- ArrowRightIcon,
1850
- {
1851
- className: cn(
1852
- "size-3.5 transition-transform",
1853
- expanded && "rotate-90"
1854
- )
1855
- }
1856
- )
1857
- }
1858
- ) : /* @__PURE__ */ jsx("span", { className: "block size-5 shrink-0" }),
1859
- /* @__PURE__ */ jsxs(
1860
- "button",
1861
- {
1862
- className: "flex min-w-0 items-center gap-2 text-left",
1863
- type: "button",
1864
- onClick: () => {
1865
- onFocusPath(entry.path);
1866
- if (entry.kind === "folder") {
1867
- onToggleFolder(entry);
1868
- }
1869
- },
1870
- children: [
1871
- 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)]" }),
1872
- /* @__PURE__ */ jsx("span", { className: "truncate text-sm text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(entry) })
1873
- ]
1874
- }
1875
- ),
1876
- /* @__PURE__ */ jsx(
1877
- Button,
1878
- {
1879
- "aria-label": resolveIssueManagerReferenceLabel(entry),
1880
- "aria-pressed": selected,
1881
- size: "icon-sm",
1882
- type: "button",
1883
- variant: "ghost",
1884
- onClick: () => {
1885
- onFocusPath(entry.path);
1886
- onToggleRef(entry);
1887
- },
1888
- children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(AddLinedIcon, { size: 16 })
1889
- }
1890
- )
1891
- ]
1892
- }
1893
- ),
1894
- isFolder ? /* @__PURE__ */ jsx(
1895
- "div",
1896
- {
1897
- className: cn(
1898
- "grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none",
1899
- expanded ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
1900
- childContent && "mt-[2px]"
1901
- ),
1902
- children: /* @__PURE__ */ jsx(
1903
- "div",
1904
- {
1905
- "aria-hidden": expanded ? void 0 : "true",
1906
- className: cn(
1907
- "min-h-0 overflow-hidden transition-[opacity,transform] duration-200 ease-out motion-reduce:transition-none",
1908
- expanded ? "translate-y-0 opacity-100" : "-translate-y-1 opacity-0"
1909
- ),
1910
- inert: expanded ? void 0 : true,
1911
- children: childContent
1912
- }
1913
- )
1914
- }
1915
- ) : null
1916
- ] });
1917
- }
1918
- function IssueManagerReferencePickerSearchEntry({
1919
- entry,
1920
- focused,
1921
- selected,
1922
- onFocusPath,
1923
- onToggleRef
1924
- }) {
1925
- const isFolder = entry.kind === "folder";
1926
- return /* @__PURE__ */ jsxs(
1927
- "div",
1928
- {
1929
- className: cn(
1930
- "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-[6px] border py-2.5 pr-1 pl-3 transition-colors",
1931
- focused || selected ? "border-border bg-transparency-block" : "border-transparent bg-transparent hover:border-border/70 hover:bg-transparency-block"
1932
- ),
1933
- children: [
1934
- /* @__PURE__ */ jsxs(
1935
- "button",
1936
- {
1937
- className: "flex min-w-0 items-center gap-3 text-left",
1938
- type: "button",
1939
- onClick: () => onFocusPath(entry.path),
1940
- children: [
1941
- /* @__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)]" }) }),
1942
- /* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
1943
- /* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(entry) }),
1944
- /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-[var(--text-secondary)]", children: entry.path })
1945
- ] })
1946
- ]
1947
- }
1948
- ),
1949
- /* @__PURE__ */ jsx(
1950
- Button,
1951
- {
1952
- "aria-label": resolveIssueManagerReferenceLabel(entry),
1953
- "aria-pressed": selected,
1954
- size: "icon-sm",
1955
- type: "button",
1956
- variant: "ghost",
1957
- onClick: () => {
1958
- onFocusPath(entry.path);
1959
- onToggleRef(entry);
1960
- },
1961
- children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(AddLinedIcon, { size: 16 })
1962
- }
1963
- )
1964
- ]
1965
- }
1966
- );
1967
- }
1968
- function IssueManagerReferencePickerFeedback({
1969
- children
1970
- }) {
1971
- 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 });
1972
- }
1973
- function resolveIssueManagerReferenceLabel(ref) {
1974
- return ref.displayName || ref.path.split("/").filter(Boolean).at(-1) || ref.path;
1975
- }
1976
-
1977
- // src/ui/internal/reference/IssueManagerReferencePickerSections.tsx
1978
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1979
- var issueManagerReferencePickerSelectedBadgeClassName = "max-w-[14rem] rounded-[4px] border-transparent bg-[var(--transparency-block)] text-[var(--text-primary)]";
1980
- function IssueManagerReferencePickerPreviewPane({
1981
- copy,
1982
- focusedEntry,
1983
- mode
1984
- }) {
1985
- 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: [
1986
- /* @__PURE__ */ jsxs2("div", { className: "flex min-h-32 flex-col items-center justify-center space-y-4 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", children: [
1987
- focusedEntry.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)]" }),
1988
- /* @__PURE__ */ jsx2("p", { className: "mx-auto max-w-[24ch] text-sm leading-5 text-[var(--text-secondary)] [overflow-wrap:anywhere]", children: focusedEntry.kind === "folder" ? focusedEntry.path : resolveIssueManagerReferenceLabel(focusedEntry) })
1989
- ] }),
1990
- /* @__PURE__ */ jsx2("div", { className: "space-y-2 lg:space-y-3", children: /* @__PURE__ */ jsxs2("div", { className: "space-y-1.5", children: [
1991
- /* @__PURE__ */ jsx2("p", { className: "truncate text-[15px] font-semibold text-[var(--text-primary)]", children: resolveIssueManagerReferenceLabel(focusedEntry) }),
1992
- /* @__PURE__ */ jsx2("p", { className: "line-clamp-3 text-sm text-[var(--text-secondary)] [overflow-wrap:anywhere]", children: focusedEntry.path })
1993
- ] }) })
1994
- ] }) : /* @__PURE__ */ jsx2(IssueManagerReferencePickerFeedback2, { children: mode === "search" ? copy.t("referencePicker.emptySearch") : copy.t("referencePicker.emptyDirectory") }) }) });
1995
- }
1996
- function IssueManagerReferencePickerFooter({
1997
- copy,
1998
- onClose,
1999
- onConfirm,
2000
- selectedRefs
2001
- }) {
2002
- 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: [
2003
- /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-wrap items-center gap-2 lg:flex-1", children: [
2004
- /* @__PURE__ */ jsx2("span", { className: "text-sm text-[var(--text-secondary)]", children: copy.t("referencePicker.selectedCount", {
2005
- count: selectedRefs.length
2006
- }) }),
2007
- selectedRefs.slice(0, 2).map((ref) => /* @__PURE__ */ jsx2(
2008
- Badge,
2009
- {
2010
- className: issueManagerReferencePickerSelectedBadgeClassName,
2011
- variant: "secondary",
2012
- children: /* @__PURE__ */ jsx2("span", { className: "truncate", children: resolveIssueManagerReferenceLabel(ref) })
2013
- },
2014
- ref.path
2015
- )),
2016
- selectedRefs.length > 2 ? /* @__PURE__ */ jsxs2(
2017
- Badge,
2018
- {
2019
- className: issueManagerReferencePickerSelectedBadgeClassName,
2020
- variant: "secondary",
2021
- children: [
2022
- "+",
2023
- selectedRefs.length - 2
2024
- ]
2025
- }
2026
- ) : null
2027
- ] }),
2028
- /* @__PURE__ */ jsxs2("div", { className: "flex w-full items-center justify-end gap-2 lg:w-auto lg:shrink-0", children: [
2029
- /* @__PURE__ */ jsx2(Button2, { type: "button", variant: "secondary", onClick: onClose, children: copy.t("actions.cancel") }),
2030
- /* @__PURE__ */ jsx2(
2031
- Button2,
2032
- {
2033
- disabled: selectedRefs.length === 0,
2034
- type: "button",
2035
- onClick: onConfirm,
2036
- children: copy.t("referencePicker.confirm")
2037
- }
2038
- )
2039
- ] })
2040
- ] });
2041
- }
2042
- function IssueManagerReferencePickerFeedback2({
2043
- children
2044
- }) {
2045
- 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 });
2046
- }
2047
-
2048
- // src/ui/internal/reference/IssueManagerReferencePicker.tsx
2049
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
2050
- 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";
2051
- 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";
2052
- function IssueManagerReferencePicker({
2053
- copy,
2054
- fileAdapter,
2055
- onClose,
2056
- onConfirm,
2057
- open,
2058
- workspaceId
2059
- }) {
2060
- const {
2061
- browseRootEntries,
2062
- directoryStateByPath,
2063
- expandedFolderPaths,
2064
- focusedEntry,
2065
- focusedPath,
2066
- isLoading,
2067
- mode,
2068
- searchQuery,
2069
- selectedRefs,
2070
- visibleEntries,
2071
- setFocusedPath,
2072
- setSearchQuery,
2073
- toggleFolder,
2074
- toggleRef
2075
- } = useIssueManagerReferencePickerView({
2076
- fileAdapter,
2077
- onClose,
2078
- onConfirm,
2079
- open,
2080
- workspaceId
2081
- });
2082
- if (!open) {
2083
- return null;
2084
- }
2085
- const dialog = /* @__PURE__ */ jsx3(
2086
- "div",
2087
- {
2088
- className: cn2(
2089
- "fixed inset-0 grid place-items-center bg-[var(--backdrop)] px-3 py-4 backdrop-blur-md sm:px-6 sm:py-8",
2090
- issueManagerReferencePickerBackdropMotionClassName
2091
- ),
2092
- style: { zIndex: "var(--z-panel)" },
2093
- onClick: onClose,
2094
- children: /* @__PURE__ */ jsxs3(
2095
- Card,
2096
- {
2097
- "aria-modal": "true",
2098
- className: cn2(
2099
- "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)]",
2100
- issueManagerReferencePickerPanelMotionClassName
2101
- ),
2102
- role: "dialog",
2103
- onClick: (event) => event.stopPropagation(),
2104
- children: [
2105
- /* @__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: [
2106
- /* @__PURE__ */ jsx3("div", { className: "min-w-0", children: /* @__PURE__ */ jsx3(CardTitle, { children: copy.t("referencePicker.title") }) }),
2107
- /* @__PURE__ */ jsx3(
2108
- Button3,
2109
- {
2110
- "aria-label": copy.t("actions.cancel"),
2111
- size: "icon-sm",
2112
- type: "button",
2113
- variant: "ghost",
2114
- onClick: onClose,
2115
- children: /* @__PURE__ */ jsx3(CloseIcon, { size: 16 })
2116
- }
2117
- )
2118
- ] }) }),
2119
- /* @__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: [
2120
- /* @__PURE__ */ jsx3(
2121
- IssueManagerReferencePickerBrowserPane,
2122
- {
2123
- browseRootEntries,
2124
- copy,
2125
- directoryStateByPath,
2126
- expandedFolderPaths,
2127
- focusedPath,
2128
- isLoading,
2129
- mode,
2130
- searchQuery,
2131
- selectedRefs,
2132
- setSearchQuery,
2133
- visibleEntries,
2134
- onFocusPath: setFocusedPath,
2135
- onToggleFolder: toggleFolder,
2136
- onToggleRef: toggleRef
2137
- }
2138
- ),
2139
- /* @__PURE__ */ jsx3(
2140
- IssueManagerReferencePickerPreviewPane,
2141
- {
2142
- copy,
2143
- focusedEntry,
2144
- mode
2145
- }
2146
- )
2147
- ] }),
2148
- /* @__PURE__ */ jsx3(
2149
- IssueManagerReferencePickerFooter,
2150
- {
2151
- copy,
2152
- onClose,
2153
- onConfirm: () => onConfirm(selectedRefs),
2154
- selectedRefs
2155
- }
2156
- )
2157
- ]
2158
- }
2159
- )
2160
- }
2161
- );
2162
- if (typeof document === "undefined") {
2163
- return dialog;
2164
- }
2165
- return createPortal(dialog, document.body);
2166
- }
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";
2167
1629
 
2168
1630
  // src/ui/internal/shell/IssueManagerShell.tsx
2169
- import { Button as Button13, FileCreateIcon as FileCreateIcon4, cn as cn11 } from "@nextop-os/ui-system";
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";
2170
1633
 
2171
1634
  // src/ui/internal/shell/IssueManagerPanels.tsx
2172
- import { useState as useState6 } from "react";
2173
- import { Badge as Badge3, Button as Button7, ConfirmationDialog, Input as Input2 } from "@nextop-os/ui-system";
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
+ }
2174
1642
 
2175
1643
  // src/ui/internal/issue/IssueManagerIssueSections.tsx
2176
1644
  import {
2177
- Badge as Badge2,
2178
- Button as Button5,
1645
+ Badge,
1646
+ Button as Button2,
2179
1647
  FileCreateIcon as FileCreateIcon2,
2180
- ScrollArea as ScrollArea2,
2181
- cn as cn3
1648
+ ScrollArea,
1649
+ cn
2182
1650
  } from "@nextop-os/ui-system";
2183
1651
 
2184
1652
  // src/ui/internal/panel/IssueManagerPanelText.ts
2185
1653
  function summarizeIssueManagerContent(content, fallback) {
2186
- const plainText = extractIssueManagerPlainTextFromContent(
2187
- content ?? ""
2188
- ).trim();
1654
+ const plainText = stripIssueManagerDescriptionTerminalPunctuation(
1655
+ extractIssueManagerPlainTextFromContent(content ?? "")
1656
+ );
2189
1657
  if (!plainText) {
2190
- return fallback;
1658
+ return stripIssueManagerDescriptionTerminalPunctuation(fallback);
2191
1659
  }
2192
1660
  if (plainText.length <= 120) {
2193
1661
  return plainText;
2194
1662
  }
2195
1663
  return `${plainText.slice(0, 117)}...`;
2196
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
+ }
2197
1672
  function resolveTaskCreatorLabel(task) {
2198
1673
  return resolveIssueManagerCreatorLabel(task);
2199
1674
  }
@@ -2202,70 +1677,71 @@ function resolveIssueManagerCreatorLabel(entity) {
2202
1677
  }
2203
1678
 
2204
1679
  // src/ui/internal/panel/IssueManagerPanelSurface.tsx
2205
- import { Button as Button4, FileCreateIcon } from "@nextop-os/ui-system";
2206
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1680
+ import { Button, FileCreateIcon } from "@nextop-os/ui-system";
1681
+ import { jsx, jsxs } from "react/jsx-runtime";
2207
1682
  function IssueManagerPaneLoadingState() {
2208
- return /* @__PURE__ */ jsxs4(
1683
+ return /* @__PURE__ */ jsxs(
2209
1684
  "div",
2210
1685
  {
2211
1686
  "aria-hidden": "true",
2212
1687
  className: "mx-auto flex w-full max-w-4xl flex-col gap-6",
2213
1688
  children: [
2214
- /* @__PURE__ */ jsx4("div", { className: "h-6 w-28 rounded-full bg-muted" }),
2215
- /* @__PURE__ */ jsx4("div", { className: "h-12 w-2/3 rounded-full bg-muted" }),
2216
- /* @__PURE__ */ jsxs4("div", { className: "rounded-[28px] border border-border/70 bg-transparent px-5 py-5", children: [
2217
- /* @__PURE__ */ jsx4("div", { className: "h-4 w-24 rounded-full bg-muted" }),
2218
- /* @__PURE__ */ jsx4("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
2219
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
2220
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-10/12 rounded-full bg-muted" })
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" })
2221
1696
  ] }),
2222
- /* @__PURE__ */ jsxs4("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-5 py-5", children: [
2223
- /* @__PURE__ */ jsx4("div", { className: "h-4 w-32 rounded-full bg-muted" }),
2224
- /* @__PURE__ */ jsx4("div", { className: "mt-5 h-4 w-full rounded-full bg-muted" }),
2225
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-9/12 rounded-full bg-muted" })
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" })
2226
1701
  ] })
2227
1702
  ]
2228
1703
  }
2229
1704
  );
2230
1705
  }
2231
1706
  function IssueManagerTaskDrawerLoadingState() {
2232
- return /* @__PURE__ */ jsxs4("div", { "aria-hidden": "true", className: "grid gap-5", children: [
2233
- /* @__PURE__ */ jsx4("div", { className: "h-12 w-full rounded-2xl bg-muted" }),
2234
- /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-2 gap-3", children: [
2235
- /* @__PURE__ */ jsx4("div", { className: "h-10 rounded-xl bg-muted" }),
2236
- /* @__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" })
2237
1712
  ] }),
2238
- /* @__PURE__ */ jsxs4("div", { className: "rounded-[24px] border border-border/70 bg-transparent px-4 py-4", children: [
2239
- /* @__PURE__ */ jsx4("div", { className: "h-4 w-24 rounded-full bg-muted" }),
2240
- /* @__PURE__ */ jsx4("div", { className: "mt-4 h-4 w-full rounded-full bg-muted" }),
2241
- /* @__PURE__ */ jsx4("div", { className: "mt-3 h-4 w-11/12 rounded-full bg-muted" }),
2242
- /* @__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" })
2243
1718
  ] })
2244
1719
  ] });
2245
1720
  }
2246
1721
 
2247
1722
  // src/ui/internal/issue/IssueManagerIssueSections.tsx
2248
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1723
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
2249
1724
  function IssueManagerDetailTextSection({
2250
1725
  body,
1726
+ isPlaceholder = false,
2251
1727
  label,
2252
1728
  meta,
2253
1729
  tone = "muted"
2254
1730
  }) {
2255
- return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
2256
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: label }),
2257
- /* @__PURE__ */ jsxs5("div", { className: "grid gap-1.5", children: [
2258
- /* @__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(
2259
1735
  "p",
2260
1736
  {
2261
- className: cn3(
2262
- "text-sm font-normal leading-6",
2263
- 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)]"
2264
1740
  ),
2265
- children: body
1741
+ children: stripIssueManagerDescriptionTerminalPunctuation(body)
2266
1742
  }
2267
1743
  ),
2268
- 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
2269
1745
  ] })
2270
1746
  ] });
2271
1747
  }
@@ -2274,12 +1750,12 @@ function IssueManagerOutputSection({
2274
1750
  onOpen,
2275
1751
  outputs
2276
1752
  }) {
2277
- return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
2278
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: copy.t("labels.executionOutputs") }),
2279
- 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(
2280
1756
  "button",
2281
1757
  {
2282
- 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",
2283
1759
  type: "button",
2284
1760
  onClick: () => {
2285
1761
  void onOpen({
@@ -2289,11 +1765,11 @@ function IssueManagerOutputSection({
2289
1765
  });
2290
1766
  },
2291
1767
  children: [
2292
- /* @__PURE__ */ jsxs5("span", { className: "min-w-0 flex-1", children: [
2293
- /* @__PURE__ */ jsx5("span", { className: "block truncate text-sm font-semibold text-[var(--text-primary)]", children: output.displayName }),
2294
- /* @__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 })
2295
1771
  ] }),
2296
- /* @__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) || "" })
2297
1773
  ]
2298
1774
  },
2299
1775
  output.outputId
@@ -2307,35 +1783,35 @@ function IssueManagerSubtaskSection({
2307
1783
  selectedTaskId,
2308
1784
  tasks
2309
1785
  }) {
2310
- return /* @__PURE__ */ jsxs5("section", { className: "grid gap-2.5", children: [
2311
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between gap-3", children: [
2312
- /* @__PURE__ */ jsx5("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: copy.t("labels.subtasks") }),
2313
- /* @__PURE__ */ jsxs5(Button5, { size: "dialog", type: "button", variant: "ghost", onClick: onCreate, children: [
2314
- /* @__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 }),
2315
1791
  copy.t("actions.add")
2316
1792
  ] })
2317
1793
  ] }),
2318
- 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(
2319
1795
  "button",
2320
1796
  {
2321
- className: cn3(
2322
- "flex items-start justify-between gap-4 rounded-xl border px-4 py-3 text-left transition-colors",
2323
- 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"
2324
1800
  ),
2325
1801
  type: "button",
2326
1802
  onClick: () => onSelectTask(task.taskId),
2327
1803
  children: [
2328
- /* @__PURE__ */ jsxs5("div", { className: "min-w-0 flex-1", children: [
2329
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2.5", children: [
2330
- /* @__PURE__ */ jsx5("span", { className: "truncate text-sm font-semibold text-[var(--text-primary)]", children: task.title }),
2331
- /* @__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) })
2332
1808
  ] }),
2333
- /* @__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(
2334
1810
  task.content,
2335
1811
  copy.t("messages.taskContentEmpty")
2336
1812
  ) })
2337
1813
  ] }),
2338
- /* @__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(
2339
1815
  task.createdAtUnix ?? task.updatedAtUnix
2340
1816
  ) || "" })
2341
1817
  ]
@@ -2346,10 +1822,10 @@ function IssueManagerSubtaskSection({
2346
1822
  }
2347
1823
 
2348
1824
  // src/ui/internal/content/IssueManagerDescriptionSection.tsx
2349
- import { useEffect as useEffect5, useRef, useState as useState4 } from "react";
1825
+ import { useEffect as useEffect3, useRef, useState as useState2 } from "react";
2350
1826
  import { RichTextReadonlyContent } from "@nextop-os/ui-rich-text/editor";
2351
- import { cn as cn4 } from "@nextop-os/ui-system";
2352
- 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";
2353
1829
  function IssueManagerDescriptionSection({
2354
1830
  content,
2355
1831
  emptyLabel,
@@ -2359,14 +1835,15 @@ function IssueManagerDescriptionSection({
2359
1835
  variant = "card"
2360
1836
  }) {
2361
1837
  const contentRef = useRef(null);
2362
- const [isOverflowing, setIsOverflowing] = useState4(false);
1838
+ const [isOverflowing, setIsOverflowing] = useState2(false);
2363
1839
  const normalizedContent = normalizeIssueManagerContent(content).trim();
2364
- useEffect5(() => {
1840
+ const displayContent = stripIssueManagerDescriptionTerminalPunctuation(normalizedContent);
1841
+ useEffect3(() => {
2365
1842
  if (variant === "plain") {
2366
1843
  setIsOverflowing(false);
2367
1844
  return;
2368
1845
  }
2369
- if (!normalizedContent) {
1846
+ if (!displayContent) {
2370
1847
  setIsOverflowing(false);
2371
1848
  return;
2372
1849
  }
@@ -2390,47 +1867,47 @@ function IssueManagerDescriptionSection({
2390
1867
  return () => {
2391
1868
  observer.disconnect();
2392
1869
  };
2393
- }, [normalizedContent, variant]);
1870
+ }, [displayContent, variant]);
2394
1871
  if (variant === "plain") {
2395
- return /* @__PURE__ */ jsxs6("section", { className: "grid gap-2", children: [
2396
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
2397
- 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(
2398
1875
  IssueManagerDescriptionContent,
2399
1876
  {
2400
- content: normalizedContent,
1877
+ content: displayContent,
2401
1878
  onOpen
2402
1879
  }
2403
- ) }) : /* @__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 })
2404
1881
  ] });
2405
1882
  }
2406
- return /* @__PURE__ */ jsxs6("section", { className: "grid gap-2", children: [
2407
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: label }),
2408
- /* @__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(
2409
1886
  "div",
2410
1887
  {
2411
- className: cn4(
1888
+ className: cn2(
2412
1889
  "relative min-w-0 rounded-lg border border-border-1 bg-transparent px-4 py-3",
2413
1890
  minHeightClass
2414
1891
  ),
2415
1892
  children: [
2416
- /* @__PURE__ */ jsx6(
1893
+ /* @__PURE__ */ jsx3(
2417
1894
  "div",
2418
1895
  {
2419
- className: cn4(
1896
+ className: cn2(
2420
1897
  "max-h-[18rem] overflow-y-auto pr-2 text-sm font-normal leading-5 text-[var(--text-secondary)]",
2421
1898
  isOverflowing && "pb-8"
2422
1899
  ),
2423
1900
  ref: contentRef,
2424
- children: normalizedContent ? /* @__PURE__ */ jsx6(
1901
+ children: displayContent ? /* @__PURE__ */ jsx3(
2425
1902
  IssueManagerDescriptionContent,
2426
1903
  {
2427
- content: normalizedContent,
1904
+ content: displayContent,
2428
1905
  onOpen
2429
1906
  }
2430
- ) : /* @__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 })
2431
1908
  }
2432
1909
  ),
2433
- isOverflowing ? /* @__PURE__ */ jsx6(
1910
+ isOverflowing ? /* @__PURE__ */ jsx3(
2434
1911
  "div",
2435
1912
  {
2436
1913
  className: "pointer-events-none absolute right-0 bottom-1 left-0 h-10",
@@ -2448,7 +1925,7 @@ function IssueManagerDescriptionContent({
2448
1925
  content,
2449
1926
  onOpen
2450
1927
  }) {
2451
- return /* @__PURE__ */ jsx6(
1928
+ return /* @__PURE__ */ jsx3(
2452
1929
  RichTextReadonlyContent,
2453
1930
  {
2454
1931
  value: content,
@@ -2462,10 +1939,10 @@ function IssueManagerDescriptionContent({
2462
1939
  }
2463
1940
 
2464
1941
  // src/ui/internal/content/IssueManagerRichTextTextarea.tsx
2465
- 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";
2466
1943
  import { RichTextAtEditor } from "@nextop-os/ui-rich-text/editor";
2467
- import { Button as Button6, LinkIcon, cn as cn5 } from "@nextop-os/ui-system";
2468
- 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";
2469
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";
2470
1947
  var issueManagerRichTextPlaceholderBaseClassName = "min-h-20 w-full p-3 text-sm font-normal leading-[1.3] text-[var(--text-placeholder)]";
2471
1948
  function IssueManagerRichTextTextarea({
@@ -2476,15 +1953,15 @@ function IssueManagerRichTextTextarea({
2476
1953
  textareaClassName,
2477
1954
  value
2478
1955
  }) {
2479
- const providers = useMemo4(
1956
+ const providers = useMemo3(
2480
1957
  () => controller.resolveRichTextAtProviders(surface),
2481
1958
  [controller, surface]
2482
1959
  );
2483
1960
  const showReferenceAction = controller.canReferenceWorkspaceFiles;
2484
- const [focusSignal, setFocusSignal] = useState5(0);
1961
+ const [focusSignal, setFocusSignal] = useState3(0);
2485
1962
  const previousValueRef = useRef2(value);
2486
1963
  const wasAddingReferenceRef = useRef2(false);
2487
- useEffect6(() => {
1964
+ useEffect4(() => {
2488
1965
  const isAddingReference = controller.referenceTarget?.mode === "insert" && controller.referenceTarget.parentKind === surface;
2489
1966
  if (wasAddingReferenceRef.current && !isAddingReference && value !== previousValueRef.current) {
2490
1967
  setFocusSignal((current) => current + 1);
@@ -2492,7 +1969,7 @@ function IssueManagerRichTextTextarea({
2492
1969
  wasAddingReferenceRef.current = isAddingReference;
2493
1970
  previousValueRef.current = value;
2494
1971
  }, [controller.referenceTarget, surface, value]);
2495
- return /* @__PURE__ */ jsx7(
1972
+ return /* @__PURE__ */ jsx4(
2496
1973
  RichTextAtEditor,
2497
1974
  {
2498
1975
  focusSignal,
@@ -2504,12 +1981,12 @@ function IssueManagerRichTextTextarea({
2504
1981
  noMatchesLabel: controller.copy.t("richTextAt.noMatches"),
2505
1982
  removeReferenceActionLabel: controller.copy.t("actions.removeReference")
2506
1983
  },
2507
- textareaClassName: cn5(
1984
+ textareaClassName: cn3(
2508
1985
  issueManagerRichTextTextareaBaseClassName,
2509
1986
  textareaClassName,
2510
1987
  showReferenceAction && "pb-11"
2511
1988
  ),
2512
- placeholderClassName: cn5(
1989
+ placeholderClassName: cn3(
2513
1990
  issueManagerRichTextPlaceholderBaseClassName,
2514
1991
  textareaClassName,
2515
1992
  showReferenceAction && "pb-11"
@@ -2517,8 +1994,8 @@ function IssueManagerRichTextTextarea({
2517
1994
  placeholder,
2518
1995
  value,
2519
1996
  onChange,
2520
- overlay: showReferenceAction ? /* @__PURE__ */ jsx7("div", { className: "pointer-events-none absolute inset-x-3 bottom-3 z-10 flex", children: /* @__PURE__ */ jsxs7(
2521
- 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,
2522
1999
  {
2523
2000
  className: "pointer-events-auto",
2524
2001
  size: "default",
@@ -2528,7 +2005,7 @@ function IssueManagerRichTextTextarea({
2528
2005
  void controller.insertReferences(surface);
2529
2006
  },
2530
2007
  children: [
2531
- /* @__PURE__ */ jsx7(LinkIcon, { size: 14 }),
2008
+ /* @__PURE__ */ jsx4(LinkIcon, { size: 14 }),
2532
2009
  controller.copy.t("actions.referenceWorkspaceFiles")
2533
2010
  ]
2534
2011
  }
@@ -2537,16 +2014,65 @@ function IssueManagerRichTextTextarea({
2537
2014
  );
2538
2015
  }
2539
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
+
2540
2067
  // src/ui/internal/shell/IssueManagerEditorMotion.ts
2541
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";
2542
2069
  var issueManagerEditorRiseInDelay0ClassName = "motion-safe:[animation-delay:0ms]";
2543
2070
  var issueManagerEditorRiseInDelay1ClassName = "motion-safe:[animation-delay:55ms]";
2544
2071
  var issueManagerEditorRiseInDelay2ClassName = "motion-safe:[animation-delay:110ms]";
2545
- var issueManagerEditorRiseInDelay3ClassName = "motion-safe:[animation-delay:165ms]";
2546
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";
2547
2073
 
2548
2074
  // src/ui/internal/shell/IssueManagerPanels.tsx
2549
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2075
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2550
2076
  function IssueManagerIssuePane({
2551
2077
  controller,
2552
2078
  selectedIssue,
@@ -2560,46 +2086,45 @@ function IssueManagerIssuePane({
2560
2086
  const tasks = controller.issueDetail.value?.tasks ?? [];
2561
2087
  const selectedTaskId = controller.nodeState.selectedTaskId;
2562
2088
  const selectedTask = selectedTaskId ? (controller.taskDetail.value?.task?.taskId === selectedTaskId ? controller.taskDetail.value.task : tasks.find((task) => task.taskId === selectedTaskId)) ?? null : null;
2563
- const latestRun = selectedTask ? controller.taskDetail.value?.latestRun ?? controller.taskDetail.value?.recentRuns[0] ?? null : null;
2564
- const latestOutputs = selectedTask ? controller.taskDetail.value?.latestOutputs ?? [] : [];
2565
- const [deleteDialogOpen, setDeleteDialogOpen] = useState6(false);
2566
- 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);
2567
2093
  if (isCreatingIssue || isEditingIssue) {
2568
- return /* @__PURE__ */ jsxs8("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
2569
- /* @__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: [
2570
- /* @__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(
2571
2097
  "div",
2572
2098
  {
2573
2099
  className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay0ClassName}`,
2574
- 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") })
2575
2101
  }
2576
2102
  ),
2577
- /* @__PURE__ */ jsxs8("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
2578
- /* @__PURE__ */ jsxs8(
2103
+ /* @__PURE__ */ jsxs5("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
2104
+ /* @__PURE__ */ jsxs5(
2579
2105
  "label",
2580
2106
  {
2581
2107
  className: `flex w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
2582
2108
  children: [
2583
- /* @__PURE__ */ jsx8("span", { className: "leading-5", children: copy.t("labels.title") }),
2584
- /* @__PURE__ */ jsx8(
2585
- Input2,
2109
+ /* @__PURE__ */ jsx6("span", { className: "leading-5", children: copy.t("labels.title") }),
2110
+ /* @__PURE__ */ jsx6(
2111
+ IssueManagerDraftTitleInput,
2586
2112
  {
2587
2113
  placeholder: copy.t("composer.issueTitlePlaceholder"),
2588
- variant: "md",
2589
2114
  value: controller.issueDraft.title,
2590
- onChange: (event) => controller.setIssueTitle(event.target.value)
2115
+ onChange: controller.setIssueTitle
2591
2116
  }
2592
2117
  )
2593
2118
  ]
2594
2119
  }
2595
2120
  ),
2596
- /* @__PURE__ */ jsxs8(
2121
+ /* @__PURE__ */ jsxs5(
2597
2122
  "div",
2598
2123
  {
2599
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}`,
2600
2125
  children: [
2601
- /* @__PURE__ */ jsx8("span", { className: "leading-5", children: copy.t("labels.content") }),
2602
- /* @__PURE__ */ jsx8(
2126
+ /* @__PURE__ */ jsx6("span", { className: "leading-5", children: copy.t("labels.content") }),
2127
+ /* @__PURE__ */ jsx6(
2603
2128
  IssueManagerRichTextTextarea,
2604
2129
  {
2605
2130
  controller,
@@ -2615,13 +2140,13 @@ function IssueManagerIssuePane({
2615
2140
  )
2616
2141
  ] })
2617
2142
  ] }) }),
2618
- /* @__PURE__ */ jsx8(
2143
+ /* @__PURE__ */ jsx6(
2619
2144
  "div",
2620
2145
  {
2621
2146
  className: `shrink-0 border-t border-border-1 px-7 py-4 ${issueManagerEditorFooterFadeInClassName}`,
2622
- children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-end gap-3", children: [
2623
- /* @__PURE__ */ jsx8(
2624
- Button7,
2147
+ children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-end gap-3", children: [
2148
+ /* @__PURE__ */ jsx6(
2149
+ Button4,
2625
2150
  {
2626
2151
  size: "dialog",
2627
2152
  type: "button",
@@ -2630,8 +2155,8 @@ function IssueManagerIssuePane({
2630
2155
  children: copy.t("actions.cancel")
2631
2156
  }
2632
2157
  ),
2633
- /* @__PURE__ */ jsx8(
2634
- Button7,
2158
+ /* @__PURE__ */ jsx6(
2159
+ Button4,
2635
2160
  {
2636
2161
  disabled: isIssueTitleMissing,
2637
2162
  size: "dialog",
@@ -2646,63 +2171,69 @@ function IssueManagerIssuePane({
2646
2171
  ] });
2647
2172
  }
2648
2173
  if (!selectedIssue) {
2649
- return /* @__PURE__ */ jsx8("div", { className: "h-full min-h-0" });
2174
+ return /* @__PURE__ */ jsx6("div", { className: "h-full min-h-0" });
2650
2175
  }
2651
- 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: [
2652
- /* @__PURE__ */ jsxs8("header", { className: "flex items-start justify-between gap-6", children: [
2653
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
2654
- /* @__PURE__ */ jsx8("h2", { className: "line-clamp-2 text-base font-semibold leading-6 text-[var(--text-primary)]", children: selectedIssue.title }),
2655
- /* @__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: [
2656
- /* @__PURE__ */ jsx8(Badge3, { variant: "secondary", children: resolveIssueManagerStatusLabel(copy, selectedIssue.status) }),
2657
- /* @__PURE__ */ jsx8(
2658
- "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,
2659
2183
  {
2660
- "aria-hidden": "true",
2661
- 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")
2662
2188
  }
2663
2189
  ),
2664
- /* @__PURE__ */ jsxs8("span", { children: [
2665
- copy.t("labels.creator"),
2666
- " ",
2667
- resolveIssueManagerCreatorLabel(selectedIssue)
2668
- ] }),
2669
- /* @__PURE__ */ jsx8(
2670
- "span",
2190
+ /* @__PURE__ */ jsx6(
2191
+ Button4,
2671
2192
  {
2672
- "aria-hidden": "true",
2673
- 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")
2674
2198
  }
2675
- ),
2676
- /* @__PURE__ */ jsxs8("span", { children: [
2677
- copy.t("labels.createdAt"),
2678
- " ",
2679
- formatIssueManagerTimestamp(selectedIssue.createdAtUnix) || "-"
2680
- ] })
2199
+ )
2681
2200
  ] })
2682
2201
  ] }),
2683
- /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-center gap-2 pt-1", children: [
2684
- /* @__PURE__ */ jsx8(
2685
- 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,
2686
2205
  {
2687
- type: "button",
2688
- variant: "ghost",
2689
- onClick: () => controller.setIssueEditorMode("edit"),
2690
- children: copy.t("actions.edit")
2206
+ variant: issueManagerStatusBadgeVariant(selectedIssue.status),
2207
+ children: resolveIssueManagerStatusLabel(copy, selectedIssue.status)
2691
2208
  }
2692
2209
  ),
2693
- /* @__PURE__ */ jsx8(
2694
- Button7,
2210
+ /* @__PURE__ */ jsx6(
2211
+ "span",
2695
2212
  {
2696
- className: "text-[var(--state-danger)] hover:bg-[var(--on-danger)] hover:text-[var(--state-danger)]",
2697
- type: "button",
2698
- variant: "ghost",
2699
- onClick: () => setDeleteDialogOpen(true),
2700
- children: copy.t("actions.delete")
2213
+ "aria-hidden": "true",
2214
+ className: "h-4 w-px shrink-0 bg-[var(--line-2)]"
2701
2215
  }
2702
- )
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
+ ] })
2703
2234
  ] })
2704
2235
  ] }),
2705
- /* @__PURE__ */ jsx8(
2236
+ /* @__PURE__ */ jsx6(
2706
2237
  ConfirmationDialog,
2707
2238
  {
2708
2239
  cancelLabel: copy.t("actions.cancel"),
@@ -2722,7 +2253,7 @@ function IssueManagerIssuePane({
2722
2253
  onOpenChange: setDeleteDialogOpen
2723
2254
  }
2724
2255
  ),
2725
- /* @__PURE__ */ jsx8(
2256
+ /* @__PURE__ */ jsx6(
2726
2257
  IssueManagerDescriptionSection,
2727
2258
  {
2728
2259
  content: issueContent,
@@ -2732,10 +2263,11 @@ function IssueManagerIssuePane({
2732
2263
  variant: "plain"
2733
2264
  }
2734
2265
  ),
2735
- /* @__PURE__ */ jsx8(
2266
+ /* @__PURE__ */ jsx6(
2736
2267
  IssueManagerDetailTextSection,
2737
2268
  {
2738
2269
  body: latestRun ? latestRun.summary?.trim() || resolveIssueManagerStatusLabel(copy, latestRun.status) : copy.t("messages.noExecutionStatus"),
2270
+ isPlaceholder: !latestRun,
2739
2271
  label: copy.t("labels.latestRunStatus"),
2740
2272
  meta: latestRun ? formatIssueManagerTimestamp(
2741
2273
  latestRun.updatedAtUnix ?? latestRun.createdAtUnix
@@ -2743,7 +2275,7 @@ function IssueManagerIssuePane({
2743
2275
  tone: latestRun?.status === "failed" ? "destructive" : "muted"
2744
2276
  }
2745
2277
  ),
2746
- /* @__PURE__ */ jsx8(
2278
+ /* @__PURE__ */ jsx6(
2747
2279
  IssueManagerOutputSection,
2748
2280
  {
2749
2281
  copy,
@@ -2751,7 +2283,7 @@ function IssueManagerIssuePane({
2751
2283
  onOpen: controller.openReference
2752
2284
  }
2753
2285
  ),
2754
- /* @__PURE__ */ jsx8(
2286
+ /* @__PURE__ */ jsx6(
2755
2287
  IssueManagerSubtaskSection,
2756
2288
  {
2757
2289
  copy,
@@ -2765,204 +2297,346 @@ function IssueManagerIssuePane({
2765
2297
  }
2766
2298
 
2767
2299
  // src/ui/internal/shell/IssueManagerBottomBar.tsx
2768
- 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";
2769
2301
 
2770
2302
  // src/ui/internal/task/IssueManagerRunSections.tsx
2771
- import { useState as useState7 } from "react";
2772
- import {
2773
- Badge as Badge4,
2774
- Select,
2775
- SelectContent,
2776
- SelectItem,
2777
- SelectTrigger,
2778
- buttonVariants,
2779
- 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
2780
2320
  } from "@nextop-os/ui-system";
2781
- 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";
2782
2324
  function IssueManagerRunActionTrigger({
2783
2325
  controller,
2784
2326
  disabled = false,
2785
- triggerClassName
2327
+ triggerClassName,
2328
+ triggerVariant = "default"
2786
2329
  }) {
2787
- const [resetToken, setResetToken] = useState7(0);
2788
- return /* @__PURE__ */ jsxs9(
2789
- Select,
2330
+ return /* @__PURE__ */ jsxs6(
2331
+ Button5,
2790
2332
  {
2333
+ className: cn4("min-w-0", triggerClassName),
2791
2334
  disabled: controller.isRunningTask || disabled,
2792
- onValueChange: (provider) => {
2793
- setResetToken((current) => current + 1);
2794
- void controller.runTask(provider);
2335
+ size: triggerVariant === "button" ? "dialog" : "default",
2336
+ type: "button",
2337
+ onClick: () => {
2338
+ void controller.runTask();
2795
2339
  },
2796
2340
  children: [
2797
- /* @__PURE__ */ jsx9(
2798
- SelectTrigger,
2799
- {
2800
- "aria-label": controller.copy.t("actions.askAgentToRun"),
2801
- className: cn6(
2802
- buttonVariants({ variant: "secondary", size: "dialog" }),
2803
- "[&>svg]:hidden",
2804
- triggerClassName
2805
- ),
2806
- 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") }) })
2807
- }
2808
- ),
2809
- /* @__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") })
2810
2343
  ]
2811
- },
2812
- `${controller.nodeState.selectedAgentProvider}:${resetToken}`
2344
+ }
2813
2345
  );
2814
2346
  }
2815
- function IssueManagerRunPanels({
2816
- copy,
2817
- onOpen,
2818
- outputs,
2819
- recentRuns
2347
+ function IssueManagerBreakdownActionTrigger({
2348
+ controller,
2349
+ disabled = false,
2350
+ triggerClassName,
2351
+ triggerVariant = "default"
2820
2352
  }) {
2821
- return /* @__PURE__ */ jsxs9("div", { className: "grid gap-4", children: [
2822
- /* @__PURE__ */ jsxs9("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
2823
- /* @__PURE__ */ jsx9("h4", { className: "mb-3 text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.recentRuns") }),
2824
- 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(
2825
- "div",
2826
- {
2827
- className: "rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3",
2828
- children: [
2829
- /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-3", children: [
2830
- /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
2831
- /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: run.summary || run.runId }),
2832
- /* @__PURE__ */ jsx9("p", { className: "mt-1 text-xs leading-[1.55] text-[var(--text-secondary)]", children: formatIssueManagerTimestamp(
2833
- run.updatedAtUnix ?? run.createdAtUnix
2834
- ) })
2835
- ] }),
2836
- /* @__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) })
2837
- ] }),
2838
- run.errorMessage ? /* @__PURE__ */ jsx9("p", { className: "mt-2 text-xs text-[var(--state-danger)]", children: run.errorMessage }) : null
2839
- ]
2840
- },
2841
- run.runId
2842
- )) })
2843
- ] }),
2844
- /* @__PURE__ */ jsxs9("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
2845
- /* @__PURE__ */ jsx9("h4", { className: "mb-3 text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.outputs") }),
2846
- 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(
2847
- "button",
2848
- {
2849
- className: "rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3 text-left transition-colors hover:bg-transparency-hover",
2850
- type: "button",
2851
- onClick: () => {
2852
- void onOpen({
2853
- displayName: output.displayName,
2854
- kind: "file",
2855
- path: output.path
2856
- });
2857
- },
2858
- children: [
2859
- /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: output.displayName }),
2860
- /* @__PURE__ */ jsx9("p", { className: "mt-1 truncate text-xs leading-[1.55] text-[var(--text-secondary)]", children: output.path })
2861
- ]
2862
- },
2863
- output.outputId
2864
- )) })
2865
- ] })
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
+ )
2866
2538
  ] });
2867
2539
  }
2868
2540
 
2869
2541
  // src/ui/internal/shell/IssueManagerBottomBar.tsx
2870
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2542
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2871
2543
  function IssueManagerBottomBar({
2872
2544
  controller,
2873
2545
  isNarrowLayout,
2874
2546
  selectedIssue,
2875
- selectedTask,
2876
2547
  visible
2877
2548
  }) {
2878
2549
  const copy = controller.copy;
2879
2550
  if (!visible || !selectedIssue) {
2880
2551
  return null;
2881
2552
  }
2882
- 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(
2883
2554
  "div",
2884
2555
  {
2885
- className: cn7(
2556
+ className: cn5(
2886
2557
  "flex gap-3",
2887
2558
  isNarrowLayout ? "flex-wrap items-center justify-end" : "items-center justify-end"
2888
2559
  ),
2889
2560
  children: [
2890
- /* @__PURE__ */ jsx10(
2891
- IssueManagerRunActionTrigger,
2561
+ /* @__PURE__ */ jsx8(
2562
+ IssueManagerExecutionDirectoryTrigger,
2892
2563
  {
2564
+ className: "mr-auto min-w-0 max-w-[240px] justify-start overflow-hidden",
2893
2565
  controller,
2894
- disabled: !selectedTask
2566
+ disabled: controller.isRunningTask
2895
2567
  }
2896
2568
  ),
2897
- controller.canInviteCollaborators ? /* @__PURE__ */ jsx10(
2898
- Button8,
2899
- {
2900
- className: "px-4",
2901
- disabled: !selectedIssue,
2902
- size: "dialog",
2903
- type: "button",
2904
- onClick: () => {
2905
- void controller.shareSelection();
2906
- },
2907
- children: copy.t("actions.inviteCollaborator")
2908
- }
2909
- ) : 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
+ ] })
2910
2600
  ]
2911
2601
  }
2912
2602
  ) });
2913
2603
  }
2914
2604
 
2915
2605
  // src/ui/internal/shell/IssueManagerFloatingNotice.tsx
2916
- import {
2917
- FailedFilledIcon,
2918
- Spinner as Spinner2,
2919
- toastVariants,
2920
- cn as cn8
2921
- } from "@nextop-os/ui-system";
2922
- 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";
2923
2608
  function IssueManagerFloatingNotice({
2924
2609
  notice
2925
2610
  }) {
2926
2611
  const variant = notice.tone === "destructive" ? "destructive" : "default";
2927
- 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(
2928
- "div",
2612
+ return /* @__PURE__ */ jsx9(ToastProvider, { children: /* @__PURE__ */ jsx9(
2613
+ ToastRoot,
2929
2614
  {
2930
- "aria-busy": notice.isLoading,
2931
- "aria-live": variant === "destructive" ? "assertive" : "polite",
2932
- className: cn8(
2933
- toastVariants({ variant }),
2934
- "w-fit max-w-[min(72vw,40rem)] px-4 py-3 shadow-lg"
2935
- ),
2936
- role: variant === "destructive" ? "alert" : "status",
2937
- 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: [
2938
- notice.isLoading ? /* @__PURE__ */ jsx11(
2939
- Spinner2,
2940
- {
2941
- className: "shrink-0 text-current",
2942
- size: 16,
2943
- strokeWidth: 3,
2944
- trackColor: "color-mix(in srgb, currentColor 28%, transparent)"
2945
- }
2946
- ) : notice.tone === "destructive" ? /* @__PURE__ */ jsx11(FailedFilledIcon, { className: "size-4 shrink-0 text-current" }) : null,
2947
- /* @__PURE__ */ jsx11("span", { className: "min-w-0 max-w-full truncate whitespace-nowrap", children: notice.title })
2948
- ] })
2949
- }
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
2950
2624
  ) });
2951
2625
  }
2952
2626
 
2953
2627
  // src/ui/internal/shell/IssueManagerSidebar.tsx
2954
- import { cn as cn10 } from "@nextop-os/ui-system";
2628
+ import { cn as cn7 } from "@nextop-os/ui-system";
2955
2629
 
2956
2630
  // src/ui/internal/shell/IssueManagerSidebarSections.tsx
2957
2631
  import {
2958
- Badge as Badge5,
2959
- Button as Button9,
2960
- CloseIcon as CloseIcon2,
2632
+ Badge as Badge4,
2633
+ Button as Button7,
2634
+ CloseIcon,
2961
2635
  FileCreateIcon as FileCreateIcon3,
2962
- Input as Input3,
2963
- ScrollArea as ScrollArea3,
2636
+ Input as Input2,
2637
+ ScrollArea as ScrollArea2,
2964
2638
  UnderlineTabs,
2965
- cn as cn9
2639
+ cn as cn6
2966
2640
  } from "@nextop-os/ui-system";
2967
2641
 
2968
2642
  // src/ui/internal/shell/IssueManagerShellState.ts
@@ -3039,20 +2713,20 @@ function resolveIssueManagerShellContentViewState(input) {
3039
2713
  isIssueEditing,
3040
2714
  isTaskCreating,
3041
2715
  isTaskDrawerOpen,
3042
- showBottomBar: input.selectedIssue !== null && input.issueEditorMode === "read" && input.taskEditorMode === "read"
2716
+ showBottomBar: input.selectedIssue !== null && input.issueEditorMode === "read" && input.taskEditorMode !== "create"
3043
2717
  };
3044
2718
  }
3045
2719
 
3046
2720
  // src/ui/internal/shell/IssueManagerSidebarSections.tsx
3047
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2721
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
3048
2722
  function IssueManagerSidebarHeader({
3049
2723
  copy,
3050
2724
  issueSearchQuery,
3051
2725
  onCreateIssue,
3052
2726
  onIssueSearchQueryChange
3053
2727
  }) {
3054
- return /* @__PURE__ */ jsx12("div", { className: "px-4 py-4", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2.5", children: [
3055
- /* @__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(
3056
2730
  IssueManagerSearchField,
3057
2731
  {
3058
2732
  clearLabel: copy.t("actions.clearSearch"),
@@ -3061,8 +2735,8 @@ function IssueManagerSidebarHeader({
3061
2735
  onChange: onIssueSearchQueryChange
3062
2736
  }
3063
2737
  ),
3064
- /* @__PURE__ */ jsxs12(
3065
- Button9,
2738
+ /* @__PURE__ */ jsxs8(
2739
+ Button7,
3066
2740
  {
3067
2741
  className: "gap-2 px-3",
3068
2742
  size: "dialog",
@@ -3070,7 +2744,7 @@ function IssueManagerSidebarHeader({
3070
2744
  variant: "secondary",
3071
2745
  onClick: onCreateIssue,
3072
2746
  children: [
3073
- /* @__PURE__ */ jsx12(FileCreateIcon3, { size: 16 }),
2747
+ /* @__PURE__ */ jsx10(FileCreateIcon3, { size: 16 }),
3074
2748
  copy.t("actions.createIssue")
3075
2749
  ]
3076
2750
  }
@@ -3083,7 +2757,7 @@ function IssueManagerSidebarStatusTabs({
3083
2757
  statusCounts,
3084
2758
  onIssueStatusFilterChange
3085
2759
  }) {
3086
- return /* @__PURE__ */ jsx12(
2760
+ return /* @__PURE__ */ jsx10(
3087
2761
  UnderlineTabs,
3088
2762
  {
3089
2763
  ariaLabel: copy.t("labels.status"),
@@ -3108,18 +2782,18 @@ function IssueManagerSidebarBody({
3108
2782
  onRetry,
3109
2783
  onSelectIssue
3110
2784
  }) {
3111
- return /* @__PURE__ */ jsx12(
3112
- ScrollArea3,
2785
+ return /* @__PURE__ */ jsx10(
2786
+ ScrollArea2,
3113
2787
  {
3114
- className: cn9("min-h-0", isNarrowLayout ? "flex-none" : "h-full flex-1"),
3115
- children: /* @__PURE__ */ jsx12(
2788
+ className: cn6("min-h-0", isNarrowLayout ? "flex-none" : "h-full flex-1"),
2789
+ children: /* @__PURE__ */ jsx10(
3116
2790
  "div",
3117
2791
  {
3118
- className: cn9(
2792
+ className: cn6(
3119
2793
  "flex min-h-full flex-col gap-2.5 px-4 pt-1.5 pb-4",
3120
2794
  isNarrowLayout ? "min-h-0" : "h-full"
3121
2795
  ),
3122
- 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(
3123
2797
  IssueManagerSidebarErrorState,
3124
2798
  {
3125
2799
  isNarrowLayout,
@@ -3127,14 +2801,14 @@ function IssueManagerSidebarBody({
3127
2801
  title: sidebarViewState.title,
3128
2802
  onRetry
3129
2803
  }
3130
- ) : sidebarViewState.kind === "empty" ? /* @__PURE__ */ jsx12(
2804
+ ) : sidebarViewState.kind === "empty" ? /* @__PURE__ */ jsx10(
3131
2805
  IssueManagerSidebarEmptyState,
3132
2806
  {
3133
2807
  body: sidebarViewState.body,
3134
2808
  isNarrowLayout,
3135
2809
  title: sidebarViewState.title
3136
2810
  }
3137
- ) : /* @__PURE__ */ jsx12(
2811
+ ) : /* @__PURE__ */ jsx10(
3138
2812
  IssueManagerSidebarIssueList,
3139
2813
  {
3140
2814
  copy,
@@ -3158,7 +2832,7 @@ function IssueManagerSidebarStandalonePane({
3158
2832
  onRetry
3159
2833
  }) {
3160
2834
  if (kind === "error" && retryLabel) {
3161
- return /* @__PURE__ */ jsx12(
2835
+ return /* @__PURE__ */ jsx10(
3162
2836
  IssueManagerSidebarErrorState,
3163
2837
  {
3164
2838
  isNarrowLayout,
@@ -3168,7 +2842,7 @@ function IssueManagerSidebarStandalonePane({
3168
2842
  }
3169
2843
  );
3170
2844
  }
3171
- return /* @__PURE__ */ jsx12(
2845
+ return /* @__PURE__ */ jsx10(
3172
2846
  IssueManagerSidebarEmptyState,
3173
2847
  {
3174
2848
  body: body ?? "",
@@ -3183,17 +2857,17 @@ function IssueManagerSearchField({
3183
2857
  placeholder,
3184
2858
  value
3185
2859
  }) {
3186
- return /* @__PURE__ */ jsxs12(
2860
+ return /* @__PURE__ */ jsxs8(
3187
2861
  "div",
3188
2862
  {
3189
2863
  className: "relative min-w-0 flex-1",
3190
2864
  "data-has-value": value ? "true" : "false",
3191
2865
  children: [
3192
- /* @__PURE__ */ jsx12(
3193
- Input3,
2866
+ /* @__PURE__ */ jsx10(
2867
+ Input2,
3194
2868
  {
3195
2869
  "aria-label": placeholder,
3196
- className: cn9(
2870
+ className: cn6(
3197
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",
3198
2872
  "[&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none",
3199
2873
  value ? "pr-9" : "pr-3"
@@ -3204,7 +2878,7 @@ function IssueManagerSearchField({
3204
2878
  onChange: (event) => onChange(event.target.value)
3205
2879
  }
3206
2880
  ),
3207
- value ? /* @__PURE__ */ jsx12(
2881
+ value ? /* @__PURE__ */ jsx10(
3208
2882
  "button",
3209
2883
  {
3210
2884
  "aria-label": clearLabel,
@@ -3212,7 +2886,7 @@ function IssueManagerSearchField({
3212
2886
  type: "button",
3213
2887
  onClick: () => onChange(""),
3214
2888
  onMouseDown: (event) => event.preventDefault(),
3215
- children: /* @__PURE__ */ jsx12(CloseIcon2, { className: "size-3.5" })
2889
+ children: /* @__PURE__ */ jsx10(CloseIcon, { className: "size-3.5" })
3216
2890
  }
3217
2891
  ) : null
3218
2892
  ]
@@ -3226,14 +2900,14 @@ function IssueManagerSidebarIssueList({
3226
2900
  selectedIssueId,
3227
2901
  onSelectIssue
3228
2902
  }) {
3229
- return /* @__PURE__ */ jsx12(
2903
+ return /* @__PURE__ */ jsx10(
3230
2904
  "div",
3231
2905
  {
3232
- className: cn9(
2906
+ className: cn6(
3233
2907
  "flex gap-2.5",
3234
2908
  isNarrowLayout ? "flex-row flex-nowrap items-start overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden" : "flex-col"
3235
2909
  ),
3236
- children: issues.map((issue) => /* @__PURE__ */ jsx12(
2910
+ children: issues.map((issue) => /* @__PURE__ */ jsx10(
3237
2911
  IssueManagerSidebarItem,
3238
2912
  {
3239
2913
  copy,
@@ -3254,25 +2928,30 @@ function IssueManagerSidebarItem({
3254
2928
  onSelect,
3255
2929
  selected
3256
2930
  }) {
3257
- return /* @__PURE__ */ jsxs12(
2931
+ return /* @__PURE__ */ jsxs8(
3258
2932
  "button",
3259
2933
  {
3260
- className: cn9(
3261
- "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",
3262
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",
3263
2937
  selected ? "border-[var(--border-1)] bg-[var(--background-fronted)]" : "border-[var(--border-1)] bg-transparent hover:bg-[var(--transparency-block)]"
3264
2938
  ),
3265
2939
  type: "button",
3266
2940
  onClick: () => onSelect(issue.issueId),
3267
2941
  children: [
3268
- /* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
3269
- /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1 space-y-2", children: [
3270
- /* @__PURE__ */ jsx12("p", { className: "text-[12px] leading-[1.55] text-[var(--text-secondary)]", children: formatIssueManagerDate(issue.updatedAtUnix ?? issue.createdAtUnix) }),
3271
- /* @__PURE__ */ jsx12("p", { className: "line-clamp-4 text-[14px] font-semibold leading-[1.35rem] text-[var(--text-primary)]", children: issue.title })
3272
- ] }),
3273
- /* @__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 })
3274
2953
  ] }),
3275
- /* @__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 }) })
3276
2955
  ]
3277
2956
  }
3278
2957
  );
@@ -3280,25 +2959,25 @@ function IssueManagerSidebarItem({
3280
2959
  function IssueManagerSidebarLoadingState({
3281
2960
  isNarrowLayout
3282
2961
  }) {
3283
- return /* @__PURE__ */ jsx12(
2962
+ return /* @__PURE__ */ jsx10(
3284
2963
  "div",
3285
2964
  {
3286
2965
  "aria-hidden": "true",
3287
- className: cn9(
2966
+ className: cn6(
3288
2967
  "gap-2.5",
3289
2968
  isNarrowLayout ? "flex flex-row flex-nowrap overflow-x-hidden" : "grid"
3290
2969
  ),
3291
- children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxs12(
2970
+ children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxs8(
3292
2971
  "div",
3293
2972
  {
3294
- className: cn9(
2973
+ className: cn6(
3295
2974
  "rounded-lg bg-transparent px-3.5 py-3.5",
3296
2975
  isNarrowLayout && "h-24 max-h-24 min-h-24 w-[clamp(220px,58vw,320px)] flex-[0_0_clamp(220px,58vw,320px)]"
3297
2976
  ),
3298
2977
  children: [
3299
- /* @__PURE__ */ jsx12("div", { className: "h-3.5 w-20 rounded-full bg-[var(--transparency-block)]" }),
3300
- /* @__PURE__ */ jsx12("div", { className: "mt-3 h-4 w-4/5 rounded-full bg-[var(--transparency-block)]" }),
3301
- /* @__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)]" })
3302
2981
  ]
3303
2982
  },
3304
2983
  index
@@ -3312,25 +2991,25 @@ function IssueManagerSidebarEmptyState({
3312
2991
  title,
3313
2992
  tone = "default"
3314
2993
  }) {
3315
- return /* @__PURE__ */ jsxs12(
2994
+ return /* @__PURE__ */ jsxs8(
3316
2995
  "div",
3317
2996
  {
3318
- className: cn9(
2997
+ className: cn6(
3319
2998
  "relative flex flex-1 flex-col items-center justify-center self-stretch overflow-hidden p-0 text-center",
3320
2999
  isNarrowLayout ? "h-24 max-h-24 min-h-24 w-full flex-[0_0_100%]" : "min-h-full"
3321
3000
  ),
3322
3001
  children: [
3323
- /* @__PURE__ */ jsx12(
3002
+ /* @__PURE__ */ jsx10(
3324
3003
  "p",
3325
3004
  {
3326
- className: cn9(
3005
+ className: cn6(
3327
3006
  "text-sm font-semibold leading-5 text-[var(--text-primary)]",
3328
3007
  tone === "destructive" ? "text-[var(--state-danger)]" : "text-[var(--text-primary)]"
3329
3008
  ),
3330
3009
  children: title
3331
3010
  }
3332
3011
  ),
3333
- /* @__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 })
3334
3013
  ]
3335
3014
  }
3336
3015
  );
@@ -3341,17 +3020,17 @@ function IssueManagerSidebarErrorState({
3341
3020
  title,
3342
3021
  onRetry
3343
3022
  }) {
3344
- return /* @__PURE__ */ jsxs12(
3023
+ return /* @__PURE__ */ jsxs8(
3345
3024
  "div",
3346
3025
  {
3347
- className: cn9(
3026
+ className: cn6(
3348
3027
  "relative flex flex-1 flex-col items-center justify-center self-stretch overflow-hidden px-4 py-6 text-center",
3349
3028
  isNarrowLayout ? "h-24 max-h-24 min-h-24 w-full flex-[0_0_100%]" : "min-h-full"
3350
3029
  ),
3351
3030
  children: [
3352
- /* @__PURE__ */ jsx12("p", { className: "text-sm font-semibold leading-5 text-[var(--state-danger)]", children: title }),
3353
- /* @__PURE__ */ jsx12(
3354
- Button9,
3031
+ /* @__PURE__ */ jsx10("p", { className: "text-sm font-semibold leading-5 text-[var(--state-danger)]", children: title }),
3032
+ /* @__PURE__ */ jsx10(
3033
+ Button7,
3355
3034
  {
3356
3035
  className: "mt-3",
3357
3036
  size: "sm",
@@ -3390,7 +3069,7 @@ function resolveIssueManagerSidebarPresentationState(input) {
3390
3069
  }
3391
3070
 
3392
3071
  // src/ui/internal/shell/IssueManagerSidebar.tsx
3393
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
3072
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
3394
3073
  function IssueManagerSidebar({
3395
3074
  controller,
3396
3075
  isCollapsed,
@@ -3404,18 +3083,18 @@ function IssueManagerSidebar({
3404
3083
  showStandaloneState,
3405
3084
  sidebarViewState
3406
3085
  });
3407
- return /* @__PURE__ */ jsxs13(
3086
+ return /* @__PURE__ */ jsxs9(
3408
3087
  "aside",
3409
3088
  {
3410
3089
  "aria-hidden": isCollapsed ? "true" : void 0,
3411
- className: cn10(
3090
+ className: cn7(
3412
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",
3413
3092
  isNarrowLayout ? "border-b border-[var(--border-1)]" : "border-r border-[var(--border-1)]",
3414
3093
  isCollapsed && "pointer-events-none border-r-transparent after:opacity-100 after:delay-0 [&>*]:opacity-0 [&>*]:blur-[1px] [&>*]:delay-0 motion-reduce:[&>*]:blur-none"
3415
3094
  ),
3416
3095
  inert: isCollapsed ? true : void 0,
3417
3096
  children: [
3418
- /* @__PURE__ */ jsx13(
3097
+ /* @__PURE__ */ jsx11(
3419
3098
  IssueManagerSidebarHeader,
3420
3099
  {
3421
3100
  copy,
@@ -3424,7 +3103,7 @@ function IssueManagerSidebar({
3424
3103
  onIssueSearchQueryChange: controller.setIssueSearchQuery
3425
3104
  }
3426
3105
  ),
3427
- /* @__PURE__ */ jsx13(
3106
+ /* @__PURE__ */ jsx11(
3428
3107
  IssueManagerSidebarStatusTabs,
3429
3108
  {
3430
3109
  copy,
@@ -3433,15 +3112,15 @@ function IssueManagerSidebar({
3433
3112
  onIssueStatusFilterChange: controller.setIssueStatusFilter
3434
3113
  }
3435
3114
  ),
3436
- /* @__PURE__ */ jsx13("div", { "aria-hidden": "true", className: "h-2.5 flex-none" }),
3437
- /* @__PURE__ */ jsx13(
3115
+ /* @__PURE__ */ jsx11("div", { "aria-hidden": "true", className: "h-2.5 flex-none" }),
3116
+ /* @__PURE__ */ jsx11(
3438
3117
  "div",
3439
3118
  {
3440
- className: cn10(
3119
+ className: cn7(
3441
3120
  "relative flex min-h-0 flex-col",
3442
3121
  isNarrowLayout ? "flex-none" : "flex-1"
3443
3122
  ),
3444
- 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(
3445
3124
  IssueManagerSidebarStandalonePane,
3446
3125
  {
3447
3126
  body: presentation.kind === "empty" ? presentation.body : void 0,
@@ -3451,7 +3130,7 @@ function IssueManagerSidebar({
3451
3130
  title: presentation.title,
3452
3131
  onRetry: () => controller.refreshAll()
3453
3132
  }
3454
- ) }) : /* @__PURE__ */ jsx13(
3133
+ ) }) : /* @__PURE__ */ jsx11(
3455
3134
  IssueManagerSidebarBody,
3456
3135
  {
3457
3136
  copy,
@@ -3470,8 +3149,8 @@ function IssueManagerSidebar({
3470
3149
  }
3471
3150
 
3472
3151
  // src/ui/internal/shell/IssueManagerTaskComposerPane.tsx
3473
- import { Button as Button10, Input as Input4 } from "@nextop-os/ui-system";
3474
- 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";
3475
3154
  function IssueManagerTaskComposerPane({
3476
3155
  controller,
3477
3156
  onCancel,
@@ -3479,41 +3158,40 @@ function IssueManagerTaskComposerPane({
3479
3158
  }) {
3480
3159
  const copy = controller.copy;
3481
3160
  const isTaskTitleMissing = controller.taskDraft.title.trim().length === 0;
3482
- return /* @__PURE__ */ jsxs14("div", { className: "flex h-full min-h-0 flex-col overflow-hidden", children: [
3483
- /* @__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: [
3484
- /* @__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(
3485
3164
  "div",
3486
3165
  {
3487
3166
  className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay0ClassName}`,
3488
- 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") })
3489
3168
  }
3490
3169
  ),
3491
- /* @__PURE__ */ jsxs14("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
3492
- /* @__PURE__ */ jsxs14(
3170
+ /* @__PURE__ */ jsxs10("div", { className: "flex w-full min-w-0 flex-col gap-6", children: [
3171
+ /* @__PURE__ */ jsxs10(
3493
3172
  "label",
3494
3173
  {
3495
3174
  className: `flex w-full min-w-0 flex-col gap-2 text-sm font-semibold text-[var(--text-primary)] ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
3496
3175
  children: [
3497
- /* @__PURE__ */ jsx14("span", { className: "leading-5", children: copy.t("labels.title") }),
3498
- /* @__PURE__ */ jsx14(
3499
- Input4,
3176
+ /* @__PURE__ */ jsx12("span", { className: "leading-5", children: copy.t("labels.title") }),
3177
+ /* @__PURE__ */ jsx12(
3178
+ IssueManagerDraftTitleInput,
3500
3179
  {
3501
3180
  placeholder: copy.t("composer.subtaskTitlePlaceholder"),
3502
- variant: "md",
3503
3181
  value: controller.taskDraft.title,
3504
- onChange: (event) => controller.setTaskTitle(event.target.value)
3182
+ onChange: controller.setTaskTitle
3505
3183
  }
3506
3184
  )
3507
3185
  ]
3508
3186
  }
3509
3187
  ),
3510
- /* @__PURE__ */ jsxs14(
3188
+ /* @__PURE__ */ jsxs10(
3511
3189
  "div",
3512
3190
  {
3513
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}`,
3514
3192
  children: [
3515
- /* @__PURE__ */ jsx14("span", { className: "leading-5", children: copy.t("labels.requirementDescription") }),
3516
- /* @__PURE__ */ jsx14(
3193
+ /* @__PURE__ */ jsx12("span", { className: "leading-5", children: copy.t("labels.requirementDescription") }),
3194
+ /* @__PURE__ */ jsx12(
3517
3195
  IssueManagerRichTextTextarea,
3518
3196
  {
3519
3197
  controller,
@@ -3529,13 +3207,13 @@ function IssueManagerTaskComposerPane({
3529
3207
  )
3530
3208
  ] })
3531
3209
  ] }) }),
3532
- /* @__PURE__ */ jsx14(
3210
+ /* @__PURE__ */ jsx12(
3533
3211
  "div",
3534
3212
  {
3535
3213
  className: `shrink-0 border-t border-border-1 px-7 py-4 ${issueManagerEditorFooterFadeInClassName}`,
3536
- children: /* @__PURE__ */ jsxs14("div", { className: "flex items-center justify-end gap-3", children: [
3537
- /* @__PURE__ */ jsx14(
3538
- Button10,
3214
+ children: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-end gap-3", children: [
3215
+ /* @__PURE__ */ jsx12(
3216
+ Button8,
3539
3217
  {
3540
3218
  size: "default",
3541
3219
  type: "button",
@@ -3544,8 +3222,8 @@ function IssueManagerTaskComposerPane({
3544
3222
  children: copy.t("actions.cancel")
3545
3223
  }
3546
3224
  ),
3547
- /* @__PURE__ */ jsx14(
3548
- Button10,
3225
+ /* @__PURE__ */ jsx12(
3226
+ Button8,
3549
3227
  {
3550
3228
  disabled: !selectedIssue || isTaskTitleMissing,
3551
3229
  size: "default",
@@ -3561,109 +3239,11 @@ function IssueManagerTaskComposerPane({
3561
3239
  }
3562
3240
 
3563
3241
  // src/ui/internal/shell/IssueManagerTaskDrawer.tsx
3564
- import { ScrollArea as ScrollArea4 } from "@nextop-os/ui-system";
3242
+ import { ScrollArea as ScrollArea3, cn as cn8 } from "@nextop-os/ui-system";
3565
3243
 
3566
3244
  // src/ui/internal/shell/IssueManagerTaskDrawerSections.tsx
3567
- import {
3568
- Badge as Badge6,
3569
- Button as Button12,
3570
- CloseIcon as CloseIcon3,
3571
- DropdownMenu,
3572
- DropdownMenuContent,
3573
- DropdownMenuItem,
3574
- DropdownMenuTrigger,
3575
- Input as Input5,
3576
- Select as Select2,
3577
- SelectContent as SelectContent2,
3578
- SelectItem as SelectItem2,
3579
- SelectTrigger as SelectTrigger2,
3580
- SelectValue,
3581
- CapabilityIcon
3582
- } from "@nextop-os/ui-system";
3583
-
3584
- // src/ui/internal/content/IssueManagerContextSection.tsx
3585
- import { Button as Button11, DirectoryIcon, FileIcon as FileIcon3 } from "@nextop-os/ui-system";
3586
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
3587
- function IssueManagerContextSection({
3588
- copy,
3589
- emptyLabel,
3590
- onAdd,
3591
- onOpen,
3592
- onRemove,
3593
- refs
3594
- }) {
3595
- return /* @__PURE__ */ jsxs15("section", { className: "rounded-lg border border-border-1 bg-transparent px-4 py-4", children: [
3596
- /* @__PURE__ */ jsxs15("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
3597
- /* @__PURE__ */ jsx15("h4", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.contextReferences") }),
3598
- /* @__PURE__ */ jsx15(
3599
- Button11,
3600
- {
3601
- className: "px-3",
3602
- size: "dialog",
3603
- type: "button",
3604
- variant: "secondary",
3605
- onClick: onAdd,
3606
- children: copy.t("actions.addReferences")
3607
- }
3608
- )
3609
- ] }),
3610
- 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(
3611
- "div",
3612
- {
3613
- className: "flex items-center justify-between gap-3 rounded-lg border border-[var(--border-2)] bg-transparent px-3.5 py-3",
3614
- children: [
3615
- /* @__PURE__ */ jsxs15(
3616
- "button",
3617
- {
3618
- className: "flex min-w-0 flex-1 items-center gap-3 text-left",
3619
- type: "button",
3620
- onClick: () => {
3621
- void onOpen({
3622
- displayName: ref.displayName,
3623
- kind: ref.path.endsWith("/") ? "folder" : "file",
3624
- path: ref.path
3625
- });
3626
- },
3627
- children: [
3628
- ref.path.endsWith("/") ? /* @__PURE__ */ jsx15(
3629
- DirectoryIcon,
3630
- {
3631
- className: "shrink-0 text-[var(--text-secondary)]",
3632
- size: 16
3633
- }
3634
- ) : /* @__PURE__ */ jsx15(
3635
- FileIcon3,
3636
- {
3637
- className: "shrink-0 text-[var(--text-secondary)]",
3638
- size: 16
3639
- }
3640
- ),
3641
- /* @__PURE__ */ jsxs15("span", { className: "min-w-0", children: [
3642
- /* @__PURE__ */ jsx15("span", { className: "block truncate text-sm font-semibold leading-5 text-[var(--text-primary)]", children: ref.displayName }),
3643
- /* @__PURE__ */ jsx15("span", { className: "block truncate text-xs leading-[1.55] text-[var(--text-secondary)]", children: ref.path })
3644
- ] })
3645
- ]
3646
- }
3647
- ),
3648
- /* @__PURE__ */ jsx15(
3649
- Button11,
3650
- {
3651
- className: "h-7 rounded-md px-2 text-[13px] font-semibold text-[var(--text-secondary)] hover:text-[var(--text-primary)]",
3652
- size: "sm",
3653
- type: "button",
3654
- variant: "ghost",
3655
- onClick: () => {
3656
- void onRemove(ref);
3657
- },
3658
- children: copy.t("actions.removeReference")
3659
- }
3660
- )
3661
- ]
3662
- },
3663
- ref.contextRefId
3664
- )) })
3665
- ] });
3666
- }
3245
+ import { useState as useState7 } from "react";
3246
+ import { Badge as Badge5, Button as Button9, ConfirmationDialog as ConfirmationDialog2 } from "@nextop-os/ui-system";
3667
3247
 
3668
3248
  // src/ui/internal/shell/IssueManagerTaskDrawerState.ts
3669
3249
  function resolveIssueManagerTaskDrawerViewState(input) {
@@ -3686,193 +3266,173 @@ function resolveIssueManagerTaskDrawerViewState(input) {
3686
3266
  title: isCreate || isEdit ? isCreate ? controller.copy.t("actions.createTask") : controller.copy.t("actions.editTask") : selectedTask?.title || controller.copy.t("labels.taskDetails")
3687
3267
  };
3688
3268
  }
3689
- function resolveIssueManagerTaskRefs(input) {
3690
- return input.controller.taskDetail.value?.contextRefs.filter(
3691
- (ref) => ref.parentKind === "task"
3692
- ) ?? [];
3693
- }
3694
3269
  function canIssueManagerSaveTask(input) {
3695
3270
  return input.selectedIssue !== null && input.view.isTaskTitleMissing === false;
3696
3271
  }
3697
3272
 
3698
3273
  // src/ui/internal/shell/IssueManagerTaskDrawerSections.tsx
3699
- import { Fragment, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
3700
- var taskPriorityOptions = ["high", "medium", "low"];
3274
+ import { Fragment, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
3701
3275
  function IssueManagerTaskDrawerHeader({
3702
3276
  controller,
3703
3277
  selectedTask,
3704
- view,
3705
- onClose
3278
+ view
3706
3279
  }) {
3707
3280
  const copy = controller.copy;
3708
- return /* @__PURE__ */ jsxs16("div", { className: "flex items-start justify-between gap-4 border-b border-border-1 px-7 py-5", children: [
3709
- /* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1", children: [
3710
- 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 }),
3711
- 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: [
3712
- /* @__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) }),
3713
- /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
3714
- /* @__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) }),
3715
- /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
3716
- /* @__PURE__ */ jsxs16("span", { children: [
3717
- copy.t("labels.updatedAt"),
3718
- " ",
3719
- formatIssueManagerTimestamp(
3720
- selectedTask.updatedAtUnix ?? selectedTask.createdAtUnix
3721
- ) || "-"
3722
- ] }),
3723
- /* @__PURE__ */ jsx16("span", { className: "mx-3 h-[13px] w-px shrink-0 bg-border-1" }),
3724
- /* @__PURE__ */ jsx16("span", { className: "min-w-0 truncate", children: resolveTaskCreatorLabel(selectedTask) })
3725
- ] }) : null
3726
- ] }),
3727
- /* @__PURE__ */ jsxs16("div", { className: "flex shrink-0 items-center gap-2", children: [
3728
- view.showTaskActions && selectedTask ? /* @__PURE__ */ jsxs16(DropdownMenu, { children: [
3729
- /* @__PURE__ */ jsx16(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx16(
3730
- Button12,
3731
- {
3732
- "aria-label": copy.t("actions.moreActions"),
3733
- size: "icon-sm",
3734
- type: "button",
3735
- variant: "ghost",
3736
- children: /* @__PURE__ */ jsx16(
3737
- "span",
3738
- {
3739
- "aria-hidden": "true",
3740
- className: "text-base leading-none tracking-[0.18em] text-[var(--text-secondary)]",
3741
- children: "..."
3742
- }
3743
- )
3744
- }
3745
- ) }),
3746
- /* @__PURE__ */ jsxs16(DropdownMenuContent, { align: "end", sideOffset: 8, children: [
3747
- /* @__PURE__ */ jsx16(
3748
- 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,
3749
3290
  {
3291
+ type: "button",
3292
+ variant: "ghost",
3750
3293
  onClick: () => controller.setTaskEditorMode("edit"),
3751
- children: copy.t("actions.editTask")
3294
+ children: copy.t("actions.edit")
3752
3295
  }
3753
3296
  ),
3754
- /* @__PURE__ */ jsx16(
3755
- DropdownMenuItem,
3297
+ /* @__PURE__ */ jsx13(
3298
+ Button9,
3756
3299
  {
3757
- variant: "destructive",
3758
- onClick: () => {
3759
- void controller.deleteTask();
3760
- },
3761
- 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")
3762
3305
  }
3763
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) || "-"
3764
3340
  ] })
3765
- ] }) : null,
3766
- /* @__PURE__ */ jsx16(
3767
- Button12,
3768
- {
3769
- "aria-label": copy.t("actions.cancel"),
3770
- size: "icon-sm",
3771
- type: "button",
3772
- variant: "ghost",
3773
- onClick: onClose,
3774
- children: /* @__PURE__ */ jsx16(CloseIcon3, { size: 16 })
3775
- }
3776
- )
3777
- ] })
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
3778
3363
  ] });
3779
3364
  }
3780
3365
  function IssueManagerTaskDrawerLoadingBody() {
3781
- return /* @__PURE__ */ jsx16(IssueManagerTaskDrawerLoadingState, {});
3366
+ return /* @__PURE__ */ jsx13(IssueManagerTaskDrawerLoadingState, {});
3782
3367
  }
3783
3368
  function IssueManagerTaskDrawerBody({
3784
3369
  controller,
3785
3370
  taskContent,
3786
- taskRefs,
3787
3371
  view
3788
3372
  }) {
3789
3373
  if (view.bodyKind === "loading") {
3790
- return /* @__PURE__ */ jsx16(IssueManagerTaskDrawerLoadingBody, {});
3374
+ return /* @__PURE__ */ jsx13(IssueManagerTaskDrawerLoadingBody, {});
3791
3375
  }
3792
3376
  if (view.bodyKind === "edit") {
3793
- return /* @__PURE__ */ jsx16(
3377
+ return /* @__PURE__ */ jsx13(
3794
3378
  IssueManagerTaskDrawerEditBody,
3795
3379
  {
3796
3380
  controller,
3797
- isCreate: view.isCreate,
3798
- taskRefs
3381
+ title: view.title
3799
3382
  }
3800
3383
  );
3801
3384
  }
3802
- return /* @__PURE__ */ jsx16(
3385
+ return /* @__PURE__ */ jsx13(
3803
3386
  IssueManagerTaskDrawerReadBody,
3804
3387
  {
3805
3388
  controller,
3806
- taskContent,
3807
- taskRefs
3389
+ taskContent
3808
3390
  }
3809
3391
  );
3810
3392
  }
3811
3393
  function IssueManagerTaskDrawerEditBody({
3812
3394
  controller,
3813
- isCreate,
3814
- taskRefs
3395
+ title
3815
3396
  }) {
3816
3397
  const copy = controller.copy;
3817
- return /* @__PURE__ */ jsxs16(Fragment, { children: [
3818
- /* @__PURE__ */ jsxs16("div", { className: "grid gap-5", children: [
3819
- /* @__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(
3820
3408
  "label",
3821
3409
  {
3822
- 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}`,
3823
3411
  children: [
3824
- /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.title") }),
3825
- /* @__PURE__ */ jsx16(
3826
- Input5,
3412
+ /* @__PURE__ */ jsx13("span", { className: "leading-5", children: copy.t("labels.title") }),
3413
+ /* @__PURE__ */ jsx13(
3414
+ IssueManagerDraftTitleInput,
3827
3415
  {
3828
3416
  placeholder: copy.t("composer.taskTitlePlaceholder"),
3829
- variant: "md",
3830
3417
  value: controller.taskDraft.title,
3831
- onChange: (event) => controller.setTaskTitle(event.target.value)
3418
+ onChange: controller.setTaskTitle
3832
3419
  }
3833
3420
  )
3834
3421
  ]
3835
3422
  }
3836
3423
  ),
3837
- /* @__PURE__ */ jsx16(
3838
- "div",
3839
- {
3840
- className: `flex flex-wrap items-center gap-3 ${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay1ClassName}`,
3841
- children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
3842
- /* @__PURE__ */ jsx16("span", { className: "text-sm font-medium text-[var(--text-secondary)]", children: copy.t("labels.priority") }),
3843
- /* @__PURE__ */ jsxs16(
3844
- Select2,
3845
- {
3846
- value: controller.taskDraft.priority,
3847
- onValueChange: (value) => controller.setTaskPriority(value),
3848
- children: [
3849
- /* @__PURE__ */ jsx16(
3850
- SelectTrigger2,
3851
- {
3852
- "aria-label": copy.t("labels.priority"),
3853
- className: "min-w-28 rounded-lg border-border-1 bg-transparency-block text-sm",
3854
- children: /* @__PURE__ */ jsx16(SelectValue, {})
3855
- }
3856
- ),
3857
- /* @__PURE__ */ jsx16(SelectContent2, { style: { zIndex: "var(--z-panel-popover)" }, children: taskPriorityOptions.map((priority) => /* @__PURE__ */ jsx16(SelectItem2, { value: priority, children: resolveIssueManagerPriorityLabel(copy, priority) }, priority)) })
3858
- ]
3859
- }
3860
- )
3861
- ] })
3862
- }
3863
- ),
3864
- /* @__PURE__ */ jsxs16(
3424
+ /* @__PURE__ */ jsxs11(
3865
3425
  "div",
3866
3426
  {
3867
- 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}`,
3868
3428
  children: [
3869
- /* @__PURE__ */ jsx16("span", { className: "text-sm font-semibold leading-5 text-[var(--text-primary)]", children: copy.t("labels.content") }),
3870
- /* @__PURE__ */ jsx16(
3429
+ /* @__PURE__ */ jsx13("span", { className: "leading-5", children: copy.t("labels.content") }),
3430
+ /* @__PURE__ */ jsx13(
3871
3431
  IssueManagerRichTextTextarea,
3872
3432
  {
3873
3433
  controller,
3874
3434
  surface: "task",
3875
- textareaClassName: "min-h-[12rem] resize-none",
3435
+ textareaClassName: "min-h-[180px] resize-none",
3876
3436
  placeholder: copy.t("composer.taskContentPlaceholder"),
3877
3437
  value: controller.taskDraft.content,
3878
3438
  onChange: controller.setTaskContent
@@ -3881,73 +3441,44 @@ function IssueManagerTaskDrawerEditBody({
3881
3441
  ]
3882
3442
  }
3883
3443
  )
3884
- ] }),
3885
- /* @__PURE__ */ jsx16(
3886
- "div",
3887
- {
3888
- className: `${issueManagerEditorRiseInClassName} ${issueManagerEditorRiseInDelay3ClassName}`,
3889
- children: /* @__PURE__ */ jsx16(
3890
- IssueManagerContextSection,
3891
- {
3892
- copy,
3893
- emptyLabel: copy.t("messages.noTaskReferences"),
3894
- refs: taskRefs,
3895
- onAdd: () => {
3896
- void controller.attachReferences("task");
3897
- },
3898
- onOpen: controller.openReference,
3899
- onRemove: controller.removeContextRef
3900
- }
3901
- )
3902
- }
3903
- ),
3904
- !isCreate ? /* @__PURE__ */ jsx16(
3905
- IssueManagerRunPanels,
3906
- {
3907
- copy,
3908
- outputs: controller.taskDetail.value?.latestOutputs ?? [],
3909
- recentRuns: controller.taskDetail.value?.recentRuns ?? [],
3910
- onOpen: controller.openReference
3911
- }
3912
- ) : null
3444
+ ] })
3913
3445
  ] });
3914
3446
  }
3915
3447
  function IssueManagerTaskDrawerReadBody({
3916
3448
  controller,
3917
- taskContent,
3918
- taskRefs
3449
+ taskContent
3919
3450
  }) {
3920
3451
  const copy = controller.copy;
3921
- return /* @__PURE__ */ jsxs16(Fragment, { children: [
3922
- /* @__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(
3923
3456
  IssueManagerDescriptionSection,
3924
3457
  {
3925
3458
  content: taskContent,
3926
3459
  emptyLabel: copy.t("messages.taskContentEmpty"),
3927
- label: copy.t("labels.content"),
3928
- minHeightClass: "min-h-[8rem]",
3929
- onOpen: controller.openReference
3460
+ label: copy.t("labels.description"),
3461
+ onOpen: controller.openReference,
3462
+ variant: "plain"
3930
3463
  }
3931
3464
  ),
3932
- /* @__PURE__ */ jsx16(
3933
- IssueManagerContextSection,
3465
+ /* @__PURE__ */ jsx13(
3466
+ IssueManagerDetailTextSection,
3934
3467
  {
3935
- copy,
3936
- emptyLabel: copy.t("messages.noTaskReferences"),
3937
- refs: taskRefs,
3938
- onAdd: () => {
3939
- void controller.attachReferences("task");
3940
- },
3941
- onOpen: controller.openReference,
3942
- 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"
3943
3475
  }
3944
3476
  ),
3945
- /* @__PURE__ */ jsx16(
3946
- IssueManagerRunPanels,
3477
+ /* @__PURE__ */ jsx13(
3478
+ IssueManagerOutputSection,
3947
3479
  {
3948
3480
  copy,
3949
- outputs: controller.taskDetail.value?.latestOutputs ?? [],
3950
- recentRuns: controller.taskDetail.value?.recentRuns ?? [],
3481
+ outputs: latestOutputs,
3951
3482
  onOpen: controller.openReference
3952
3483
  }
3953
3484
  )
@@ -3961,18 +3492,26 @@ function IssueManagerTaskDrawerFooter({
3961
3492
  }) {
3962
3493
  const copy = controller.copy;
3963
3494
  if (view.showReadFooter && selectedTask) {
3964
- 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: [
3965
- /* @__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(
3966
3505
  IssueManagerRunActionTrigger,
3967
3506
  {
3968
3507
  controller,
3969
- triggerClassName: "min-w-[11rem]"
3508
+ triggerVariant: "button"
3970
3509
  }
3971
3510
  ),
3972
- controller.canInviteCollaborators ? /* @__PURE__ */ jsx16(
3973
- Button12,
3511
+ controller.canInviteCollaborators ? /* @__PURE__ */ jsx13(
3512
+ Button9,
3974
3513
  {
3975
- className: "shrink-0 px-4",
3514
+ disabled: !selectedIssue,
3976
3515
  size: "dialog",
3977
3516
  type: "button",
3978
3517
  onClick: () => {
@@ -3984,51 +3523,34 @@ function IssueManagerTaskDrawerFooter({
3984
3523
  ] }) });
3985
3524
  }
3986
3525
  if (view.showEditFooter) {
3987
- return /* @__PURE__ */ jsx16(
3526
+ return /* @__PURE__ */ jsx13(
3988
3527
  "div",
3989
3528
  {
3990
- className: `border-t border-border-1 px-7 py-4 ${issueManagerEditorFooterFadeInClassName}`,
3991
- children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-3", children: [
3992
- /* @__PURE__ */ jsx16("div", { className: "flex items-center gap-2", children: !view.isCreate && selectedTask ? /* @__PURE__ */ jsx16(
3993
- 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,
3994
3533
  {
3995
- size: "default",
3534
+ size: "dialog",
3996
3535
  type: "button",
3997
- variant: "destructive",
3998
- onClick: () => {
3999
- void controller.deleteTask();
4000
- },
4001
- children: copy.t("actions.deleteTask")
3536
+ variant: "secondary",
3537
+ onClick: () => controller.setTaskEditorMode("read"),
3538
+ children: copy.t("actions.cancel")
4002
3539
  }
4003
- ) : null }),
4004
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
4005
- /* @__PURE__ */ jsx16(
4006
- Button12,
4007
- {
4008
- size: "default",
4009
- type: "button",
4010
- variant: "secondary",
4011
- onClick: () => controller.setTaskEditorMode("read"),
4012
- children: copy.t("actions.cancel")
4013
- }
4014
- ),
4015
- /* @__PURE__ */ jsxs16(
4016
- Button12,
4017
- {
4018
- disabled: canIssueManagerSaveTask({
4019
- selectedIssue,
4020
- view
4021
- }) === false,
4022
- size: "default",
4023
- type: "button",
4024
- onClick: () => void controller.saveTask(),
4025
- children: [
4026
- /* @__PURE__ */ jsx16(CapabilityIcon, { size: 16 }),
4027
- copy.t("actions.saveTask")
4028
- ]
4029
- }
4030
- )
4031
- ] })
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
+ )
4032
3554
  ] })
4033
3555
  }
4034
3556
  );
@@ -4037,9 +3559,10 @@ function IssueManagerTaskDrawerFooter({
4037
3559
  }
4038
3560
 
4039
3561
  // src/ui/internal/shell/IssueManagerTaskDrawer.tsx
4040
- import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
3562
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
4041
3563
  function IssueManagerTaskDrawer({
4042
3564
  controller,
3565
+ isClosing,
4043
3566
  selectedIssue,
4044
3567
  selectedTask,
4045
3568
  onClose
@@ -4048,38 +3571,58 @@ function IssueManagerTaskDrawer({
4048
3571
  controller,
4049
3572
  selectedTask
4050
3573
  });
4051
- const taskRefs = resolveIssueManagerTaskRefs({ controller });
4052
3574
  const taskContent = selectedTask?.content ?? "";
4053
- return /* @__PURE__ */ jsx17(
3575
+ return /* @__PURE__ */ jsx14(
4054
3576
  "div",
4055
3577
  {
4056
- 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
+ ),
4057
3582
  onClick: onClose,
4058
- children: /* @__PURE__ */ jsxs17(
3583
+ onTouchMove: (event) => {
3584
+ event.preventDefault();
3585
+ },
3586
+ onWheel: (event) => {
3587
+ event.preventDefault();
3588
+ },
3589
+ children: /* @__PURE__ */ jsxs12(
4059
3590
  "aside",
4060
3591
  {
4061
- 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
+ ),
4062
3596
  onClick: (event) => event.stopPropagation(),
3597
+ onTouchMove: (event) => event.stopPropagation(),
3598
+ onWheel: (event) => event.stopPropagation(),
4063
3599
  children: [
4064
- /* @__PURE__ */ jsx17(
3600
+ view.bodyKind === "edit" ? null : /* @__PURE__ */ jsx14(
4065
3601
  IssueManagerTaskDrawerHeader,
4066
3602
  {
4067
3603
  controller,
4068
3604
  selectedTask,
4069
- view,
4070
- onClose
3605
+ view
4071
3606
  }
4072
3607
  ),
4073
- /* @__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(
4074
- IssueManagerTaskDrawerBody,
3608
+ /* @__PURE__ */ jsx14(ScrollArea3, { className: "min-h-0 flex-1 [&_[data-slot=scroll-area-viewport]]:overscroll-contain", children: /* @__PURE__ */ jsx14(
3609
+ "div",
4075
3610
  {
4076
- controller,
4077
- taskContent,
4078
- taskRefs,
4079
- 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
+ )
4080
3623
  }
4081
- ) }) }),
4082
- /* @__PURE__ */ jsx17(
3624
+ ) }),
3625
+ /* @__PURE__ */ jsx14(
4083
3626
  IssueManagerTaskDrawerFooter,
4084
3627
  {
4085
3628
  controller,
@@ -4098,7 +3641,7 @@ function IssueManagerTaskDrawer({
4098
3641
  // src/ui/internal/shell/useIssueManagerShellView.ts
4099
3642
  import {
4100
3643
  useEffect as useEffect7,
4101
- useEffectEvent as useEffectEvent3,
3644
+ useEffectEvent as useEffectEvent2,
4102
3645
  useRef as useRef3,
4103
3646
  useState as useState8
4104
3647
  } from "react";
@@ -4113,7 +3656,7 @@ function useIssueManagerShellView({
4113
3656
  issueManagerSidebarDefaultWidth
4114
3657
  );
4115
3658
  const [isNarrowLayout, setIsNarrowLayout] = useState8(false);
4116
- const dismissNotification = useEffectEvent3(() => {
3659
+ const dismissNotification = useEffectEvent2(() => {
4117
3660
  controller.dismissNotification();
4118
3661
  });
4119
3662
  const floatingNotice = controller.floatingNotice;
@@ -4250,7 +3793,8 @@ function useIssueManagerShellView({
4250
3793
  }
4251
3794
 
4252
3795
  // src/ui/internal/shell/IssueManagerShell.tsx
4253
- 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;
4254
3798
  function IssueManagerShell({
4255
3799
  controller,
4256
3800
  emptyIllustration,
@@ -4264,7 +3808,32 @@ function IssueManagerShell({
4264
3808
  selectedIssue,
4265
3809
  selectedTask
4266
3810
  });
4267
- 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(
4268
3837
  "div",
4269
3838
  {
4270
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",
@@ -4273,8 +3842,8 @@ function IssueManagerShell({
4273
3842
  ref: shellView.layoutRef,
4274
3843
  style: shellView.layoutStyle,
4275
3844
  children: [
4276
- shellView.floatingNotice ? /* @__PURE__ */ jsx18(IssueManagerFloatingNotice, { notice: shellView.floatingNotice }) : null,
4277
- /* @__PURE__ */ jsx18(
3845
+ shellView.floatingNotice ? /* @__PURE__ */ jsx15(IssueManagerFloatingNotice, { notice: shellView.floatingNotice }) : null,
3846
+ /* @__PURE__ */ jsx15(
4278
3847
  IssueManagerSidebar,
4279
3848
  {
4280
3849
  controller,
@@ -4285,7 +3854,7 @@ function IssueManagerShell({
4285
3854
  statusCounts: shellView.sidebar.statusCounts
4286
3855
  }
4287
3856
  ),
4288
- shellView.sidebar.isAutoCollapsed ? null : /* @__PURE__ */ jsx18(
3857
+ shellView.sidebar.isAutoCollapsed ? null : /* @__PURE__ */ jsx15(
4289
3858
  "div",
4290
3859
  {
4291
3860
  "aria-label": controller.copy.t("labels.resizeIssueList"),
@@ -4293,7 +3862,7 @@ function IssueManagerShell({
4293
3862
  "aria-valuemax": shellView.resizeHandle.ariaValueMax,
4294
3863
  "aria-valuemin": shellView.resizeHandle.ariaValueMin,
4295
3864
  "aria-valuenow": shellView.resizeHandle.ariaValueNow,
4296
- className: cn11(
3865
+ className: cn9(
4297
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",
4298
3867
  shellView.sidebar.isCollapsed && "pointer-events-none left-[-6px] opacity-0"
4299
3868
  ),
@@ -4304,56 +3873,56 @@ function IssueManagerShell({
4304
3873
  onPointerDown: shellView.resizeHandle.onPointerDown,
4305
3874
  onPointerMove: shellView.resizeHandle.onPointerMove,
4306
3875
  onPointerUp: shellView.resizeHandle.onPointerUp,
4307
- 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)]" })
4308
3877
  }
4309
3878
  ),
4310
- /* @__PURE__ */ jsxs18("div", { className: "relative h-full min-h-0 overflow-hidden bg-transparent", children: [
4311
- /* @__PURE__ */ jsxs18("div", { className: "flex h-full min-h-0 flex-col", children: [
4312
- /* @__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(
4313
3882
  IssueManagerIssuePane,
4314
3883
  {
4315
3884
  controller,
4316
3885
  selectedIssue,
4317
3886
  onDismissCreate: onDismissIssueCreate
4318
3887
  }
4319
- ) : shellView.content.isTaskCreating ? /* @__PURE__ */ jsx18(
3888
+ ) : shellView.content.isTaskCreating ? /* @__PURE__ */ jsx15(
4320
3889
  IssueManagerTaskComposerPane,
4321
3890
  {
4322
3891
  controller,
4323
3892
  selectedIssue,
4324
3893
  onCancel: () => controller.setTaskEditorMode("read")
4325
3894
  }
4326
- ) : selectedIssue ? /* @__PURE__ */ jsx18(
3895
+ ) : selectedIssue ? /* @__PURE__ */ jsx15(
4327
3896
  IssueManagerIssuePane,
4328
3897
  {
4329
3898
  controller,
4330
3899
  selectedIssue,
4331
3900
  onDismissCreate: onDismissIssueCreate
4332
3901
  }
4333
- ) : /* @__PURE__ */ jsx18(
3902
+ ) : /* @__PURE__ */ jsx15(
4334
3903
  IssueManagerShellEmptyState,
4335
3904
  {
4336
3905
  controller,
4337
3906
  emptyIllustration
4338
3907
  }
4339
3908
  ) }),
4340
- /* @__PURE__ */ jsx18(
3909
+ /* @__PURE__ */ jsx15(
4341
3910
  IssueManagerBottomBar,
4342
3911
  {
4343
3912
  controller,
4344
3913
  isNarrowLayout: shellView.isNarrowLayout,
4345
3914
  selectedIssue,
4346
- selectedTask,
4347
3915
  visible: shellView.content.showBottomBar
4348
3916
  }
4349
3917
  )
4350
3918
  ] }),
4351
- shellView.content.isTaskDrawerOpen ? /* @__PURE__ */ jsx18(
3919
+ taskDrawerTask ? /* @__PURE__ */ jsx15(
4352
3920
  IssueManagerTaskDrawer,
4353
3921
  {
4354
3922
  controller,
3923
+ isClosing: isTaskDrawerClosing,
4355
3924
  selectedIssue,
4356
- selectedTask,
3925
+ selectedTask: taskDrawerTask,
4357
3926
  onClose: onCloseTaskDrawer
4358
3927
  }
4359
3928
  ) : null
@@ -4366,18 +3935,18 @@ function IssueManagerShellEmptyState({
4366
3935
  controller,
4367
3936
  emptyIllustration
4368
3937
  }) {
4369
- 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: [
4370
3939
  emptyIllustration ?? null,
4371
- /* @__PURE__ */ jsx18("h2", { className: "text-lg font-semibold leading-[1.35] text-[var(--text-primary)]", children: controller.copy.t("messages.noIssues") }),
4372
- /* @__PURE__ */ jsx18("p", { className: "max-w-[420px] text-base leading-[1.3] text-[var(--text-secondary)]", children: controller.copy.t("emptyState") }),
4373
- /* @__PURE__ */ jsxs18(
4374
- 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,
4375
3944
  {
4376
3945
  className: "mt-2 gap-2",
4377
3946
  type: "button",
4378
3947
  onClick: () => controller.setIssueEditorMode("create"),
4379
3948
  children: [
4380
- /* @__PURE__ */ jsx18(FileCreateIcon4, { size: 16 }),
3949
+ /* @__PURE__ */ jsx15(FileCreateIcon4, { size: 16 }),
4381
3950
  controller.copy.t("actions.createIssue")
4382
3951
  ]
4383
3952
  }
@@ -4385,8 +3954,330 @@ function IssueManagerShellEmptyState({
4385
3954
  ] }) });
4386
3955
  }
4387
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
+
4388
4279
  // src/ui/IssueManagerNode.tsx
4389
- import { jsx as jsx19, jsxs as jsxs19 } from "react/jsx-runtime";
4280
+ import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
4390
4281
  function IssueManagerNode({
4391
4282
  emptyIllustration,
4392
4283
  feature,
@@ -4406,7 +4297,27 @@ function IssueManagerNode({
4406
4297
  state,
4407
4298
  workspaceId
4408
4299
  });
4409
- 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(
4410
4321
  "section",
4411
4322
  {
4412
4323
  "aria-label": controller.copy.t("title"),
@@ -4414,7 +4325,7 @@ function IssueManagerNode({
4414
4325
  "data-issue-manager-node-id": nodeId,
4415
4326
  "data-issue-manager-workspace-id": workspaceId,
4416
4327
  children: [
4417
- /* @__PURE__ */ jsx19(
4328
+ /* @__PURE__ */ jsx17(
4418
4329
  IssueManagerShell,
4419
4330
  {
4420
4331
  controller,
@@ -4425,8 +4336,8 @@ function IssueManagerNode({
4425
4336
  selectedTask
4426
4337
  }
4427
4338
  ),
4428
- /* @__PURE__ */ jsx19(
4429
- IssueManagerReferencePicker,
4339
+ /* @__PURE__ */ jsx17(
4340
+ WorkspaceFileReferencePicker,
4430
4341
  {
4431
4342
  copy: controller.copy,
4432
4343
  fileAdapter: feature.fileAdapter,
@@ -4441,6 +4352,7 @@ function IssueManagerNode({
4441
4352
  );
4442
4353
  }
4443
4354
  function IssueManagerNodeHeader({
4355
+ activeTopicId = null,
4444
4356
  className,
4445
4357
  copy,
4446
4358
  defaultActions,
@@ -4458,19 +4370,64 @@ function IssueManagerNodeHeader({
4458
4370
  nodeId,
4459
4371
  onToggleSidebar
4460
4372
  });
4461
- return /* @__PURE__ */ jsxs19(
4373
+ const topicState = useIssueManagerTopicHeaderStateSync({
4374
+ activeTopicId,
4375
+ nodeId
4376
+ });
4377
+ return /* @__PURE__ */ jsxs15(
4462
4378
  "header",
4463
4379
  {
4464
4380
  ...headerProps,
4465
- className: cn12(
4381
+ className: cn11(
4466
4382
  "flex h-full min-h-0 items-center justify-between gap-3 bg-[var(--background-panel)] px-2 pl-3",
4467
4383
  className
4468
4384
  ),
4469
4385
  children: [
4470
- /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 items-center gap-2", children: [
4471
- /* @__PURE__ */ jsx19("span", { className: "min-w-0 truncate text-[13px] font-semibold leading-5 text-[var(--text-primary)]", children: title?.trim() || copy.t("title") }),
4472
- /* @__PURE__ */ jsx19(
4473
- 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,
4474
4431
  {
4475
4432
  "aria-label": toggleLabel,
4476
4433
  className: "cursor-pointer rounded-md",
@@ -4486,11 +4443,11 @@ function IssueManagerNodeHeader({
4486
4443
  },
4487
4444
  onDoubleClick: (event) => event.stopPropagation(),
4488
4445
  onPointerDown: (event) => event.stopPropagation(),
4489
- children: /* @__PURE__ */ jsx19(PanelIcon, { className: "size-[18px]" })
4446
+ children: /* @__PURE__ */ jsx17(PanelIcon, { className: "size-[18px]" })
4490
4447
  }
4491
4448
  )
4492
4449
  ] }),
4493
- /* @__PURE__ */ jsx19(
4450
+ /* @__PURE__ */ jsx17(
4494
4451
  "div",
4495
4452
  {
4496
4453
  className: "flex flex-none items-center gap-1",
@@ -4509,4 +4466,4 @@ export {
4509
4466
  IssueManagerNode,
4510
4467
  IssueManagerNodeHeader
4511
4468
  };
4512
- //# sourceMappingURL=chunk-K3F67IRA.js.map
4469
+ //# sourceMappingURL=chunk-UT34M3FS.js.map