@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.
Files changed (47) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +15 -0
  3. package/dist/assets/workspace-dock-task.d.ts +3 -0
  4. package/dist/assets/workspace-dock-task.png +0 -0
  5. package/dist/chunk-3XE7PXVP.js +14 -0
  6. package/dist/chunk-3XE7PXVP.js.map +1 -0
  7. package/dist/chunk-4B2P64PY.js +938 -0
  8. package/dist/chunk-4B2P64PY.js.map +1 -0
  9. package/dist/chunk-DLB2WIV6.js +5033 -0
  10. package/dist/chunk-DLB2WIV6.js.map +1 -0
  11. package/dist/chunk-JDYJIVGG.js +445 -0
  12. package/dist/chunk-JDYJIVGG.js.map +1 -0
  13. package/dist/chunk-LEL6VWU4.js +1 -0
  14. package/dist/chunk-LEL6VWU4.js.map +1 -0
  15. package/dist/chunk-T5TTRS5M.js +1 -0
  16. package/dist/chunk-T5TTRS5M.js.map +1 -0
  17. package/dist/chunk-WJSZFKUD.js +292 -0
  18. package/dist/chunk-WJSZFKUD.js.map +1 -0
  19. package/dist/contracts/index.d.ts +492 -0
  20. package/dist/contracts/index.js +1 -0
  21. package/dist/contracts/index.js.map +1 -0
  22. package/dist/core/index.d.ts +81 -0
  23. package/dist/core/index.js +66 -0
  24. package/dist/core/index.js.map +1 -0
  25. package/dist/feature-D16xMEZU.d.ts +47 -0
  26. package/dist/i18n/index.d.ts +18 -0
  27. package/dist/i18n/index.js +14 -0
  28. package/dist/i18n/index.js.map +1 -0
  29. package/dist/index.d.ts +12 -0
  30. package/dist/index.js +95 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/issueManagerControllerService.interface-D8Z1B9k4.d.ts +106 -0
  33. package/dist/latestRunStatusRenderer-B_9yU0CM.d.ts +14 -0
  34. package/dist/services/index.d.ts +13 -0
  35. package/dist/services/index.js +24 -0
  36. package/dist/services/index.js.map +1 -0
  37. package/dist/ui/index.d.ts +58 -0
  38. package/dist/ui/index.js +12 -0
  39. package/dist/ui/index.js.map +1 -0
  40. package/dist/workbench/constants.d.ts +6 -0
  41. package/dist/workbench/constants.js +9 -0
  42. package/dist/workbench/constants.js.map +1 -0
  43. package/dist/workbench/index.d.ts +76 -0
  44. package/dist/workbench/index.js +276 -0
  45. package/dist/workbench/index.js.map +1 -0
  46. package/openapi/issue-manager.v1.yaml +1682 -0
  47. package/package.json +93 -0
@@ -0,0 +1,292 @@
1
+ import {
2
+ createIssueManagerI18nRuntime
3
+ } from "./chunk-JDYJIVGG.js";
4
+
5
+ // src/core/feature.ts
6
+ var defaultIssueManagerNodeState = {
7
+ activeTopicId: null,
8
+ issueSearchQuery: "",
9
+ issueStatusFilter: "all",
10
+ selectedAgentProvider: "codex",
11
+ selectedExecutionDirectory: null,
12
+ selectedIssueId: null,
13
+ selectedTaskId: null,
14
+ taskListCollapsed: false
15
+ };
16
+ function createIssueManagerFeature(input) {
17
+ return {
18
+ agentBreakdownLauncher: input.agentBreakdownLauncher,
19
+ analytics: input.analytics,
20
+ agentProviderOptions: input.agentProviderOptions,
21
+ agentSessionOpener: input.agentSessionOpener,
22
+ agentRunner: input.agentRunner,
23
+ backend: input.backend,
24
+ eventSource: input.eventSource,
25
+ executionDirectoryPicker: input.executionDirectoryPicker,
26
+ fileAdapter: input.fileAdapter,
27
+ i18n: createIssueManagerI18nRuntime(input.i18n),
28
+ identityAdapter: input.identityAdapter,
29
+ notifications: input.notifications,
30
+ shareAdapter: input.shareAdapter,
31
+ ui: {
32
+ showInviteCollaborator: input.ui?.showInviteCollaborator ?? true
33
+ }
34
+ };
35
+ }
36
+ function normalizeIssueManagerNodeState(state) {
37
+ return {
38
+ ...defaultIssueManagerNodeState,
39
+ ...state,
40
+ activeTopicId: normalizeNullableString(state?.activeTopicId),
41
+ issueSearchQuery: state?.issueSearchQuery?.trim() ?? "",
42
+ issueStatusFilter: state?.issueStatusFilter ?? "all",
43
+ selectedAgentProvider: state?.selectedAgentProvider?.trim() || "codex",
44
+ selectedExecutionDirectory: normalizeNullableString(
45
+ state?.selectedExecutionDirectory
46
+ ),
47
+ selectedIssueId: normalizeNullableString(state?.selectedIssueId),
48
+ selectedTaskId: normalizeNullableString(state?.selectedTaskId),
49
+ taskListCollapsed: state?.taskListCollapsed === true
50
+ };
51
+ }
52
+ function normalizeNullableString(value) {
53
+ const trimmed = value?.trim() ?? "";
54
+ return trimmed.length > 0 ? trimmed : null;
55
+ }
56
+
57
+ // src/core/content.ts
58
+ import {
59
+ appendRichTextLinksToContent,
60
+ createRichTextLinkMarkdown,
61
+ createRichTextMentionHref,
62
+ createRichTextMentionMarkdown,
63
+ extractPlainTextFromContent,
64
+ extractPlainTextWithoutFilesFromContent,
65
+ extractRichTextLinksFromContent,
66
+ extractRichTextMentionsFromContent,
67
+ normalizeRichTextContent,
68
+ normalizeRichTextLinkHref,
69
+ parseRichTextMentionHref,
70
+ removeRichTextLinkFromContent,
71
+ removeRichTextMentionFromContent
72
+ } from "@tutti-os/ui-rich-text/core";
73
+ var normalizeIssueManagerContent = normalizeRichTextContent;
74
+ var normalizeIssueManagerWorkspaceFileLinkHref = normalizeRichTextLinkHref;
75
+ var createIssueManagerWorkspaceFileLinkMarkdown = createRichTextLinkMarkdown;
76
+ var appendIssueManagerWorkspaceFileLinksToContent = appendRichTextLinksToContent;
77
+ var extractIssueManagerWorkspaceFileLinksFromContent = extractRichTextLinksFromContent;
78
+ var removeIssueManagerWorkspaceFileLinkFromContent = removeRichTextLinkFromContent;
79
+ var extractIssueManagerPlainTextFromContent = extractPlainTextFromContent;
80
+ var extractIssueManagerPlainTextWithoutFilesFromContent = extractPlainTextWithoutFilesFromContent;
81
+ var createIssueManagerMentionHref = createRichTextMentionHref;
82
+ var createIssueManagerMentionMarkdown = createRichTextMentionMarkdown;
83
+ var parseIssueManagerMentionHref = parseRichTextMentionHref;
84
+ var extractIssueManagerMentionsFromContent = extractRichTextMentionsFromContent;
85
+ var removeIssueManagerMentionFromContent = removeRichTextMentionFromContent;
86
+
87
+ // src/core/layout.ts
88
+ var issueManagerSidebarDefaultWidth = 280;
89
+ var issueManagerSidebarMinWidth = 248;
90
+ var issueManagerSidebarMaxWidth = 520;
91
+ var issueManagerMainMinWidth = 420;
92
+ var issueManagerDefaultNodeFrameWidth = 860;
93
+ var issueManagerExpandedFrameMinWidth = issueManagerSidebarMinWidth + issueManagerMainMinWidth;
94
+ function clampIssueManagerSidebarWidth(width, layoutWidth) {
95
+ const maxWidth = Math.max(
96
+ issueManagerSidebarMinWidth,
97
+ Math.min(
98
+ issueManagerSidebarMaxWidth,
99
+ layoutWidth - issueManagerMainMinWidth
100
+ )
101
+ );
102
+ return Math.min(Math.max(width, issueManagerSidebarMinWidth), maxWidth);
103
+ }
104
+ function shouldAutoCollapseIssueManagerSidebar(containerWidth) {
105
+ return Number.isFinite(containerWidth) && containerWidth > 0 && Math.round(containerWidth) < issueManagerExpandedFrameMinWidth;
106
+ }
107
+ function resolveIssueManagerExpandedFrame(frame, surfaceWidth) {
108
+ const preferredWidth = Math.max(
109
+ issueManagerExpandedFrameMinWidth,
110
+ Math.min(
111
+ issueManagerDefaultNodeFrameWidth,
112
+ frame.width + issueManagerSidebarDefaultWidth
113
+ )
114
+ );
115
+ const width = Math.min(
116
+ Math.max(frame.width, preferredWidth),
117
+ Math.max(frame.width, surfaceWidth)
118
+ );
119
+ return {
120
+ ...frame,
121
+ width,
122
+ x: Math.max(0, Math.min(frame.x, surfaceWidth - width))
123
+ };
124
+ }
125
+
126
+ // src/core/workspaceIssueMention.ts
127
+ function buildWorkspaceIssueMentionHref(input) {
128
+ const workspaceId = input.workspaceId.trim();
129
+ const issueId = input.issueId.trim();
130
+ if (!workspaceId || !issueId) {
131
+ return "";
132
+ }
133
+ const params = new URLSearchParams({
134
+ workspaceId,
135
+ id: issueId
136
+ });
137
+ appendWorkspaceIssueMentionParam(
138
+ params,
139
+ "mode",
140
+ normalizeMentionMode(input.mode)
141
+ );
142
+ appendWorkspaceIssueMentionParam(params, "topicId", input.topicId);
143
+ appendWorkspaceIssueMentionParam(params, "taskId", input.taskId);
144
+ appendWorkspaceIssueMentionParam(params, "runId", input.runId);
145
+ appendWorkspaceIssueMentionParam(params, "outputDir", input.outputDir);
146
+ return `mention://workspace-issue?${params.toString()}`;
147
+ }
148
+ function parseWorkspaceIssueMentionHref(href) {
149
+ const trimmedHref = href.trim();
150
+ if (!trimmedHref.toLowerCase().startsWith("mention://workspace-issue")) {
151
+ return null;
152
+ }
153
+ let url;
154
+ try {
155
+ url = new URL(trimmedHref);
156
+ } catch {
157
+ return null;
158
+ }
159
+ if (url.protocol !== "mention:" || url.hostname !== "workspace-issue") {
160
+ return null;
161
+ }
162
+ const workspaceId = url.searchParams.get("workspaceId")?.trim() || "";
163
+ const issueId = url.searchParams.get("id")?.trim() || "";
164
+ if (!workspaceId || !issueId) {
165
+ return null;
166
+ }
167
+ const mode = normalizeMentionMode(url.searchParams.get("mode"));
168
+ const topicId = optionalSearchParam(url.searchParams, "topicId");
169
+ const taskId = optionalSearchParam(url.searchParams, "taskId");
170
+ const runId = optionalSearchParam(url.searchParams, "runId");
171
+ const outputDir = optionalSearchParam(url.searchParams, "outputDir");
172
+ return {
173
+ issueId,
174
+ ...mode ? { mode } : {},
175
+ ...outputDir ? { outputDir } : {},
176
+ ...runId ? { runId } : {},
177
+ ...taskId ? { taskId } : {},
178
+ ...topicId ? { topicId } : {},
179
+ workspaceId
180
+ };
181
+ }
182
+ function appendWorkspaceIssueMentionParam(params, key, value) {
183
+ const normalized = value?.trim() || "";
184
+ if (normalized) {
185
+ params.set(key, normalized);
186
+ }
187
+ }
188
+ function optionalSearchParam(params, key) {
189
+ const value = params.get(key)?.trim() || "";
190
+ return value || void 0;
191
+ }
192
+ function normalizeMentionMode(value) {
193
+ return value === "breakdown" || value === "execute" ? value : void 0;
194
+ }
195
+
196
+ // src/core/runPrompt.ts
197
+ function resolveIssueManagerWorkspaceRuntimePath(workspaceRoot, requestedPath) {
198
+ const normalizedWorkspaceRoot = workspaceRoot.trim().replace(/\/+$/, "");
199
+ const normalizedRequestedPath = requestedPath.trim();
200
+ if (!normalizedWorkspaceRoot || !normalizedRequestedPath) {
201
+ return normalizedRequestedPath;
202
+ }
203
+ if (normalizedRequestedPath === normalizedWorkspaceRoot || normalizedRequestedPath.startsWith(`${normalizedWorkspaceRoot}/`)) {
204
+ return normalizedRequestedPath;
205
+ }
206
+ if (normalizedRequestedPath === "/workspace") {
207
+ return normalizedWorkspaceRoot;
208
+ }
209
+ if (normalizedRequestedPath.startsWith("/workspace/")) {
210
+ return `${normalizedWorkspaceRoot}/${normalizedRequestedPath.slice("/workspace/".length)}`;
211
+ }
212
+ if (!normalizedRequestedPath.startsWith("/")) {
213
+ return `${normalizedWorkspaceRoot}/${normalizedRequestedPath.replace(/^\/+/, "")}`;
214
+ }
215
+ return normalizedRequestedPath;
216
+ }
217
+ function buildIssueManagerRunPrompt(input) {
218
+ const mentionMarkdown = buildIssueManagerIssueMention({
219
+ issue: input.issue,
220
+ task: input.task,
221
+ mode: "execute"
222
+ });
223
+ return [
224
+ input.copy?.t("runPrompts.executeIntro") ?? "Handle this issue reference.",
225
+ "",
226
+ mentionMarkdown
227
+ ].join("\n");
228
+ }
229
+ function buildIssueManagerTaskBreakdownPrompt(input) {
230
+ const issue = input.issueDetail.issue;
231
+ const issueMention = buildIssueManagerIssueMention({
232
+ issue,
233
+ mode: "breakdown"
234
+ });
235
+ return [
236
+ input.copy?.t("runPrompts.breakdownIntro") ?? "Break this issue reference down into executable tasks.",
237
+ "",
238
+ issueMention
239
+ ].join("\n");
240
+ }
241
+ function buildIssueManagerIssueMention(input) {
242
+ const labelParts = [input.issue.title.trim(), input.task?.title.trim() || ""].filter(Boolean).map(
243
+ (value) => escapeIssueManagerMentionLabel(value.replace(/^@+/, "").trim())
244
+ );
245
+ const href = buildWorkspaceIssueMentionHref({
246
+ issueId: input.issue.issueId,
247
+ mode: input.mode,
248
+ outputDir: input.outputDir,
249
+ runId: input.runId,
250
+ taskId: input.task?.taskId,
251
+ topicId: input.issue.topicId,
252
+ workspaceId: input.issue.workspaceId
253
+ });
254
+ return `[@${labelParts.join(" / ")}](${href})`;
255
+ }
256
+ function escapeIssueManagerMentionLabel(value) {
257
+ return value.replaceAll("\\", "\\\\").replaceAll("[", "\\[").replaceAll("]", "\\]").replaceAll("\r", " ").replaceAll("\n", " ");
258
+ }
259
+
260
+ export {
261
+ defaultIssueManagerNodeState,
262
+ createIssueManagerFeature,
263
+ normalizeIssueManagerNodeState,
264
+ normalizeIssueManagerContent,
265
+ normalizeIssueManagerWorkspaceFileLinkHref,
266
+ createIssueManagerWorkspaceFileLinkMarkdown,
267
+ appendIssueManagerWorkspaceFileLinksToContent,
268
+ extractIssueManagerWorkspaceFileLinksFromContent,
269
+ removeIssueManagerWorkspaceFileLinkFromContent,
270
+ extractIssueManagerPlainTextFromContent,
271
+ extractIssueManagerPlainTextWithoutFilesFromContent,
272
+ createIssueManagerMentionHref,
273
+ createIssueManagerMentionMarkdown,
274
+ parseIssueManagerMentionHref,
275
+ extractIssueManagerMentionsFromContent,
276
+ removeIssueManagerMentionFromContent,
277
+ issueManagerSidebarDefaultWidth,
278
+ issueManagerSidebarMinWidth,
279
+ issueManagerSidebarMaxWidth,
280
+ issueManagerMainMinWidth,
281
+ issueManagerDefaultNodeFrameWidth,
282
+ issueManagerExpandedFrameMinWidth,
283
+ clampIssueManagerSidebarWidth,
284
+ shouldAutoCollapseIssueManagerSidebar,
285
+ resolveIssueManagerExpandedFrame,
286
+ buildWorkspaceIssueMentionHref,
287
+ parseWorkspaceIssueMentionHref,
288
+ resolveIssueManagerWorkspaceRuntimePath,
289
+ buildIssueManagerRunPrompt,
290
+ buildIssueManagerTaskBreakdownPrompt
291
+ };
292
+ //# sourceMappingURL=chunk-WJSZFKUD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/feature.ts","../src/core/content.ts","../src/core/layout.ts","../src/core/workspaceIssueMention.ts","../src/core/runPrompt.ts"],"sourcesContent":["import type { I18nRuntime } from \"@tutti-os/ui-i18n-runtime\";\nimport {\n createIssueManagerI18nRuntime,\n type IssueManagerI18nRuntime\n} from \"../i18n/issueManagerI18n.ts\";\nimport type {\n IssueManagerAgentBreakdownLauncher,\n IssueManagerAgentProviderOptionsAdapter,\n IssueManagerAnalyticsAdapter,\n IssueManagerExecutionDirectoryPicker,\n IssueManagerAgentSessionOpener,\n IssueManagerAgentRunner,\n IssueManagerBackend,\n IssueManagerEventSource,\n IssueManagerFileAdapter,\n IssueManagerIdentityAdapter,\n IssueManagerNodeState,\n IssueManagerShareAdapter\n} from \"../contracts/index.ts\";\n\nexport interface IssueManagerNotificationSink {\n tips(title: string): void;\n}\n\nexport interface IssueManagerFeatureUIConfig {\n showInviteCollaborator: boolean;\n}\n\nexport interface IssueManagerFeature {\n agentBreakdownLauncher?: IssueManagerAgentBreakdownLauncher;\n analytics?: IssueManagerAnalyticsAdapter;\n agentProviderOptions?: IssueManagerAgentProviderOptionsAdapter;\n agentSessionOpener?: IssueManagerAgentSessionOpener;\n agentRunner: IssueManagerAgentRunner;\n backend: IssueManagerBackend;\n eventSource?: IssueManagerEventSource;\n executionDirectoryPicker?: IssueManagerExecutionDirectoryPicker;\n fileAdapter?: IssueManagerFileAdapter;\n i18n: IssueManagerI18nRuntime;\n identityAdapter: IssueManagerIdentityAdapter;\n notifications?: IssueManagerNotificationSink;\n shareAdapter?: IssueManagerShareAdapter;\n ui: IssueManagerFeatureUIConfig;\n}\n\nexport interface CreateIssueManagerFeatureInput {\n agentBreakdownLauncher?: IssueManagerAgentBreakdownLauncher;\n analytics?: IssueManagerAnalyticsAdapter;\n agentProviderOptions?: IssueManagerAgentProviderOptionsAdapter;\n agentSessionOpener?: IssueManagerAgentSessionOpener;\n agentRunner: IssueManagerAgentRunner;\n backend: IssueManagerBackend;\n eventSource?: IssueManagerEventSource;\n executionDirectoryPicker?: IssueManagerExecutionDirectoryPicker;\n fileAdapter?: IssueManagerFileAdapter;\n i18n?: I18nRuntime<string>;\n identityAdapter: IssueManagerIdentityAdapter;\n notifications?: IssueManagerNotificationSink;\n shareAdapter?: IssueManagerShareAdapter;\n ui?: Partial<IssueManagerFeatureUIConfig>;\n}\n\nexport const defaultIssueManagerNodeState: IssueManagerNodeState = {\n activeTopicId: null,\n issueSearchQuery: \"\",\n issueStatusFilter: \"all\",\n selectedAgentProvider: \"codex\",\n selectedExecutionDirectory: null,\n selectedIssueId: null,\n selectedTaskId: null,\n taskListCollapsed: false\n};\n\nexport function createIssueManagerFeature(\n input: CreateIssueManagerFeatureInput\n): IssueManagerFeature {\n return {\n agentBreakdownLauncher: input.agentBreakdownLauncher,\n analytics: input.analytics,\n agentProviderOptions: input.agentProviderOptions,\n agentSessionOpener: input.agentSessionOpener,\n agentRunner: input.agentRunner,\n backend: input.backend,\n eventSource: input.eventSource,\n executionDirectoryPicker: input.executionDirectoryPicker,\n fileAdapter: input.fileAdapter,\n i18n: createIssueManagerI18nRuntime(input.i18n),\n identityAdapter: input.identityAdapter,\n notifications: input.notifications,\n shareAdapter: input.shareAdapter,\n ui: {\n showInviteCollaborator: input.ui?.showInviteCollaborator ?? true\n }\n };\n}\n\nexport function normalizeIssueManagerNodeState(\n state: Partial<IssueManagerNodeState> | null | undefined\n): IssueManagerNodeState {\n return {\n ...defaultIssueManagerNodeState,\n ...state,\n activeTopicId: normalizeNullableString(state?.activeTopicId),\n issueSearchQuery: state?.issueSearchQuery?.trim() ?? \"\",\n issueStatusFilter: state?.issueStatusFilter ?? \"all\",\n selectedAgentProvider: state?.selectedAgentProvider?.trim() || \"codex\",\n selectedExecutionDirectory: normalizeNullableString(\n state?.selectedExecutionDirectory\n ),\n selectedIssueId: normalizeNullableString(state?.selectedIssueId),\n selectedTaskId: normalizeNullableString(state?.selectedTaskId),\n taskListCollapsed: state?.taskListCollapsed === true\n };\n}\n\nfunction normalizeNullableString(\n value: string | null | undefined\n): string | null {\n const trimmed = value?.trim() ?? \"\";\n return trimmed.length > 0 ? trimmed : null;\n}\n","import {\n appendRichTextLinksToContent,\n createRichTextLinkMarkdown,\n createRichTextMentionHref,\n createRichTextMentionMarkdown,\n extractPlainTextFromContent,\n extractPlainTextWithoutFilesFromContent,\n extractRichTextLinksFromContent,\n extractRichTextMentionsFromContent,\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextMentionHref,\n removeRichTextLinkFromContent,\n removeRichTextMentionFromContent\n} from \"@tutti-os/ui-rich-text/core\";\nimport type {\n RichTextLinkInput,\n RichTextLinkRef\n} from \"@tutti-os/ui-rich-text/core\";\nimport type { RichTextMentionAttrs } from \"@tutti-os/ui-rich-text/types\";\n\nexport type IssueManagerWorkspaceFileLinkRef = RichTextLinkRef;\nexport type IssueManagerWorkspaceFileLinkInput = RichTextLinkInput;\n\nexport type IssueManagerMentionRef = RichTextMentionAttrs;\nexport type IssueManagerMentionAttrs = RichTextMentionAttrs;\n\nexport const normalizeIssueManagerContent = normalizeRichTextContent;\n\nexport const normalizeIssueManagerWorkspaceFileLinkHref =\n normalizeRichTextLinkHref;\n\nexport const createIssueManagerWorkspaceFileLinkMarkdown =\n createRichTextLinkMarkdown;\n\nexport const appendIssueManagerWorkspaceFileLinksToContent =\n appendRichTextLinksToContent;\n\nexport const extractIssueManagerWorkspaceFileLinksFromContent =\n extractRichTextLinksFromContent;\n\nexport const removeIssueManagerWorkspaceFileLinkFromContent =\n removeRichTextLinkFromContent;\n\nexport const extractIssueManagerPlainTextFromContent =\n extractPlainTextFromContent;\n\nexport const extractIssueManagerPlainTextWithoutFilesFromContent =\n extractPlainTextWithoutFilesFromContent;\n\nexport const createIssueManagerMentionHref = createRichTextMentionHref;\nexport const createIssueManagerMentionMarkdown = createRichTextMentionMarkdown;\nexport const parseIssueManagerMentionHref = parseRichTextMentionHref;\nexport const extractIssueManagerMentionsFromContent =\n extractRichTextMentionsFromContent;\nexport const removeIssueManagerMentionFromContent =\n removeRichTextMentionFromContent;\n","export const issueManagerSidebarDefaultWidth = 280;\nexport const issueManagerSidebarMinWidth = 248;\nexport const issueManagerSidebarMaxWidth = 520;\nexport const issueManagerMainMinWidth = 420;\nexport const issueManagerDefaultNodeFrameWidth = 860;\nexport const issueManagerExpandedFrameMinWidth =\n issueManagerSidebarMinWidth + issueManagerMainMinWidth;\n\nexport function clampIssueManagerSidebarWidth(\n width: number,\n layoutWidth: number\n): number {\n const maxWidth = Math.max(\n issueManagerSidebarMinWidth,\n Math.min(\n issueManagerSidebarMaxWidth,\n layoutWidth - issueManagerMainMinWidth\n )\n );\n return Math.min(Math.max(width, issueManagerSidebarMinWidth), maxWidth);\n}\n\nexport function shouldAutoCollapseIssueManagerSidebar(\n containerWidth: number\n): boolean {\n return (\n Number.isFinite(containerWidth) &&\n containerWidth > 0 &&\n Math.round(containerWidth) < issueManagerExpandedFrameMinWidth\n );\n}\n\nexport function resolveIssueManagerExpandedFrame<\n TFrame extends { width: number; x: number }\n>(frame: TFrame, surfaceWidth: number): TFrame {\n const preferredWidth = Math.max(\n issueManagerExpandedFrameMinWidth,\n Math.min(\n issueManagerDefaultNodeFrameWidth,\n frame.width + issueManagerSidebarDefaultWidth\n )\n );\n const width = Math.min(\n Math.max(frame.width, preferredWidth),\n Math.max(frame.width, surfaceWidth)\n );\n\n return {\n ...frame,\n width,\n x: Math.max(0, Math.min(frame.x, surfaceWidth - width))\n };\n}\n","export type WorkspaceIssueMentionMode = \"breakdown\" | \"execute\";\n\nexport interface BuildWorkspaceIssueMentionHrefInput {\n issueId: string;\n mode?: WorkspaceIssueMentionMode;\n outputDir?: string | null;\n runId?: string | null;\n taskId?: string | null;\n topicId?: string | null;\n workspaceId: string;\n}\n\nexport interface ParsedWorkspaceIssueMention {\n issueId: string;\n mode?: WorkspaceIssueMentionMode;\n outputDir?: string;\n runId?: string;\n taskId?: string;\n topicId?: string;\n workspaceId: string;\n}\n\nexport function buildWorkspaceIssueMentionHref(\n input: BuildWorkspaceIssueMentionHrefInput\n): string {\n const workspaceId = input.workspaceId.trim();\n const issueId = input.issueId.trim();\n if (!workspaceId || !issueId) {\n return \"\";\n }\n\n const params = new URLSearchParams({\n workspaceId,\n id: issueId\n });\n appendWorkspaceIssueMentionParam(\n params,\n \"mode\",\n normalizeMentionMode(input.mode)\n );\n appendWorkspaceIssueMentionParam(params, \"topicId\", input.topicId);\n appendWorkspaceIssueMentionParam(params, \"taskId\", input.taskId);\n appendWorkspaceIssueMentionParam(params, \"runId\", input.runId);\n appendWorkspaceIssueMentionParam(params, \"outputDir\", input.outputDir);\n return `mention://workspace-issue?${params.toString()}`;\n}\n\nexport function parseWorkspaceIssueMentionHref(\n href: string\n): ParsedWorkspaceIssueMention | null {\n const trimmedHref = href.trim();\n if (!trimmedHref.toLowerCase().startsWith(\"mention://workspace-issue\")) {\n return null;\n }\n\n let url: URL;\n try {\n url = new URL(trimmedHref);\n } catch {\n return null;\n }\n if (url.protocol !== \"mention:\" || url.hostname !== \"workspace-issue\") {\n return null;\n }\n\n const workspaceId = url.searchParams.get(\"workspaceId\")?.trim() || \"\";\n const issueId = url.searchParams.get(\"id\")?.trim() || \"\";\n if (!workspaceId || !issueId) {\n return null;\n }\n\n const mode = normalizeMentionMode(url.searchParams.get(\"mode\"));\n const topicId = optionalSearchParam(url.searchParams, \"topicId\");\n const taskId = optionalSearchParam(url.searchParams, \"taskId\");\n const runId = optionalSearchParam(url.searchParams, \"runId\");\n const outputDir = optionalSearchParam(url.searchParams, \"outputDir\");\n\n return {\n issueId,\n ...(mode ? { mode } : {}),\n ...(outputDir ? { outputDir } : {}),\n ...(runId ? { runId } : {}),\n ...(taskId ? { taskId } : {}),\n ...(topicId ? { topicId } : {}),\n workspaceId\n };\n}\n\nfunction appendWorkspaceIssueMentionParam(\n params: URLSearchParams,\n key: string,\n value: string | null | undefined\n): void {\n const normalized = value?.trim() || \"\";\n if (normalized) {\n params.set(key, normalized);\n }\n}\n\nfunction optionalSearchParam(\n params: URLSearchParams,\n key: string\n): string | undefined {\n const value = params.get(key)?.trim() || \"\";\n return value || undefined;\n}\n\nfunction normalizeMentionMode(\n value: string | null | undefined\n): WorkspaceIssueMentionMode | undefined {\n return value === \"breakdown\" || value === \"execute\" ? value : undefined;\n}\n","import type {\n IssueManagerContextRef,\n IssueManagerIssueSummary,\n IssueManagerTaskSummary\n} from \"../contracts/index.ts\";\nimport type { IssueManagerI18nRuntime } from \"../i18n/issueManagerI18n.ts\";\nimport { buildWorkspaceIssueMentionHref } from \"./workspaceIssueMention.ts\";\n\ntype IssueManagerPromptCopy = Pick<IssueManagerI18nRuntime, \"t\">;\n\nexport function resolveIssueManagerWorkspaceRuntimePath(\n workspaceRoot: string,\n requestedPath: string\n): string {\n const normalizedWorkspaceRoot = workspaceRoot.trim().replace(/\\/+$/, \"\");\n const normalizedRequestedPath = requestedPath.trim();\n\n if (!normalizedWorkspaceRoot || !normalizedRequestedPath) {\n return normalizedRequestedPath;\n }\n\n if (\n normalizedRequestedPath === normalizedWorkspaceRoot ||\n normalizedRequestedPath.startsWith(`${normalizedWorkspaceRoot}/`)\n ) {\n return normalizedRequestedPath;\n }\n\n if (normalizedRequestedPath === \"/workspace\") {\n return normalizedWorkspaceRoot;\n }\n\n if (normalizedRequestedPath.startsWith(\"/workspace/\")) {\n return `${normalizedWorkspaceRoot}/${normalizedRequestedPath.slice(\"/workspace/\".length)}`;\n }\n\n if (!normalizedRequestedPath.startsWith(\"/\")) {\n return `${normalizedWorkspaceRoot}/${normalizedRequestedPath.replace(/^\\/+/, \"\")}`;\n }\n\n return normalizedRequestedPath;\n}\n\nexport function buildIssueManagerRunPrompt(input: {\n copy?: IssueManagerPromptCopy;\n issue: IssueManagerIssueSummary;\n task?: IssueManagerTaskSummary;\n workspaceRoot: string;\n}): string {\n const mentionMarkdown = buildIssueManagerIssueMention({\n issue: input.issue,\n task: input.task,\n mode: \"execute\"\n });\n return [\n input.copy?.t(\"runPrompts.executeIntro\") ?? \"Handle this issue reference.\",\n \"\",\n mentionMarkdown\n ].join(\"\\n\");\n}\n\nexport function buildIssueManagerTaskBreakdownPrompt(input: {\n copy?: IssueManagerPromptCopy;\n issueDetail: {\n contextRefs: readonly IssueManagerContextRef[];\n issue: IssueManagerIssueSummary;\n tasks: readonly IssueManagerTaskSummary[];\n };\n workspaceId: string;\n}): string {\n const issue = input.issueDetail.issue;\n const issueMention = buildIssueManagerIssueMention({\n issue,\n mode: \"breakdown\"\n });\n\n return [\n input.copy?.t(\"runPrompts.breakdownIntro\") ??\n \"Break this issue reference down into executable tasks.\",\n \"\",\n issueMention\n ].join(\"\\n\");\n}\n\nfunction buildIssueManagerIssueMention(input: {\n issue: IssueManagerIssueSummary;\n task?: IssueManagerTaskSummary;\n mode: \"breakdown\" | \"execute\";\n outputDir?: string | null;\n runId?: string | null;\n}): string {\n const labelParts = [input.issue.title.trim(), input.task?.title.trim() || \"\"]\n .filter(Boolean)\n .map((value) =>\n escapeIssueManagerMentionLabel(value.replace(/^@+/, \"\").trim())\n );\n const href = buildWorkspaceIssueMentionHref({\n issueId: input.issue.issueId,\n mode: input.mode,\n outputDir: input.outputDir,\n runId: input.runId,\n taskId: input.task?.taskId,\n topicId: input.issue.topicId,\n workspaceId: input.issue.workspaceId\n });\n return `[@${labelParts.join(\" / \")}](${href})`;\n}\n\nfunction escapeIssueManagerMentionLabel(value: string): string {\n return value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"[\", \"\\\\[\")\n .replaceAll(\"]\", \"\\\\]\")\n .replaceAll(\"\\r\", \" \")\n .replaceAll(\"\\n\", \" \");\n}\n"],"mappings":"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","names":[]}