@tutti-os/workspace-issue-manager 0.0.1
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.
- package/LICENSE +202 -0
- package/README.md +15 -0
- package/dist/assets/workspace-dock-task.d.ts +3 -0
- package/dist/assets/workspace-dock-task.png +0 -0
- package/dist/chunk-3XE7PXVP.js +14 -0
- package/dist/chunk-3XE7PXVP.js.map +1 -0
- package/dist/chunk-4B2P64PY.js +938 -0
- package/dist/chunk-4B2P64PY.js.map +1 -0
- package/dist/chunk-DLB2WIV6.js +5033 -0
- package/dist/chunk-DLB2WIV6.js.map +1 -0
- package/dist/chunk-JDYJIVGG.js +445 -0
- package/dist/chunk-JDYJIVGG.js.map +1 -0
- package/dist/chunk-LEL6VWU4.js +1 -0
- package/dist/chunk-LEL6VWU4.js.map +1 -0
- package/dist/chunk-T5TTRS5M.js +1 -0
- package/dist/chunk-T5TTRS5M.js.map +1 -0
- package/dist/chunk-WJSZFKUD.js +292 -0
- package/dist/chunk-WJSZFKUD.js.map +1 -0
- package/dist/contracts/index.d.ts +492 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/core/index.d.ts +81 -0
- package/dist/core/index.js +66 -0
- package/dist/core/index.js.map +1 -0
- package/dist/feature-D16xMEZU.d.ts +47 -0
- package/dist/i18n/index.d.ts +18 -0
- package/dist/i18n/index.js +14 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/issueManagerControllerService.interface-D8Z1B9k4.d.ts +106 -0
- package/dist/latestRunStatusRenderer-B_9yU0CM.d.ts +14 -0
- package/dist/services/index.d.ts +13 -0
- package/dist/services/index.js +24 -0
- package/dist/services/index.js.map +1 -0
- package/dist/ui/index.d.ts +58 -0
- package/dist/ui/index.js +12 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/workbench/constants.d.ts +6 -0
- package/dist/workbench/constants.js +9 -0
- package/dist/workbench/constants.js.map +1 -0
- package/dist/workbench/index.d.ts +76 -0
- package/dist/workbench/index.js +276 -0
- package/dist/workbench/index.js.map +1 -0
- package/openapi/issue-manager.v1.yaml +1682 -0
- package/package.json +93 -0
|
@@ -0,0 +1,938 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeIssueManagerContent,
|
|
3
|
+
normalizeIssueManagerNodeState
|
|
4
|
+
} from "./chunk-WJSZFKUD.js";
|
|
5
|
+
|
|
6
|
+
// src/services/internal/model.ts
|
|
7
|
+
import { formatNextopShortDateTime } from "@tutti-os/ui-system/date-format";
|
|
8
|
+
function createIssueManagerDate(value) {
|
|
9
|
+
if (!value || !Number.isFinite(value)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const normalized = value < 1e12 ? value * 1e3 : value;
|
|
13
|
+
const date = new Date(normalized);
|
|
14
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
15
|
+
}
|
|
16
|
+
function formatIssueManagerTimestamp(value) {
|
|
17
|
+
const date = createIssueManagerDate(value);
|
|
18
|
+
return date ? formatNextopShortDateTime(date) : null;
|
|
19
|
+
}
|
|
20
|
+
function formatIssueManagerDate(value) {
|
|
21
|
+
const date = createIssueManagerDate(value);
|
|
22
|
+
return date ? formatNextopShortDateTime(date) : "";
|
|
23
|
+
}
|
|
24
|
+
function resolveIssueManagerStatusLabel(copy, status) {
|
|
25
|
+
switch (status) {
|
|
26
|
+
case "not_started":
|
|
27
|
+
return copy.t("status.notStarted");
|
|
28
|
+
case "running":
|
|
29
|
+
return copy.t("status.running");
|
|
30
|
+
case "in_progress":
|
|
31
|
+
return copy.t("status.inProgress");
|
|
32
|
+
case "pending_acceptance":
|
|
33
|
+
return copy.t("status.pendingAcceptance");
|
|
34
|
+
case "completed":
|
|
35
|
+
return copy.t("status.completed");
|
|
36
|
+
case "failed":
|
|
37
|
+
return copy.t("status.failed");
|
|
38
|
+
case "canceled":
|
|
39
|
+
return copy.t("status.canceled");
|
|
40
|
+
default:
|
|
41
|
+
return copy.t("status.unknown");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function resolveIssueManagerPriorityLabel(copy, priority) {
|
|
45
|
+
switch (priority) {
|
|
46
|
+
case "high":
|
|
47
|
+
return copy.t("priority.high");
|
|
48
|
+
case "low":
|
|
49
|
+
return copy.t("priority.low");
|
|
50
|
+
default:
|
|
51
|
+
return copy.t("priority.medium");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function uniqueIssueManagerFileReferences(refs) {
|
|
55
|
+
const unique = /* @__PURE__ */ new Map();
|
|
56
|
+
for (const ref of refs) {
|
|
57
|
+
const normalizedPath = ref.path.trim();
|
|
58
|
+
if (!normalizedPath || unique.has(normalizedPath)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
unique.set(normalizedPath, {
|
|
62
|
+
displayName: ref.displayName?.trim() || void 0,
|
|
63
|
+
kind: ref.kind === "folder" ? "folder" : "file",
|
|
64
|
+
path: normalizedPath
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return [...unique.values()];
|
|
68
|
+
}
|
|
69
|
+
function parentDirectoryPath(path) {
|
|
70
|
+
const trimmed = path.trim();
|
|
71
|
+
if (!trimmed || trimmed === "/") {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
const normalized = trimmed.endsWith("/") && trimmed.length > 1 ? trimmed.slice(0, -1) : trimmed;
|
|
75
|
+
const index = normalized.lastIndexOf("/");
|
|
76
|
+
if (index <= 0) {
|
|
77
|
+
return "/";
|
|
78
|
+
}
|
|
79
|
+
return normalized.slice(0, index) || "/";
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/services/internal/controllerRuntime.ts
|
|
83
|
+
import { proxy } from "valtio/vanilla";
|
|
84
|
+
|
|
85
|
+
// src/services/internal/controllerUtils.ts
|
|
86
|
+
var defaultTaskPriority = "medium";
|
|
87
|
+
function resolveIssueManagerSelectedIssueId(currentSelectedIssueId, issues) {
|
|
88
|
+
if (currentSelectedIssueId && issues.some((issue) => issue.issueId === currentSelectedIssueId)) {
|
|
89
|
+
return currentSelectedIssueId;
|
|
90
|
+
}
|
|
91
|
+
return issues[0]?.issueId ?? null;
|
|
92
|
+
}
|
|
93
|
+
function resolveIssueManagerSelectedTaskId(currentSelectedTaskId, tasks) {
|
|
94
|
+
if (currentSelectedTaskId && tasks.some((task) => task.taskId === currentSelectedTaskId)) {
|
|
95
|
+
return currentSelectedTaskId;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
function toContextRefInput(ref) {
|
|
100
|
+
return {
|
|
101
|
+
displayName: ref.displayName,
|
|
102
|
+
path: ref.path,
|
|
103
|
+
refType: ref.kind === "folder" ? "folder" : "file"
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function toIssueManagerWorkspaceFileLinkInput(ref) {
|
|
107
|
+
return {
|
|
108
|
+
kind: ref.kind === "folder" ? "folder" : "file",
|
|
109
|
+
name: ref.displayName,
|
|
110
|
+
path: ref.path
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function confirmIssueManagerMessage(message) {
|
|
114
|
+
try {
|
|
115
|
+
return globalThis.confirm?.(message) ?? true;
|
|
116
|
+
} catch {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function resolveIssueManagerErrorMessage(error, copy, fallbackKey) {
|
|
121
|
+
const raw = error instanceof Error ? error.message : typeof error === "string" ? error : String(error);
|
|
122
|
+
if (!copy) {
|
|
123
|
+
return raw;
|
|
124
|
+
}
|
|
125
|
+
if (raw === "issue_manager.upload_type_conflict") {
|
|
126
|
+
return copy.t("messages.uploadTypeConflict");
|
|
127
|
+
}
|
|
128
|
+
if (raw === "issue_manager.clipboard_unavailable") {
|
|
129
|
+
return copy.t("messages.clipboardUnavailable");
|
|
130
|
+
}
|
|
131
|
+
if (raw === "issue_manager.workspace_path_unavailable") {
|
|
132
|
+
return copy.t("messages.workspacePathUnavailable");
|
|
133
|
+
}
|
|
134
|
+
if (raw === "issue_manager.run_status_missing") {
|
|
135
|
+
return copy.t("messages.runStatusMissing");
|
|
136
|
+
}
|
|
137
|
+
if (raw === "issue_manager.run_timed_out") {
|
|
138
|
+
return copy.t("messages.runTimedOut");
|
|
139
|
+
}
|
|
140
|
+
if (raw.startsWith("issue_manager.run_exit_code:")) {
|
|
141
|
+
return copy.t("messages.runExitCode", {
|
|
142
|
+
code: raw.slice("issue_manager.run_exit_code:".length)
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return fallbackKey ? copy.t(fallbackKey) : raw;
|
|
146
|
+
}
|
|
147
|
+
function resolveIssueManagerTopicDeleteErrorMessage(error, copy) {
|
|
148
|
+
const protocolError = extractProtocolErrorShape(error);
|
|
149
|
+
if (!protocolError) {
|
|
150
|
+
return resolveIssueManagerErrorMessage(
|
|
151
|
+
error,
|
|
152
|
+
copy,
|
|
153
|
+
"messages.topicDeleteFailed"
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (protocolError.reason === "workspace_issue_topic_not_empty") {
|
|
157
|
+
return copy.t("messages.topicDeleteNotEmpty");
|
|
158
|
+
}
|
|
159
|
+
if (protocolError.reason === "workspace_issue_topic_not_found") {
|
|
160
|
+
return copy.t("messages.topicDeleteNotFound");
|
|
161
|
+
}
|
|
162
|
+
if (protocolError.code === "invalid_request" && protocolError.reason === "malformed_request") {
|
|
163
|
+
return copy.t("messages.topicDeleteDefaultForbidden");
|
|
164
|
+
}
|
|
165
|
+
return copy.t("messages.topicDeleteFailed");
|
|
166
|
+
}
|
|
167
|
+
function extractProtocolErrorShape(error) {
|
|
168
|
+
if (isProtocolErrorShape(error)) {
|
|
169
|
+
return error;
|
|
170
|
+
}
|
|
171
|
+
if (typeof error !== "object" || error === null || !("error" in error)) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
const nestedError = error.error;
|
|
175
|
+
return isProtocolErrorShape(nestedError) ? nestedError : null;
|
|
176
|
+
}
|
|
177
|
+
function isProtocolErrorShape(value) {
|
|
178
|
+
return typeof value === "object" && value !== null && "code" in value && typeof value.code === "string" && (!("reason" in value) || typeof value.reason === "string" || typeof value.reason === "undefined");
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/services/internal/controllerState.ts
|
|
182
|
+
function createIssueManagerIssueDraftFromNodeState(state) {
|
|
183
|
+
return {
|
|
184
|
+
content: state?.issueDraftContent ?? "",
|
|
185
|
+
title: state?.issueDraftTitle ?? ""
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function createIssueManagerTaskDraftFromNodeState(state, priority = defaultTaskPriority) {
|
|
189
|
+
return {
|
|
190
|
+
content: state?.taskDraftContent ?? "",
|
|
191
|
+
priority,
|
|
192
|
+
title: state?.taskDraftTitle ?? ""
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function applyIssueManagerIssueSelection(current, issueId) {
|
|
196
|
+
return {
|
|
197
|
+
...current,
|
|
198
|
+
selectedIssueId: issueId,
|
|
199
|
+
selectedTaskId: null
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function applyIssueManagerTaskSelection(current, taskId) {
|
|
203
|
+
return {
|
|
204
|
+
...current,
|
|
205
|
+
selectedTaskId: taskId
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function applyIssueManagerIssueDeleted(current) {
|
|
209
|
+
return {
|
|
210
|
+
...current,
|
|
211
|
+
selectedIssueId: null,
|
|
212
|
+
selectedTaskId: null
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function applyIssueManagerTaskDeleted(current) {
|
|
216
|
+
return {
|
|
217
|
+
...current,
|
|
218
|
+
selectedTaskId: null
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function applyIssueManagerSelectedAgentProvider(current, provider) {
|
|
222
|
+
return {
|
|
223
|
+
...current,
|
|
224
|
+
selectedAgentProvider: provider
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function applyIssueManagerSelectedExecutionDirectory(current, executionDirectory) {
|
|
228
|
+
return {
|
|
229
|
+
...current,
|
|
230
|
+
selectedExecutionDirectory: executionDirectory?.trim() || null
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function applyIssueManagerIssueListResultToNodeState(current, result) {
|
|
234
|
+
return {
|
|
235
|
+
...current,
|
|
236
|
+
issueListNextPageToken: result.nextPageToken ?? null,
|
|
237
|
+
selectedIssueId: resolveIssueManagerSelectedIssueId(
|
|
238
|
+
current.selectedIssueId,
|
|
239
|
+
result.issues
|
|
240
|
+
)
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
function applyIssueManagerIssueDetailResultToNodeState(current, detail) {
|
|
244
|
+
return {
|
|
245
|
+
...current,
|
|
246
|
+
selectedTaskId: resolveIssueManagerSelectedTaskId(
|
|
247
|
+
current.selectedTaskId,
|
|
248
|
+
detail.tasks
|
|
249
|
+
)
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function syncIssueManagerIssueDraftFromDetail(current, detail, editorMode) {
|
|
253
|
+
if (editorMode !== "read") {
|
|
254
|
+
return current;
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
content: normalizeIssueManagerContent(detail?.issue.content ?? ""),
|
|
258
|
+
title: detail?.issue.title ?? ""
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function syncIssueManagerTaskDraftFromDetail(current, detail, editorMode) {
|
|
262
|
+
if (editorMode !== "read") {
|
|
263
|
+
return current;
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
content: normalizeIssueManagerContent(detail?.task.content ?? ""),
|
|
267
|
+
priority: detail?.task.priority ?? defaultTaskPriority,
|
|
268
|
+
title: detail?.task.title ?? ""
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function applyIssueManagerIssueEditorModeToNodeState(current, editorMode) {
|
|
272
|
+
if (editorMode === "create") {
|
|
273
|
+
return current;
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
...current,
|
|
277
|
+
issueDraftContent: null,
|
|
278
|
+
issueDraftTitle: null
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function applyIssueManagerTaskEditorModeToNodeState(current, editorMode) {
|
|
282
|
+
if (editorMode === "create") {
|
|
283
|
+
return current;
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
...current,
|
|
287
|
+
taskDraftContent: null,
|
|
288
|
+
taskDraftTitle: null
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function applyIssueManagerIssueSaved(current, issueId) {
|
|
292
|
+
return {
|
|
293
|
+
...current,
|
|
294
|
+
issueDraftContent: null,
|
|
295
|
+
issueDraftTitle: null,
|
|
296
|
+
selectedIssueId: issueId
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
function applyIssueManagerTaskSaved(current, taskId) {
|
|
300
|
+
return {
|
|
301
|
+
...current,
|
|
302
|
+
selectedTaskId: taskId,
|
|
303
|
+
taskDraftContent: null,
|
|
304
|
+
taskDraftTitle: null
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function persistIssueManagerIssueDraftContent(current, editorMode, content) {
|
|
308
|
+
if (editorMode !== "create") {
|
|
309
|
+
return current;
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
...current,
|
|
313
|
+
issueDraftContent: content
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function persistIssueManagerTaskDraftContent(current, editorMode, content) {
|
|
317
|
+
if (editorMode !== "create") {
|
|
318
|
+
return current;
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
...current,
|
|
322
|
+
taskDraftContent: content
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// src/services/internal/controllerRuntime.ts
|
|
327
|
+
function createIssueManagerOpenedParams(source) {
|
|
328
|
+
return {
|
|
329
|
+
source,
|
|
330
|
+
trigger: source === "restore" || source === "agent_command" ? "automatic" : "manual"
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function createIssueManagerControllerRuntime(input) {
|
|
334
|
+
const normalizedNodeState = normalizeIssueManagerNodeState(input.state);
|
|
335
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
336
|
+
let deferredIssueSearch = normalizedNodeState.issueSearchQuery;
|
|
337
|
+
let issueDetailSequence = 0;
|
|
338
|
+
let issueListSequence = 0;
|
|
339
|
+
let lastResolvedIssueSearchQuery = null;
|
|
340
|
+
let hasReportedOpened = false;
|
|
341
|
+
let onStateChange;
|
|
342
|
+
let pendingIssueSearchAnalyticsQuery = null;
|
|
343
|
+
let refCount = 0;
|
|
344
|
+
let retained = false;
|
|
345
|
+
let taskDetailSequence = 0;
|
|
346
|
+
let topicListSequence = 0;
|
|
347
|
+
let unsubscribeIssueUpdates = null;
|
|
348
|
+
let snapshot = {
|
|
349
|
+
issueDetail: createAsyncCollectionState(
|
|
350
|
+
null
|
|
351
|
+
),
|
|
352
|
+
issueDraft: createIssueManagerIssueDraftFromNodeState(normalizedNodeState),
|
|
353
|
+
issueEditorMode: "read",
|
|
354
|
+
issues: createAsyncCollectionState([], {
|
|
355
|
+
hasResolved: false
|
|
356
|
+
}),
|
|
357
|
+
isRunningTask: false,
|
|
358
|
+
nodeState: normalizedNodeState,
|
|
359
|
+
notification: null,
|
|
360
|
+
referenceTarget: null,
|
|
361
|
+
taskDetail: createAsyncCollectionState(null),
|
|
362
|
+
taskDraft: createIssueManagerTaskDraftFromNodeState(normalizedNodeState),
|
|
363
|
+
taskEditorMode: "read",
|
|
364
|
+
topics: createAsyncCollectionState([], {
|
|
365
|
+
hasResolved: false
|
|
366
|
+
})
|
|
367
|
+
};
|
|
368
|
+
const store = proxy(snapshot);
|
|
369
|
+
const notify = () => {
|
|
370
|
+
for (const listener of listeners) {
|
|
371
|
+
listener();
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
const setSnapshot = (updater) => {
|
|
375
|
+
const next = typeof updater === "function" ? updater(snapshot) : {
|
|
376
|
+
...snapshot,
|
|
377
|
+
...updater
|
|
378
|
+
};
|
|
379
|
+
if (next === snapshot) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
snapshot = next;
|
|
383
|
+
Object.assign(store, next);
|
|
384
|
+
notify();
|
|
385
|
+
};
|
|
386
|
+
const syncIssueDraftFromCurrentDetail = () => {
|
|
387
|
+
const nextIssueDraft = syncIssueManagerIssueDraftFromDetail(
|
|
388
|
+
snapshot.issueDraft,
|
|
389
|
+
snapshot.issueDetail.value,
|
|
390
|
+
snapshot.issueEditorMode
|
|
391
|
+
);
|
|
392
|
+
if (nextIssueDraft === snapshot.issueDraft) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
setSnapshot((current) => ({
|
|
396
|
+
...current,
|
|
397
|
+
issueDraft: nextIssueDraft
|
|
398
|
+
}));
|
|
399
|
+
};
|
|
400
|
+
const syncTaskDraftFromCurrentDetail = () => {
|
|
401
|
+
const nextTaskDraft = syncIssueManagerTaskDraftFromDetail(
|
|
402
|
+
snapshot.taskDraft,
|
|
403
|
+
snapshot.taskDetail.value,
|
|
404
|
+
snapshot.taskEditorMode
|
|
405
|
+
);
|
|
406
|
+
if (nextTaskDraft === snapshot.taskDraft) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
setSnapshot((current) => ({
|
|
410
|
+
...current,
|
|
411
|
+
taskDraft: nextTaskDraft
|
|
412
|
+
}));
|
|
413
|
+
};
|
|
414
|
+
const applyNodeState = (updater) => {
|
|
415
|
+
const previous = snapshot.nodeState;
|
|
416
|
+
const next = typeof updater === "function" ? updater(previous) : {
|
|
417
|
+
...previous,
|
|
418
|
+
...updater
|
|
419
|
+
};
|
|
420
|
+
if (next === previous) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
setSnapshot((current) => ({
|
|
424
|
+
...current,
|
|
425
|
+
nodeState: next
|
|
426
|
+
}));
|
|
427
|
+
onStateChange?.(next);
|
|
428
|
+
handleNodeStateTransition(previous, next);
|
|
429
|
+
};
|
|
430
|
+
const loadTopics = async () => {
|
|
431
|
+
const sequence = ++topicListSequence;
|
|
432
|
+
setSnapshot((current) => ({
|
|
433
|
+
...current,
|
|
434
|
+
topics: {
|
|
435
|
+
...current.topics,
|
|
436
|
+
error: null,
|
|
437
|
+
isLoading: true
|
|
438
|
+
}
|
|
439
|
+
}));
|
|
440
|
+
try {
|
|
441
|
+
const result = await input.feature.backend.listTopics({
|
|
442
|
+
workspaceId: input.workspaceId
|
|
443
|
+
});
|
|
444
|
+
if (!retained || sequence !== topicListSequence) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (result.topics.length === 0) {
|
|
448
|
+
throw new Error(input.feature.i18n.t("messages.topicListEmpty"));
|
|
449
|
+
}
|
|
450
|
+
setSnapshot((current) => ({
|
|
451
|
+
...current,
|
|
452
|
+
topics: {
|
|
453
|
+
error: null,
|
|
454
|
+
hasResolved: true,
|
|
455
|
+
isLoading: false,
|
|
456
|
+
value: result.topics
|
|
457
|
+
}
|
|
458
|
+
}));
|
|
459
|
+
const currentActiveTopicId = snapshot.nodeState.activeTopicId;
|
|
460
|
+
const currentTopicExists = result.topics.some(
|
|
461
|
+
(topic) => topic.topicId === currentActiveTopicId
|
|
462
|
+
);
|
|
463
|
+
const activeTopicId = currentTopicExists ? currentActiveTopicId : result.topics[0]?.topicId ?? null;
|
|
464
|
+
applyNodeState({
|
|
465
|
+
activeTopicId
|
|
466
|
+
});
|
|
467
|
+
if (activeTopicId && activeTopicId === currentActiveTopicId) {
|
|
468
|
+
void loadIssues();
|
|
469
|
+
}
|
|
470
|
+
} catch (error) {
|
|
471
|
+
if (!retained || sequence !== topicListSequence) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
setSnapshot((current) => ({
|
|
475
|
+
...current,
|
|
476
|
+
topics: {
|
|
477
|
+
error: resolveIssueManagerErrorMessage(error, input.feature.i18n),
|
|
478
|
+
hasResolved: true,
|
|
479
|
+
isLoading: false,
|
|
480
|
+
value: []
|
|
481
|
+
}
|
|
482
|
+
}));
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
const trackIssueSearchAnalytics = (inputValue, resultCount) => {
|
|
486
|
+
const query = inputValue.trim();
|
|
487
|
+
if (!query) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
void Promise.resolve(
|
|
491
|
+
input.feature.analytics?.track({
|
|
492
|
+
name: "issue_manager.task_searched",
|
|
493
|
+
params: {
|
|
494
|
+
queryLength: query.length,
|
|
495
|
+
resultCount
|
|
496
|
+
}
|
|
497
|
+
})
|
|
498
|
+
).catch(() => void 0);
|
|
499
|
+
};
|
|
500
|
+
const flushPendingIssueSearchAnalytics = (searchQuery, resultCount) => {
|
|
501
|
+
if (pendingIssueSearchAnalyticsQuery !== searchQuery || !searchQuery) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
pendingIssueSearchAnalyticsQuery = null;
|
|
505
|
+
trackIssueSearchAnalytics(searchQuery, resultCount);
|
|
506
|
+
};
|
|
507
|
+
const loadIssues = async () => {
|
|
508
|
+
const searchQuery = deferredIssueSearch.trim();
|
|
509
|
+
const activeTopicId = snapshot.nodeState.activeTopicId;
|
|
510
|
+
const sequence = ++issueListSequence;
|
|
511
|
+
if (!activeTopicId) {
|
|
512
|
+
lastResolvedIssueSearchQuery = searchQuery;
|
|
513
|
+
setSnapshot((current) => ({
|
|
514
|
+
...current,
|
|
515
|
+
issues: {
|
|
516
|
+
error: null,
|
|
517
|
+
hasResolved: true,
|
|
518
|
+
isLoading: false,
|
|
519
|
+
value: []
|
|
520
|
+
}
|
|
521
|
+
}));
|
|
522
|
+
flushPendingIssueSearchAnalytics(searchQuery, 0);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
setSnapshot((current) => ({
|
|
526
|
+
...current,
|
|
527
|
+
issues: {
|
|
528
|
+
...current.issues,
|
|
529
|
+
error: null,
|
|
530
|
+
isLoading: true
|
|
531
|
+
}
|
|
532
|
+
}));
|
|
533
|
+
try {
|
|
534
|
+
const result = await input.feature.backend.listIssues({
|
|
535
|
+
searchQuery: searchQuery || void 0,
|
|
536
|
+
statusFilter: snapshot.nodeState.issueStatusFilter,
|
|
537
|
+
topicId: activeTopicId,
|
|
538
|
+
workspaceId: input.workspaceId
|
|
539
|
+
});
|
|
540
|
+
if (!retained || sequence !== issueListSequence) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
lastResolvedIssueSearchQuery = searchQuery;
|
|
544
|
+
setSnapshot((current) => ({
|
|
545
|
+
...current,
|
|
546
|
+
issues: {
|
|
547
|
+
error: null,
|
|
548
|
+
hasResolved: true,
|
|
549
|
+
isLoading: false,
|
|
550
|
+
statusCounts: result.statusCounts ?? current.issues.statusCounts,
|
|
551
|
+
value: result.issues
|
|
552
|
+
}
|
|
553
|
+
}));
|
|
554
|
+
applyNodeState(
|
|
555
|
+
(current) => applyIssueManagerIssueListResultToNodeState(current, result)
|
|
556
|
+
);
|
|
557
|
+
flushPendingIssueSearchAnalytics(searchQuery, result.issues.length);
|
|
558
|
+
} catch (error) {
|
|
559
|
+
if (!retained || sequence !== issueListSequence) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
setSnapshot((current) => ({
|
|
563
|
+
...current,
|
|
564
|
+
issues: {
|
|
565
|
+
error: resolveIssueManagerErrorMessage(error, input.feature.i18n),
|
|
566
|
+
hasResolved: true,
|
|
567
|
+
isLoading: false,
|
|
568
|
+
statusCounts: current.issues.statusCounts,
|
|
569
|
+
value: []
|
|
570
|
+
}
|
|
571
|
+
}));
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
const clearIssueDetail = () => {
|
|
575
|
+
setSnapshot((current) => ({
|
|
576
|
+
...current,
|
|
577
|
+
issueDetail: createAsyncCollectionState(
|
|
578
|
+
null
|
|
579
|
+
)
|
|
580
|
+
}));
|
|
581
|
+
syncIssueDraftFromCurrentDetail();
|
|
582
|
+
};
|
|
583
|
+
const clearTaskDetail = () => {
|
|
584
|
+
setSnapshot((current) => ({
|
|
585
|
+
...current,
|
|
586
|
+
taskDetail: createAsyncCollectionState(
|
|
587
|
+
null
|
|
588
|
+
)
|
|
589
|
+
}));
|
|
590
|
+
syncTaskDraftFromCurrentDetail();
|
|
591
|
+
};
|
|
592
|
+
const loadIssueDetail = async () => {
|
|
593
|
+
const selectedIssueId = snapshot.nodeState.selectedIssueId;
|
|
594
|
+
issueDetailSequence += 1;
|
|
595
|
+
const sequence = issueDetailSequence;
|
|
596
|
+
if (!selectedIssueId) {
|
|
597
|
+
clearIssueDetail();
|
|
598
|
+
clearTaskDetail();
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
setSnapshot((current) => ({
|
|
602
|
+
...current,
|
|
603
|
+
issueDetail: {
|
|
604
|
+
...current.issueDetail,
|
|
605
|
+
error: null,
|
|
606
|
+
isLoading: true
|
|
607
|
+
}
|
|
608
|
+
}));
|
|
609
|
+
try {
|
|
610
|
+
const result = await input.feature.backend.getIssueDetail({
|
|
611
|
+
issueId: selectedIssueId,
|
|
612
|
+
workspaceId: input.workspaceId
|
|
613
|
+
});
|
|
614
|
+
if (!retained || sequence !== issueDetailSequence) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
setSnapshot((current) => ({
|
|
618
|
+
...current,
|
|
619
|
+
issueDetail: {
|
|
620
|
+
error: null,
|
|
621
|
+
isLoading: false,
|
|
622
|
+
value: result
|
|
623
|
+
}
|
|
624
|
+
}));
|
|
625
|
+
syncIssueDraftFromCurrentDetail();
|
|
626
|
+
applyNodeState(
|
|
627
|
+
(current) => applyIssueManagerIssueDetailResultToNodeState(current, result)
|
|
628
|
+
);
|
|
629
|
+
} catch (error) {
|
|
630
|
+
if (!retained || sequence !== issueDetailSequence) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
setSnapshot((current) => ({
|
|
634
|
+
...current,
|
|
635
|
+
issueDetail: {
|
|
636
|
+
error: resolveIssueManagerErrorMessage(error, input.feature.i18n),
|
|
637
|
+
isLoading: false,
|
|
638
|
+
value: null
|
|
639
|
+
}
|
|
640
|
+
}));
|
|
641
|
+
syncIssueDraftFromCurrentDetail();
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
const loadTaskDetail = async () => {
|
|
645
|
+
const selectedIssueId = snapshot.nodeState.selectedIssueId;
|
|
646
|
+
const selectedTaskId = snapshot.nodeState.selectedTaskId;
|
|
647
|
+
taskDetailSequence += 1;
|
|
648
|
+
const sequence = taskDetailSequence;
|
|
649
|
+
if (!selectedIssueId || !selectedTaskId) {
|
|
650
|
+
clearTaskDetail();
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
setSnapshot((current) => ({
|
|
654
|
+
...current,
|
|
655
|
+
taskDetail: {
|
|
656
|
+
...current.taskDetail,
|
|
657
|
+
error: null,
|
|
658
|
+
isLoading: true
|
|
659
|
+
}
|
|
660
|
+
}));
|
|
661
|
+
try {
|
|
662
|
+
const result = await input.feature.backend.getTaskDetail({
|
|
663
|
+
issueId: selectedIssueId,
|
|
664
|
+
taskId: selectedTaskId,
|
|
665
|
+
workspaceId: input.workspaceId
|
|
666
|
+
});
|
|
667
|
+
if (!retained || sequence !== taskDetailSequence) {
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
670
|
+
setSnapshot((current) => ({
|
|
671
|
+
...current,
|
|
672
|
+
taskDetail: {
|
|
673
|
+
error: null,
|
|
674
|
+
isLoading: false,
|
|
675
|
+
value: result
|
|
676
|
+
}
|
|
677
|
+
}));
|
|
678
|
+
syncTaskDraftFromCurrentDetail();
|
|
679
|
+
} catch (error) {
|
|
680
|
+
if (!retained || sequence !== taskDetailSequence) {
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
setSnapshot((current) => ({
|
|
684
|
+
...current,
|
|
685
|
+
taskDetail: {
|
|
686
|
+
error: resolveIssueManagerErrorMessage(error, input.feature.i18n),
|
|
687
|
+
isLoading: false,
|
|
688
|
+
value: null
|
|
689
|
+
}
|
|
690
|
+
}));
|
|
691
|
+
syncTaskDraftFromCurrentDetail();
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
const handleNodeStateTransition = (previous, next) => {
|
|
695
|
+
if (!retained) {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
if (previous.activeTopicId !== next.activeTopicId && next.activeTopicId) {
|
|
699
|
+
applyNodeState({
|
|
700
|
+
selectedIssueId: null,
|
|
701
|
+
selectedTaskId: null
|
|
702
|
+
});
|
|
703
|
+
void loadIssues();
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
if (previous.issueStatusFilter !== next.issueStatusFilter && deferredIssueSearch === snapshot.nodeState.issueSearchQuery) {
|
|
707
|
+
void loadIssues();
|
|
708
|
+
}
|
|
709
|
+
if (previous.selectedIssueId !== next.selectedIssueId) {
|
|
710
|
+
void loadIssueDetail();
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
if (previous.selectedTaskId !== next.selectedTaskId) {
|
|
714
|
+
void loadTaskDetail();
|
|
715
|
+
}
|
|
716
|
+
};
|
|
717
|
+
const retainIssueUpdates = () => {
|
|
718
|
+
if (unsubscribeIssueUpdates || !input.feature.eventSource) {
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
unsubscribeIssueUpdates = input.feature.eventSource.subscribeToIssueUpdates(
|
|
722
|
+
input.workspaceId,
|
|
723
|
+
(event) => {
|
|
724
|
+
if (event.workspaceId.trim() !== input.workspaceId.trim()) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
void loadTopics();
|
|
728
|
+
void loadIssueDetail();
|
|
729
|
+
void loadTaskDetail();
|
|
730
|
+
}
|
|
731
|
+
);
|
|
732
|
+
try {
|
|
733
|
+
const connectResult = input.feature.eventSource.connect?.();
|
|
734
|
+
if (connectResult) {
|
|
735
|
+
void connectResult.catch(() => {
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
} catch {
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
const releaseIssueUpdates = () => {
|
|
742
|
+
unsubscribeIssueUpdates?.();
|
|
743
|
+
unsubscribeIssueUpdates = null;
|
|
744
|
+
};
|
|
745
|
+
return {
|
|
746
|
+
getSnapshot() {
|
|
747
|
+
return snapshot;
|
|
748
|
+
},
|
|
749
|
+
refreshAll() {
|
|
750
|
+
if (!retained) {
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
void loadTopics();
|
|
754
|
+
void loadIssueDetail();
|
|
755
|
+
void loadTaskDetail();
|
|
756
|
+
},
|
|
757
|
+
refreshDetails() {
|
|
758
|
+
if (!retained) {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
void loadIssueDetail();
|
|
762
|
+
void loadTaskDetail();
|
|
763
|
+
},
|
|
764
|
+
release() {
|
|
765
|
+
refCount = Math.max(0, refCount - 1);
|
|
766
|
+
if (refCount > 0) {
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
retained = false;
|
|
770
|
+
issueListSequence += 1;
|
|
771
|
+
issueDetailSequence += 1;
|
|
772
|
+
taskDetailSequence += 1;
|
|
773
|
+
topicListSequence += 1;
|
|
774
|
+
releaseIssueUpdates();
|
|
775
|
+
},
|
|
776
|
+
reportIssueSearchUsage(query) {
|
|
777
|
+
const searchQuery = query.trim();
|
|
778
|
+
if (!searchQuery) {
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
pendingIssueSearchAnalyticsQuery = searchQuery;
|
|
782
|
+
if (lastResolvedIssueSearchQuery === searchQuery && !snapshot.issues.isLoading) {
|
|
783
|
+
flushPendingIssueSearchAnalytics(
|
|
784
|
+
searchQuery,
|
|
785
|
+
snapshot.issues.value.length
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
retain() {
|
|
790
|
+
refCount += 1;
|
|
791
|
+
if (retained) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
retained = true;
|
|
795
|
+
if (!hasReportedOpened) {
|
|
796
|
+
hasReportedOpened = true;
|
|
797
|
+
void Promise.resolve(
|
|
798
|
+
input.feature.analytics?.track({
|
|
799
|
+
name: "issue_manager.opened",
|
|
800
|
+
params: createIssueManagerOpenedParams(
|
|
801
|
+
input.openSource ?? "restore"
|
|
802
|
+
)
|
|
803
|
+
})
|
|
804
|
+
).catch(() => void 0);
|
|
805
|
+
}
|
|
806
|
+
retainIssueUpdates();
|
|
807
|
+
void loadTopics();
|
|
808
|
+
void loadIssueDetail();
|
|
809
|
+
void loadTaskDetail();
|
|
810
|
+
},
|
|
811
|
+
setIsRunningTask(update) {
|
|
812
|
+
setSnapshot((current) => ({
|
|
813
|
+
...current,
|
|
814
|
+
isRunningTask: resolveSetStateAction(update, current.isRunningTask)
|
|
815
|
+
}));
|
|
816
|
+
},
|
|
817
|
+
setIssueDraftInternal(update) {
|
|
818
|
+
setSnapshot((current) => ({
|
|
819
|
+
...current,
|
|
820
|
+
issueDraft: resolveSetStateAction(update, current.issueDraft)
|
|
821
|
+
}));
|
|
822
|
+
},
|
|
823
|
+
setIssueEditorModeState(update) {
|
|
824
|
+
const nextMode = resolveSetStateAction(update, snapshot.issueEditorMode);
|
|
825
|
+
setSnapshot((current) => ({
|
|
826
|
+
...current,
|
|
827
|
+
issueEditorMode: nextMode
|
|
828
|
+
}));
|
|
829
|
+
syncIssueDraftFromCurrentDetail();
|
|
830
|
+
},
|
|
831
|
+
setReferenceTarget(update) {
|
|
832
|
+
setSnapshot((current) => ({
|
|
833
|
+
...current,
|
|
834
|
+
referenceTarget: resolveSetStateAction(update, current.referenceTarget)
|
|
835
|
+
}));
|
|
836
|
+
},
|
|
837
|
+
setNotification(update) {
|
|
838
|
+
setSnapshot((current) => ({
|
|
839
|
+
...current,
|
|
840
|
+
notification: resolveSetStateAction(update, current.notification)
|
|
841
|
+
}));
|
|
842
|
+
},
|
|
843
|
+
setTaskDraftInternal(update) {
|
|
844
|
+
setSnapshot((current) => ({
|
|
845
|
+
...current,
|
|
846
|
+
taskDraft: resolveSetStateAction(update, current.taskDraft)
|
|
847
|
+
}));
|
|
848
|
+
},
|
|
849
|
+
setTaskEditorModeState(update) {
|
|
850
|
+
const nextMode = resolveSetStateAction(update, snapshot.taskEditorMode);
|
|
851
|
+
setSnapshot((current) => ({
|
|
852
|
+
...current,
|
|
853
|
+
taskEditorMode: nextMode
|
|
854
|
+
}));
|
|
855
|
+
syncTaskDraftFromCurrentDetail();
|
|
856
|
+
},
|
|
857
|
+
subscribe(listener) {
|
|
858
|
+
listeners.add(listener);
|
|
859
|
+
return () => {
|
|
860
|
+
listeners.delete(listener);
|
|
861
|
+
};
|
|
862
|
+
},
|
|
863
|
+
syncInput(nextInput) {
|
|
864
|
+
onStateChange = nextInput.onStateChange;
|
|
865
|
+
if (deferredIssueSearch !== nextInput.deferredIssueSearch) {
|
|
866
|
+
deferredIssueSearch = nextInput.deferredIssueSearch;
|
|
867
|
+
if (retained) {
|
|
868
|
+
void loadIssues();
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
if (snapshot.nodeState.taskListCollapsed === true !== nextInput.taskListCollapsed) {
|
|
872
|
+
applyNodeState((current) => ({
|
|
873
|
+
...current,
|
|
874
|
+
taskListCollapsed: nextInput.taskListCollapsed
|
|
875
|
+
}));
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
updateNodeState(updater) {
|
|
879
|
+
applyNodeState(updater);
|
|
880
|
+
},
|
|
881
|
+
store
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
function createAsyncCollectionState(value, options) {
|
|
885
|
+
return {
|
|
886
|
+
error: null,
|
|
887
|
+
...options,
|
|
888
|
+
isLoading: false,
|
|
889
|
+
value
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
function resolveSetStateAction(update, current) {
|
|
893
|
+
return typeof update === "function" ? update(current) : update;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
// src/services/internal/issueManagerControllerService.ts
|
|
897
|
+
var DefaultIssueManagerControllerService = class {
|
|
898
|
+
createSession(input) {
|
|
899
|
+
return createIssueManagerControllerRuntime(input);
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
// src/services/createIssueManagerControllerService.ts
|
|
904
|
+
function createIssueManagerControllerService() {
|
|
905
|
+
return new DefaultIssueManagerControllerService();
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
export {
|
|
909
|
+
createIssueManagerDate,
|
|
910
|
+
formatIssueManagerTimestamp,
|
|
911
|
+
formatIssueManagerDate,
|
|
912
|
+
resolveIssueManagerStatusLabel,
|
|
913
|
+
resolveIssueManagerPriorityLabel,
|
|
914
|
+
uniqueIssueManagerFileReferences,
|
|
915
|
+
parentDirectoryPath,
|
|
916
|
+
defaultTaskPriority,
|
|
917
|
+
toContextRefInput,
|
|
918
|
+
toIssueManagerWorkspaceFileLinkInput,
|
|
919
|
+
confirmIssueManagerMessage,
|
|
920
|
+
resolveIssueManagerErrorMessage,
|
|
921
|
+
resolveIssueManagerTopicDeleteErrorMessage,
|
|
922
|
+
createIssueManagerIssueDraftFromNodeState,
|
|
923
|
+
createIssueManagerTaskDraftFromNodeState,
|
|
924
|
+
applyIssueManagerIssueSelection,
|
|
925
|
+
applyIssueManagerTaskSelection,
|
|
926
|
+
applyIssueManagerIssueDeleted,
|
|
927
|
+
applyIssueManagerTaskDeleted,
|
|
928
|
+
applyIssueManagerSelectedAgentProvider,
|
|
929
|
+
applyIssueManagerSelectedExecutionDirectory,
|
|
930
|
+
applyIssueManagerIssueEditorModeToNodeState,
|
|
931
|
+
applyIssueManagerTaskEditorModeToNodeState,
|
|
932
|
+
applyIssueManagerIssueSaved,
|
|
933
|
+
applyIssueManagerTaskSaved,
|
|
934
|
+
persistIssueManagerIssueDraftContent,
|
|
935
|
+
persistIssueManagerTaskDraftContent,
|
|
936
|
+
createIssueManagerControllerService
|
|
937
|
+
};
|
|
938
|
+
//# sourceMappingURL=chunk-4B2P64PY.js.map
|