@muzzamil-khan/redmine-agent-mcp 1.0.0 → 1.1.0

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 (111) hide show
  1. package/dist/config/env.d.ts +2 -0
  2. package/dist/config/env.d.ts.map +1 -1
  3. package/dist/config/env.js +8 -0
  4. package/dist/config/env.js.map +1 -1
  5. package/dist/mcp/server.js +630 -147
  6. package/dist/mcp/server.js.map +1 -1
  7. package/dist/services/assigneeDirectory.d.ts +34 -0
  8. package/dist/services/assigneeDirectory.d.ts.map +1 -0
  9. package/dist/services/assigneeDirectory.js +138 -0
  10. package/dist/services/assigneeDirectory.js.map +1 -0
  11. package/dist/services/googleSheets.d.ts +32 -0
  12. package/dist/services/googleSheets.d.ts.map +1 -0
  13. package/dist/services/googleSheets.js +109 -0
  14. package/dist/services/googleSheets.js.map +1 -0
  15. package/dist/services/redmine.d.ts +52 -0
  16. package/dist/services/redmine.d.ts.map +1 -1
  17. package/dist/services/redmine.js +103 -0
  18. package/dist/services/redmine.js.map +1 -1
  19. package/dist/services/redmineConfig.d.ts +85 -0
  20. package/dist/services/redmineConfig.d.ts.map +1 -0
  21. package/dist/services/redmineConfig.js +271 -0
  22. package/dist/services/redmineConfig.js.map +1 -0
  23. package/dist/spreadsheet/batchColumnMapping.d.ts +93 -0
  24. package/dist/spreadsheet/batchColumnMapping.d.ts.map +1 -0
  25. package/dist/spreadsheet/batchColumnMapping.js +660 -0
  26. package/dist/spreadsheet/batchColumnMapping.js.map +1 -0
  27. package/dist/spreadsheet/batchCreationTypes.d.ts +58 -0
  28. package/dist/spreadsheet/batchCreationTypes.d.ts.map +1 -0
  29. package/dist/spreadsheet/batchCreationTypes.js +18 -0
  30. package/dist/spreadsheet/batchCreationTypes.js.map +1 -0
  31. package/dist/spreadsheet/batchIssueConfig.d.ts +21 -0
  32. package/dist/spreadsheet/batchIssueConfig.d.ts.map +1 -0
  33. package/dist/spreadsheet/batchIssueConfig.js +73 -0
  34. package/dist/spreadsheet/batchIssueConfig.js.map +1 -0
  35. package/dist/spreadsheet/batchPreviewFormat.d.ts +39 -0
  36. package/dist/spreadsheet/batchPreviewFormat.d.ts.map +1 -0
  37. package/dist/spreadsheet/batchPreviewFormat.js +190 -0
  38. package/dist/spreadsheet/batchPreviewFormat.js.map +1 -0
  39. package/dist/spreadsheet/batchSheetHeuristics.d.ts +13 -0
  40. package/dist/spreadsheet/batchSheetHeuristics.d.ts.map +1 -0
  41. package/dist/spreadsheet/batchSheetHeuristics.js +30 -0
  42. package/dist/spreadsheet/batchSheetHeuristics.js.map +1 -0
  43. package/dist/spreadsheet/csvUtils.d.ts +14 -0
  44. package/dist/spreadsheet/csvUtils.d.ts.map +1 -0
  45. package/dist/spreadsheet/csvUtils.js +113 -0
  46. package/dist/spreadsheet/csvUtils.js.map +1 -0
  47. package/dist/spreadsheet/extractRawBatchSheet.d.ts +14 -0
  48. package/dist/spreadsheet/extractRawBatchSheet.d.ts.map +1 -0
  49. package/dist/spreadsheet/extractRawBatchSheet.js +33 -0
  50. package/dist/spreadsheet/extractRawBatchSheet.js.map +1 -0
  51. package/dist/spreadsheet/featureRow.d.ts +15 -0
  52. package/dist/spreadsheet/featureRow.d.ts.map +1 -0
  53. package/dist/spreadsheet/featureRow.js +119 -0
  54. package/dist/spreadsheet/featureRow.js.map +1 -0
  55. package/dist/spreadsheet/parseBatchCreationCsv.d.ts +8 -0
  56. package/dist/spreadsheet/parseBatchCreationCsv.d.ts.map +1 -0
  57. package/dist/spreadsheet/parseBatchCreationCsv.js +22 -0
  58. package/dist/spreadsheet/parseBatchCreationCsv.js.map +1 -0
  59. package/dist/spreadsheet/parseBatchCreationCsvV1.d.ts +3 -0
  60. package/dist/spreadsheet/parseBatchCreationCsvV1.d.ts.map +1 -0
  61. package/dist/spreadsheet/parseBatchCreationCsvV1.js +226 -0
  62. package/dist/spreadsheet/parseBatchCreationCsvV1.js.map +1 -0
  63. package/dist/spreadsheet/parseBatchCreationCsvV2.d.ts +4 -0
  64. package/dist/spreadsheet/parseBatchCreationCsvV2.d.ts.map +1 -0
  65. package/dist/spreadsheet/parseBatchCreationCsvV2.js +180 -0
  66. package/dist/spreadsheet/parseBatchCreationCsvV2.js.map +1 -0
  67. package/dist/spreadsheet/redmineIssueCell.d.ts +38 -0
  68. package/dist/spreadsheet/redmineIssueCell.d.ts.map +1 -0
  69. package/dist/spreadsheet/redmineIssueCell.js +176 -0
  70. package/dist/spreadsheet/redmineIssueCell.js.map +1 -0
  71. package/dist/spreadsheet/sheetColumnMap.d.ts +38 -0
  72. package/dist/spreadsheet/sheetColumnMap.d.ts.map +1 -0
  73. package/dist/spreadsheet/sheetColumnMap.js +75 -0
  74. package/dist/spreadsheet/sheetColumnMap.js.map +1 -0
  75. package/dist/spreadsheet/sheetGridToCsv.d.ts +28 -0
  76. package/dist/spreadsheet/sheetGridToCsv.d.ts.map +1 -0
  77. package/dist/spreadsheet/sheetGridToCsv.js +88 -0
  78. package/dist/spreadsheet/sheetGridToCsv.js.map +1 -0
  79. package/dist/spreadsheet/sheetRedmineFields.d.ts +7 -0
  80. package/dist/spreadsheet/sheetRedmineFields.d.ts.map +1 -0
  81. package/dist/spreadsheet/sheetRedmineFields.js +22 -0
  82. package/dist/spreadsheet/sheetRedmineFields.js.map +1 -0
  83. package/dist/spreadsheet/sheetWriteBack.d.ts +27 -0
  84. package/dist/spreadsheet/sheetWriteBack.d.ts.map +1 -0
  85. package/dist/spreadsheet/sheetWriteBack.js +90 -0
  86. package/dist/spreadsheet/sheetWriteBack.js.map +1 -0
  87. package/dist/workflows/batchCreateIssuesWorkflow.d.ts +66 -0
  88. package/dist/workflows/batchCreateIssuesWorkflow.d.ts.map +1 -0
  89. package/dist/workflows/batchCreateIssuesWorkflow.js +1014 -0
  90. package/dist/workflows/batchCreateIssuesWorkflow.js.map +1 -0
  91. package/dist/workflows/createIssueWorkflow.d.ts +41 -0
  92. package/dist/workflows/createIssueWorkflow.d.ts.map +1 -0
  93. package/dist/workflows/createIssueWorkflow.js +697 -0
  94. package/dist/workflows/createIssueWorkflow.js.map +1 -0
  95. package/dist/workflows/getAllUsersWorkflow.d.ts +27 -0
  96. package/dist/workflows/getAllUsersWorkflow.d.ts.map +1 -0
  97. package/dist/workflows/getAllUsersWorkflow.js +48 -0
  98. package/dist/workflows/getAllUsersWorkflow.js.map +1 -0
  99. package/dist/workflows/issueCreationHelpers.d.ts +54 -0
  100. package/dist/workflows/issueCreationHelpers.d.ts.map +1 -0
  101. package/dist/workflows/issueCreationHelpers.js +272 -0
  102. package/dist/workflows/issueCreationHelpers.js.map +1 -0
  103. package/dist/workflows/logTimeWorkflow.d.ts +6 -1
  104. package/dist/workflows/logTimeWorkflow.d.ts.map +1 -1
  105. package/dist/workflows/logTimeWorkflow.js +139 -20
  106. package/dist/workflows/logTimeWorkflow.js.map +1 -1
  107. package/dist/workflows/sheetToCsvWorkflow.d.ts +15 -0
  108. package/dist/workflows/sheetToCsvWorkflow.d.ts.map +1 -0
  109. package/dist/workflows/sheetToCsvWorkflow.js +65 -0
  110. package/dist/workflows/sheetToCsvWorkflow.js.map +1 -0
  111. package/package.json +2 -2
@@ -0,0 +1,85 @@
1
+ export type RedmineEnumeration = {
2
+ id: number;
3
+ name: string;
4
+ is_default?: boolean;
5
+ };
6
+ export type RedmineConfig = {
7
+ fetchedAt: number;
8
+ activities: RedmineEnumeration[];
9
+ trackers: RedmineEnumeration[];
10
+ priorities: RedmineEnumeration[];
11
+ statuses: RedmineEnumeration[];
12
+ defaultActivityId: number;
13
+ defaultActivityName: string | null;
14
+ trackerAliases: Record<string, string>;
15
+ priorityAliases: Record<string, string>;
16
+ };
17
+ /** Lowercase alias → canonical Redmine tracker name. */
18
+ export declare const TRACKER_ALIASES: Record<string, string>;
19
+ export declare const PRIORITY_ALIASES: Record<string, string>;
20
+ export declare function applyTrackerAlias(input: string): string;
21
+ export declare function applyPriorityAlias(input: string): string;
22
+ /** Parse "123 — Name" or plain name/id from intake selection. */
23
+ export declare function parseEnumerationSelection(value: string): string;
24
+ export declare function resolveTracker(input: string, config: RedmineConfig): RedmineEnumeration | undefined;
25
+ /** Acronym from config tracker name, e.g. "Change Request" → "CR". */
26
+ export declare function trackerNameAcronym(name: string): string;
27
+ /** Trackers that receive the Steps to Reproduce custom field on batch create. */
28
+ export declare const STEPS_TO_REPRODUCE_TRACKER_NAMES: readonly ["Bug", "Task"];
29
+ export declare function trackerNeedsStepsToReproduce(tracker: {
30
+ id: number;
31
+ name: string;
32
+ }): boolean;
33
+ /**
34
+ * Resolve a sheet label or "id — name" to a live config tracker.
35
+ * Matches: numeric id, exact name (case-insensitive), acronym, then tracker aliases.
36
+ */
37
+ export declare function resolveTrackerFromConfig(input: string, config: RedmineConfig): RedmineEnumeration | undefined;
38
+ /**
39
+ * Resolve priority from config without alias tables (exact name or id only).
40
+ */
41
+ export declare function resolvePriorityFromConfig(input: string, config: RedmineConfig): RedmineEnumeration | undefined;
42
+ export declare function resolveStatus(input: string, config: RedmineConfig): RedmineEnumeration | undefined;
43
+ export declare function resolvePriority(input: string, config: RedmineConfig): RedmineEnumeration | undefined;
44
+ export declare function resolveActivityFromPairAnswer(answer: string, config: RedmineConfig): number | undefined;
45
+ export declare function resolveActivity(input: string | number | undefined, config: RedmineConfig): RedmineEnumeration | undefined;
46
+ export declare function enumerationOptions(rows: RedmineEnumeration[]): string[];
47
+ export declare function formatEnumerationLine(label: string, rows: RedmineEnumeration[]): string;
48
+ export declare function formatConfigForInstructions(config: RedmineConfig): string;
49
+ export declare function loadRedmineConfig(options?: {
50
+ force?: boolean;
51
+ }): Promise<RedmineConfig>;
52
+ /** Resolved default activity for time logging (validates REDMINE_ACTIVITY_ID against API). */
53
+ export declare function getResolvedDefaultActivity(): Promise<{
54
+ activityId: number;
55
+ activityName: string | null;
56
+ }>;
57
+ export declare function defaultActivityOption(config: RedmineConfig): string;
58
+ /** How activities/trackers/etc. were loaded for this MCP session. */
59
+ export declare function configCacheMeta(config: RedmineConfig): {
60
+ source: "cache";
61
+ fetchedAt: number;
62
+ cacheAgeMs: number;
63
+ cacheTtlMs: number;
64
+ refreshed: boolean;
65
+ };
66
+ export declare function configOptionsPayload(config: RedmineConfig): {
67
+ activities: RedmineEnumeration[];
68
+ trackers: RedmineEnumeration[];
69
+ priorities: RedmineEnumeration[];
70
+ statuses: RedmineEnumeration[];
71
+ trackerOptions: string[];
72
+ statusOptions: string[];
73
+ priorityOptions: string[];
74
+ activityOptions: string[];
75
+ defaultActivityId: number;
76
+ defaultActivityName: string | null;
77
+ trackerAliases: Record<string, string>;
78
+ priorityAliases: Record<string, string>;
79
+ source: "cache";
80
+ fetchedAt: number;
81
+ cacheAgeMs: number;
82
+ cacheTtlMs: number;
83
+ refreshed: boolean;
84
+ };
85
+ //# sourceMappingURL=redmineConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redmineConfig.d.ts","sourceRoot":"","sources":["../../src/services/redmineConfig.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,271 @@
1
+ import { getTimeEntryDefaults } from "../config/env.js";
2
+ import { getIssuePriorities, getIssueStatuses, getTimeEntryActivities, getTrackers, } from "./redmine.js";
3
+ const CACHE_MS = 5 * 60_000;
4
+ /** Lowercase alias → canonical Redmine tracker name. */
5
+ export const TRACKER_ALIASES = {
6
+ cr: "Change Request",
7
+ bug: "Bug",
8
+ task: "Task",
9
+ ticket: "Ticket",
10
+ "user story": "User Story",
11
+ story: "User Story",
12
+ feature: "Feature",
13
+ };
14
+ export const PRIORITY_ALIASES = {
15
+ medium: "Normal",
16
+ highest: "Immediate",
17
+ lowest: "Low",
18
+ };
19
+ let cached = null;
20
+ function parseEnumerations(rows) {
21
+ return (rows ?? [])
22
+ .filter((r) => Boolean(r.id && r.name))
23
+ .map((r) => ({
24
+ id: r.id,
25
+ name: r.name.trim(),
26
+ ...(r.is_default !== undefined ? { is_default: r.is_default } : {}),
27
+ }));
28
+ }
29
+ export function applyTrackerAlias(input) {
30
+ const trimmed = input.trim();
31
+ if (!trimmed)
32
+ return trimmed;
33
+ return TRACKER_ALIASES[trimmed.toLowerCase()] ?? trimmed;
34
+ }
35
+ export function applyPriorityAlias(input) {
36
+ const trimmed = input.trim();
37
+ if (!trimmed)
38
+ return trimmed;
39
+ return PRIORITY_ALIASES[trimmed.toLowerCase()] ?? trimmed;
40
+ }
41
+ /** Parse "123 — Name" or plain name/id from intake selection. */
42
+ export function parseEnumerationSelection(value) {
43
+ const raw = value.trim();
44
+ const idPrefix = /^(\d+)\s*[-—]\s*/.exec(raw);
45
+ if (idPrefix) {
46
+ return idPrefix[1] ?? raw;
47
+ }
48
+ return raw;
49
+ }
50
+ function lookupByName(rows, name) {
51
+ const target = name.trim().toLowerCase();
52
+ return rows.find((row) => row.name.trim().toLowerCase() === target);
53
+ }
54
+ function lookupById(rows, id) {
55
+ return rows.find((row) => row.id === id);
56
+ }
57
+ export function resolveTracker(input, config) {
58
+ const raw = parseEnumerationSelection(input);
59
+ const asId = Number(raw);
60
+ if (Number.isInteger(asId) && asId > 0) {
61
+ return lookupById(config.trackers, asId);
62
+ }
63
+ const aliased = applyTrackerAlias(raw);
64
+ return lookupByName(config.trackers, aliased);
65
+ }
66
+ /** Acronym from config tracker name, e.g. "Change Request" → "CR". */
67
+ export function trackerNameAcronym(name) {
68
+ return name
69
+ .split(/\s+/)
70
+ .filter(Boolean)
71
+ .map((word) => word[0]?.toUpperCase() ?? "")
72
+ .join("");
73
+ }
74
+ /** Trackers that receive the Steps to Reproduce custom field on batch create. */
75
+ export const STEPS_TO_REPRODUCE_TRACKER_NAMES = ["Bug", "Task"];
76
+ export function trackerNeedsStepsToReproduce(tracker) {
77
+ const normalized = tracker.name.trim().toLowerCase();
78
+ return STEPS_TO_REPRODUCE_TRACKER_NAMES.some((name) => name.toLowerCase() === normalized);
79
+ }
80
+ /**
81
+ * Resolve a sheet label or "id — name" to a live config tracker.
82
+ * Matches: numeric id, exact name (case-insensitive), acronym, then tracker aliases.
83
+ */
84
+ export function resolveTrackerFromConfig(input, config) {
85
+ const raw = parseEnumerationSelection(input.trim());
86
+ if (!raw)
87
+ return undefined;
88
+ const asId = Number(raw);
89
+ if (Number.isInteger(asId) && asId > 0) {
90
+ return lookupById(config.trackers, asId);
91
+ }
92
+ const byName = lookupByName(config.trackers, raw);
93
+ if (byName)
94
+ return byName;
95
+ const upper = raw.toUpperCase();
96
+ const byAcronym = config.trackers.find((tracker) => trackerNameAcronym(tracker.name) === upper);
97
+ if (byAcronym)
98
+ return byAcronym;
99
+ const aliased = applyTrackerAlias(raw);
100
+ if (aliased !== raw) {
101
+ return lookupByName(config.trackers, aliased);
102
+ }
103
+ return undefined;
104
+ }
105
+ /**
106
+ * Resolve priority from config without alias tables (exact name or id only).
107
+ */
108
+ export function resolvePriorityFromConfig(input, config) {
109
+ const raw = parseEnumerationSelection(input.trim());
110
+ if (!raw)
111
+ return undefined;
112
+ const asId = Number(raw);
113
+ if (Number.isInteger(asId) && asId > 0) {
114
+ return lookupById(config.priorities, asId);
115
+ }
116
+ return lookupByName(config.priorities, raw);
117
+ }
118
+ export function resolveStatus(input, config) {
119
+ const raw = parseEnumerationSelection(input);
120
+ const asId = Number(raw);
121
+ if (Number.isInteger(asId) && asId > 0) {
122
+ return lookupById(config.statuses, asId);
123
+ }
124
+ return lookupByName(config.statuses, raw);
125
+ }
126
+ export function resolvePriority(input, config) {
127
+ const raw = parseEnumerationSelection(input);
128
+ const asId = Number(raw);
129
+ if (Number.isInteger(asId) && asId > 0) {
130
+ return lookupById(config.priorities, asId);
131
+ }
132
+ const aliased = applyPriorityAlias(raw);
133
+ return lookupByName(config.priorities, aliased);
134
+ }
135
+ export function resolveActivityFromPairAnswer(answer, config) {
136
+ const trimmed = answer.trim();
137
+ if (!trimmed) {
138
+ return undefined;
139
+ }
140
+ if (trimmed.toLowerCase() === "default" || /^default\b/i.test(trimmed)) {
141
+ return config.defaultActivityId;
142
+ }
143
+ return resolveActivity(trimmed, config)?.id;
144
+ }
145
+ export function resolveActivity(input, config) {
146
+ if (input === undefined) {
147
+ return lookupById(config.activities, config.defaultActivityId);
148
+ }
149
+ if (typeof input === "number") {
150
+ return lookupById(config.activities, input);
151
+ }
152
+ const raw = parseEnumerationSelection(String(input));
153
+ const asId = Number(raw);
154
+ if (Number.isInteger(asId) && asId > 0) {
155
+ return lookupById(config.activities, asId);
156
+ }
157
+ return lookupByName(config.activities, raw);
158
+ }
159
+ export function enumerationOptions(rows) {
160
+ return rows.map((r) => `${r.id} — ${r.name}`);
161
+ }
162
+ export function formatEnumerationLine(label, rows) {
163
+ if (rows.length === 0) {
164
+ return `${label}: (none loaded)`;
165
+ }
166
+ return `${label}: ${rows.map((r) => `${r.id}=${r.name}`).join(", ")}`;
167
+ }
168
+ export function formatConfigForInstructions(config) {
169
+ const aliasLine = Object.entries(TRACKER_ALIASES)
170
+ .map(([k, v]) => `${k}→${v}`)
171
+ .join(", ");
172
+ const activityDefault = config.defaultActivityName
173
+ ? `${config.defaultActivityId} (${config.defaultActivityName})`
174
+ : String(config.defaultActivityId);
175
+ return [
176
+ "Redmine config (loaded at MCP connect; TTL cache refreshed on tool calls):",
177
+ formatEnumerationLine("Activities", config.activities),
178
+ `Default time-log activity: ${activityDefault} (REDMINE_ACTIVITY_ID)`,
179
+ formatEnumerationLine("Trackers", config.trackers),
180
+ `Tracker aliases: ${aliasLine}`,
181
+ formatEnumerationLine("Priorities", config.priorities),
182
+ "Priority aliases: medium→Normal",
183
+ formatEnumerationLine("Statuses", config.statuses),
184
+ ].join("\n");
185
+ }
186
+ async function fetchRedmineConfig() {
187
+ const [activitiesData, trackersData, prioritiesData, statusesData] = await Promise.all([
188
+ getTimeEntryActivities(),
189
+ getTrackers(),
190
+ getIssuePriorities(),
191
+ getIssueStatuses(),
192
+ ]);
193
+ const activities = parseEnumerations(activitiesData.time_entry_activities);
194
+ const trackers = parseEnumerations(trackersData.trackers);
195
+ const priorities = parseEnumerations(prioritiesData.issue_priorities);
196
+ const statuses = parseEnumerations(statusesData.issue_statuses);
197
+ const { activityId: envActivityId } = getTimeEntryDefaults();
198
+ let defaultActivityId = envActivityId;
199
+ let defaultActivityName = lookupById(activities, envActivityId)?.name ?? null;
200
+ if (!defaultActivityName) {
201
+ const fallback = activities.find((a) => a.is_default) ?? activities[0];
202
+ if (fallback) {
203
+ defaultActivityId = fallback.id;
204
+ defaultActivityName = fallback.name;
205
+ }
206
+ }
207
+ return {
208
+ fetchedAt: Date.now(),
209
+ activities,
210
+ trackers,
211
+ priorities,
212
+ statuses,
213
+ defaultActivityId,
214
+ defaultActivityName,
215
+ trackerAliases: { ...TRACKER_ALIASES },
216
+ priorityAliases: { ...PRIORITY_ALIASES },
217
+ };
218
+ }
219
+ export async function loadRedmineConfig(options) {
220
+ if (!options?.force &&
221
+ cached &&
222
+ Date.now() - cached.fetchedAt < CACHE_MS) {
223
+ return cached;
224
+ }
225
+ cached = await fetchRedmineConfig();
226
+ return cached;
227
+ }
228
+ /** Resolved default activity for time logging (validates REDMINE_ACTIVITY_ID against API). */
229
+ export async function getResolvedDefaultActivity() {
230
+ const config = await loadRedmineConfig();
231
+ const activity = resolveActivity(config.defaultActivityId, config);
232
+ return {
233
+ activityId: activity?.id ?? config.defaultActivityId,
234
+ activityName: activity?.name ?? config.defaultActivityName,
235
+ };
236
+ }
237
+ export function defaultActivityOption(config) {
238
+ if (config.defaultActivityName) {
239
+ return `default — ${config.defaultActivityName}`;
240
+ }
241
+ return "default";
242
+ }
243
+ /** How activities/trackers/etc. were loaded for this MCP session. */
244
+ export function configCacheMeta(config) {
245
+ const cacheAgeMs = Date.now() - config.fetchedAt;
246
+ return {
247
+ source: "cache",
248
+ fetchedAt: config.fetchedAt,
249
+ cacheAgeMs,
250
+ cacheTtlMs: CACHE_MS,
251
+ refreshed: cacheAgeMs < 1000,
252
+ };
253
+ }
254
+ export function configOptionsPayload(config) {
255
+ return {
256
+ ...configCacheMeta(config),
257
+ activities: config.activities,
258
+ trackers: config.trackers,
259
+ priorities: config.priorities,
260
+ statuses: config.statuses,
261
+ trackerOptions: enumerationOptions(config.trackers),
262
+ statusOptions: enumerationOptions(config.statuses),
263
+ priorityOptions: enumerationOptions(config.priorities),
264
+ activityOptions: enumerationOptions(config.activities),
265
+ defaultActivityId: config.defaultActivityId,
266
+ defaultActivityName: config.defaultActivityName,
267
+ trackerAliases: config.trackerAliases,
268
+ priorityAliases: config.priorityAliases,
269
+ };
270
+ }
271
+ //# sourceMappingURL=redmineConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redmineConfig.js","sourceRoot":"","sources":["../../src/services/redmineConfig.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import type { BatchParseResult } from "./batchCreationTypes.js";
2
+ import { type BatchSheetColumnMap } from "./sheetColumnMap.js";
3
+ import type { RawBatchSheet } from "./extractRawBatchSheet.js";
4
+ /** Column role keys the agent maps from sheet headers (by name or 0-based index). */
5
+ export type BatchColumnRole = "userStory" | "subtask" | "description" | "hours" | "targetVersion" | "assignedTo" | "comments" | "redmineId" | "ticket" | "system" | "status" | "priority" | "sheetType";
6
+ export type BatchColumnMappingInput = {
7
+ /** 0-based index into raw rows for the header line */
8
+ headerRowIndex: number;
9
+ /** Header label or 0-based column index per role */
10
+ columns: Partial<Record<BatchColumnRole, string | number>>;
11
+ };
12
+ export type BatchColumnFieldSchemaEntry = {
13
+ role: BatchColumnRole;
14
+ required: boolean;
15
+ redmineUse: string;
16
+ /**
17
+ * When set, this mapped role feeds the Steps to Reproduce custom field (Bug/Task)
18
+ * at this priority. Not a separate sheet column — agent maps these roles only.
19
+ */
20
+ stepsToReproducePriority?: number;
21
+ };
22
+ /**
23
+ * Steps to Reproduce is never its own sheet column. Workflow derives it from mapped roles.
24
+ * Returned on map_columns / confirm_mapping so the agent does not invent a column.
25
+ */
26
+ export declare const STEPS_TO_REPRODUCE_RULE: {
27
+ readonly notASheetColumn: true;
28
+ readonly doNotMapSeparateColumn: true;
29
+ readonly appliesToTrackers: readonly ["Bug", "Task"];
30
+ readonly valuePriority: readonly [{
31
+ readonly priority: 1;
32
+ readonly source: "comments";
33
+ readonly role: BatchColumnRole;
34
+ readonly label: "comments role (e.g. Comments / Question, RT Comment)";
35
+ }, {
36
+ readonly priority: 2;
37
+ readonly source: "description";
38
+ readonly role: BatchColumnRole;
39
+ readonly label: "description role (Description column when present)";
40
+ }, {
41
+ readonly priority: 3;
42
+ readonly source: "issueSubject";
43
+ readonly roles: BatchColumnRole[];
44
+ readonly label: "issue subject — first line of subtask cell, else userStory cell";
45
+ }, {
46
+ readonly priority: 4;
47
+ readonly source: "fallback";
48
+ readonly label: "\"...\"";
49
+ }];
50
+ readonly summary: "Map comments and description roles when headers exist. Bug/Task Steps to Reproduce is filled automatically from those mapped values, then issue subject — never map a dedicated Steps to Reproduce column.";
51
+ };
52
+ export declare const BATCH_COLUMN_FIELD_SCHEMA: BatchColumnFieldSchemaEntry[];
53
+ export type ColumnMappingProblem = {
54
+ role: BatchColumnRole;
55
+ issue: string;
56
+ spec?: string | number;
57
+ };
58
+ export type ColumnMappingValidation = {
59
+ valid: boolean;
60
+ problems: ColumnMappingProblem[];
61
+ detectedHeaders: string[];
62
+ headerRowIndex: number;
63
+ };
64
+ export type SuggestedColumnMapping = {
65
+ headerRowIndex: number;
66
+ columns: Partial<Record<BatchColumnRole, string>>;
67
+ suggestedColumnIndices: Partial<Record<BatchColumnRole, number>>;
68
+ unmappedOptionalRoles: BatchColumnRole[];
69
+ ambiguousRoles: BatchColumnRole[];
70
+ };
71
+ /**
72
+ * Derive column roles from detected headers (MCP — agent uses this, no repo file search).
73
+ * Recognizes User Stories + Tasks layout as well as Task + Sub-Tasks.
74
+ */
75
+ export declare function suggestColumnMappingFromHeaders(headers: string[], headerRowIndex: number): SuggestedColumnMapping;
76
+ /** Resolved Steps to Reproduce sources for a concrete columnMapping (MCP + mapping preview). */
77
+ export declare function buildStepsToReproduceMappingSection(mapping: BatchColumnMappingInput, headers: string[]): string;
78
+ /** Validate agent columnMapping before building the issue tree. */
79
+ export declare function validateColumnMapping(raw: RawBatchSheet, mapping: BatchColumnMappingInput): ColumnMappingValidation;
80
+ /** AskQuestion prompts for map_columns / fix_column_mapping steps. */
81
+ export declare function buildColumnMappingQuestions(validation: ColumnMappingValidation, options?: {
82
+ includeOptional?: boolean;
83
+ }): Array<{
84
+ id: string;
85
+ field: string;
86
+ question: string;
87
+ options: string[];
88
+ }>;
89
+ /** Human-readable table of agent columnMapping for confirm_mapping step. */
90
+ export declare function buildMappingPreview(mapping: BatchColumnMappingInput, headers: string[]): string;
91
+ export declare function columnMappingToSheetMap(headers: string[], mapping: BatchColumnMappingInput): BatchSheetColumnMap;
92
+ export declare function parseBatchWithColumnMapping(raw: RawBatchSheet, mapping: BatchColumnMappingInput): BatchParseResult;
93
+ //# sourceMappingURL=batchColumnMapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batchColumnMapping.d.ts","sourceRoot":"","sources":["../../src/spreadsheet/batchColumnMapping.ts"],"names":[],"mappings":"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"}