@muzzamil-khan/redmine-agent-mcp 1.0.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 (94) hide show
  1. package/README.md +44 -0
  2. package/dist/config/env.d.ts +12 -0
  3. package/dist/config/env.d.ts.map +1 -0
  4. package/dist/config/env.js +32 -0
  5. package/dist/config/env.js.map +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +65 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/mcp/server.d.ts +3 -0
  11. package/dist/mcp/server.d.ts.map +1 -0
  12. package/dist/mcp/server.js +162 -0
  13. package/dist/mcp/server.js.map +1 -0
  14. package/dist/prompts/operationalRules.d.ts +2 -0
  15. package/dist/prompts/operationalRules.d.ts.map +1 -0
  16. package/dist/prompts/operationalRules.js +12 -0
  17. package/dist/prompts/operationalRules.js.map +1 -0
  18. package/dist/prompts/questionFlows.d.ts +8 -0
  19. package/dist/prompts/questionFlows.d.ts.map +1 -0
  20. package/dist/prompts/questionFlows.js +27 -0
  21. package/dist/prompts/questionFlows.js.map +1 -0
  22. package/dist/services/redmine.d.ts +44 -0
  23. package/dist/services/redmine.d.ts.map +1 -0
  24. package/dist/services/redmine.js +139 -0
  25. package/dist/services/redmine.js.map +1 -0
  26. package/dist/types/workflow.d.ts +22 -0
  27. package/dist/types/workflow.d.ts.map +1 -0
  28. package/dist/types/workflow.js +2 -0
  29. package/dist/types/workflow.js.map +1 -0
  30. package/dist/utils/elicitation.d.ts +9 -0
  31. package/dist/utils/elicitation.d.ts.map +1 -0
  32. package/dist/utils/elicitation.js +15 -0
  33. package/dist/utils/elicitation.js.map +1 -0
  34. package/dist/utils/fetchUserLogs.d.ts +41 -0
  35. package/dist/utils/fetchUserLogs.d.ts.map +1 -0
  36. package/dist/utils/fetchUserLogs.js +47 -0
  37. package/dist/utils/fetchUserLogs.js.map +1 -0
  38. package/dist/utils/logTargets.d.ts +23 -0
  39. package/dist/utils/logTargets.d.ts.map +1 -0
  40. package/dist/utils/logTargets.js +33 -0
  41. package/dist/utils/logTargets.js.map +1 -0
  42. package/dist/utils/mcpResponse.d.ts +8 -0
  43. package/dist/utils/mcpResponse.d.ts.map +1 -0
  44. package/dist/utils/mcpResponse.js +11 -0
  45. package/dist/utils/mcpResponse.js.map +1 -0
  46. package/dist/utils/timeframe.d.ts +9 -0
  47. package/dist/utils/timeframe.d.ts.map +1 -0
  48. package/dist/utils/timeframe.js +27 -0
  49. package/dist/utils/timeframe.js.map +1 -0
  50. package/dist/utils/validation.d.ts +2 -0
  51. package/dist/utils/validation.d.ts.map +1 -0
  52. package/dist/utils/validation.js +6 -0
  53. package/dist/utils/validation.js.map +1 -0
  54. package/dist/workflows/addLogCommentWorkflow.d.ts +15 -0
  55. package/dist/workflows/addLogCommentWorkflow.d.ts.map +1 -0
  56. package/dist/workflows/addLogCommentWorkflow.js +230 -0
  57. package/dist/workflows/addLogCommentWorkflow.js.map +1 -0
  58. package/dist/workflows/checkCommentPermissionsWorkflow.d.ts +18 -0
  59. package/dist/workflows/checkCommentPermissionsWorkflow.d.ts.map +1 -0
  60. package/dist/workflows/checkCommentPermissionsWorkflow.js +98 -0
  61. package/dist/workflows/checkCommentPermissionsWorkflow.js.map +1 -0
  62. package/dist/workflows/checkProjectAccessWorkflow.d.ts +17 -0
  63. package/dist/workflows/checkProjectAccessWorkflow.d.ts.map +1 -0
  64. package/dist/workflows/checkProjectAccessWorkflow.js +47 -0
  65. package/dist/workflows/checkProjectAccessWorkflow.js.map +1 -0
  66. package/dist/workflows/getCurrentUserWorkflow.d.ts +3 -0
  67. package/dist/workflows/getCurrentUserWorkflow.d.ts.map +1 -0
  68. package/dist/workflows/getCurrentUserWorkflow.js +17 -0
  69. package/dist/workflows/getCurrentUserWorkflow.js.map +1 -0
  70. package/dist/workflows/getIssueWorkflow.d.ts +7 -0
  71. package/dist/workflows/getIssueWorkflow.d.ts.map +1 -0
  72. package/dist/workflows/getIssueWorkflow.js +32 -0
  73. package/dist/workflows/getIssueWorkflow.js.map +1 -0
  74. package/dist/workflows/getLogsWorkflow.d.ts +11 -0
  75. package/dist/workflows/getLogsWorkflow.d.ts.map +1 -0
  76. package/dist/workflows/getLogsWorkflow.js +61 -0
  77. package/dist/workflows/getLogsWorkflow.js.map +1 -0
  78. package/dist/workflows/getProjectsWorkflow.d.ts +3 -0
  79. package/dist/workflows/getProjectsWorkflow.d.ts.map +1 -0
  80. package/dist/workflows/getProjectsWorkflow.js +17 -0
  81. package/dist/workflows/getProjectsWorkflow.js.map +1 -0
  82. package/dist/workflows/getTickets.d.ts +2 -0
  83. package/dist/workflows/getTickets.d.ts.map +1 -0
  84. package/dist/workflows/getTickets.js +2 -0
  85. package/dist/workflows/getTickets.js.map +1 -0
  86. package/dist/workflows/listMyIssuesWorkflow.d.ts +9 -0
  87. package/dist/workflows/listMyIssuesWorkflow.d.ts.map +1 -0
  88. package/dist/workflows/listMyIssuesWorkflow.js +20 -0
  89. package/dist/workflows/listMyIssuesWorkflow.js.map +1 -0
  90. package/dist/workflows/logTimeWorkflow.d.ts +50 -0
  91. package/dist/workflows/logTimeWorkflow.d.ts.map +1 -0
  92. package/dist/workflows/logTimeWorkflow.js +797 -0
  93. package/dist/workflows/logTimeWorkflow.js.map +1 -0
  94. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Redmine Agent MCP
2
+
3
+ MCP server for Redmine batch time logging.
4
+
5
+ ## Quick use (single command)
6
+
7
+ Add this MCP server config in any project:
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "redmine-agent": {
13
+ "command": "npx",
14
+ "args": ["-y", "@muzzamil-khan/redmine-agent-mcp"],
15
+ "env": {
16
+ "REDMINE_BASE_URL": "https://redmine.example.com",
17
+ "REDMINE_API_KEY": "YOUR_API_KEY",
18
+ "REDMINE_ACTIVITY_ID": "5",
19
+ "REDMINE_BILLABLE_HOURS_FIELD_ID": "1"
20
+ }
21
+ }
22
+ }
23
+ }
24
+ ```
25
+
26
+ This runs the server directly with:
27
+
28
+ ```bash
29
+ npx -y @muzzamil-khan/redmine-agent-mcp
30
+ ```
31
+
32
+ ## Environment variables
33
+
34
+ - `REDMINE_BASE_URL`
35
+ - `REDMINE_API_KEY`
36
+ - `REDMINE_ACTIVITY_ID`
37
+ - `REDMINE_BILLABLE_HOURS_FIELD_ID`
38
+
39
+ ## Local development (optional)
40
+
41
+ ```bash
42
+ npm install
43
+ npm run mcp
44
+ ```
@@ -0,0 +1,12 @@
1
+ declare const projectRoot: string;
2
+ export { projectRoot };
3
+ export declare function requireRedmineEnv(): {
4
+ baseUrl: string;
5
+ apiKey: string;
6
+ };
7
+ export declare function getTimeEntryDefaults(): {
8
+ activityId: number;
9
+ billableHoursFieldId: number;
10
+ };
11
+ export declare function getDefaultTimeComment(): string;
12
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,WAAW,QAAmC,CAAC;AAIrD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,wBAAgB,iBAAiB,IAAI;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAClB,CAaA;AAED,wBAAgB,oBAAoB,IAAI;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;CAChC,CAgBA;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAG9C"}
@@ -0,0 +1,32 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ import dotenv from "dotenv";
4
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
+ const projectRoot = path.resolve(__dirname, "../..");
6
+ dotenv.config({ path: path.join(projectRoot, ".env") });
7
+ export { projectRoot };
8
+ export function requireRedmineEnv() {
9
+ const baseUrl = process.env.REDMINE_BASE_URL?.trim() ??
10
+ process.env.REDMINE_URL?.trim();
11
+ const apiKey = process.env.REDMINE_API_KEY?.trim();
12
+ if (!baseUrl || !apiKey) {
13
+ throw new Error("Set REDMINE_BASE_URL (or REDMINE_URL) and REDMINE_API_KEY in .env or MCP env");
14
+ }
15
+ return { baseUrl, apiKey };
16
+ }
17
+ export function getTimeEntryDefaults() {
18
+ const activityId = Number(process.env.REDMINE_ACTIVITY_ID ?? 5);
19
+ const billableHoursFieldId = Number(process.env.REDMINE_BILLABLE_HOURS_FIELD_ID ?? 1);
20
+ if (!Number.isInteger(activityId) || activityId <= 0) {
21
+ throw new Error("REDMINE_ACTIVITY_ID must be a positive integer");
22
+ }
23
+ if (!Number.isInteger(billableHoursFieldId) || billableHoursFieldId <= 0) {
24
+ throw new Error("REDMINE_BILLABLE_HOURS_FIELD_ID must be a positive integer");
25
+ }
26
+ return { activityId, billableHoursFieldId };
27
+ }
28
+ export function getDefaultTimeComment() {
29
+ const value = process.env.REDMINE_DEFAULT_TIME_COMMENT?.trim();
30
+ return value || "Development work";
31
+ }
32
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAErD,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,UAAU,iBAAiB;IAI7B,MAAM,OAAO,GACT,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE;QACpC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAEnD,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACX,8EAA8E,CACjF,CAAC;IACN,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,oBAAoB;IAIhC,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,CAAC,CAAC;IAChE,MAAM,oBAAoB,GAAG,MAAM,CAC/B,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,CACnD,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,oBAAoB,IAAI,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CACX,4DAA4D,CAC/D,CAAC;IACN,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACjC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,CAAC;IAC/D,OAAO,KAAK,IAAI,kBAAkB,CAAC;AACvC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Optional HTTP API for local testing. Primary interface is MCP (see src/mcp/server.ts).
3
+ */
4
+ import express from "express";
5
+ import cors from "cors";
6
+ import { getCurrentUserWorkflow } from "./workflows/getCurrentUserWorkflow.js";
7
+ import { getProjectsWorkflow } from "./workflows/getProjectsWorkflow.js";
8
+ import { getIssueWorkflow } from "./workflows/getIssueWorkflow.js";
9
+ import { getLogsWorkflow } from "./workflows/getLogsWorkflow.js";
10
+ import { addLogCommentWorkflow } from "./workflows/addLogCommentWorkflow.js";
11
+ import { checkCommentPermissionsWorkflow } from "./workflows/checkCommentPermissionsWorkflow.js";
12
+ import { logTimeWorkflow } from "./workflows/logTimeWorkflow.js";
13
+ const app = express();
14
+ app.use(cors());
15
+ app.use(express.json());
16
+ app.get("/api/user", async (_, res) => {
17
+ try {
18
+ res.json(await getCurrentUserWorkflow());
19
+ }
20
+ catch {
21
+ res.status(500).json({
22
+ success: false,
23
+ error: "Failed to fetch user",
24
+ });
25
+ }
26
+ });
27
+ app.get("/api/projects", async (_, res) => {
28
+ try {
29
+ res.json(await getProjectsWorkflow());
30
+ }
31
+ catch {
32
+ res.status(500).json({
33
+ success: false,
34
+ error: "Failed to fetch projects",
35
+ });
36
+ }
37
+ });
38
+ app.get("/api/issues/:issueId", async (req, res) => {
39
+ const issueId = Number(req.params.issueId);
40
+ res.json(await getIssueWorkflow({ issueId }));
41
+ });
42
+ app.get("/api/logs", async (req, res) => {
43
+ const { project, environment, timeframe, customFrom, customTo } = req.query;
44
+ res.json(await getLogsWorkflow({
45
+ ...(typeof project === "string" ? { project } : {}),
46
+ ...(typeof environment === "string" ? { environment } : {}),
47
+ ...(typeof timeframe === "string" ? { timeframe } : {}),
48
+ ...(typeof customFrom === "string" ? { customFrom } : {}),
49
+ ...(typeof customTo === "string" ? { customTo } : {}),
50
+ }));
51
+ });
52
+ app.get("/api/comments/permissions", async (_, res) => {
53
+ res.json(await checkCommentPermissionsWorkflow());
54
+ });
55
+ app.post("/api/logs/comment", async (req, res) => {
56
+ res.json(await addLogCommentWorkflow(req.body ?? {}));
57
+ });
58
+ app.post("/api/time_entries", async (req, res) => {
59
+ res.json(await logTimeWorkflow(req.body ?? {}));
60
+ });
61
+ const PORT = Number(process.env.PORT) || 3000;
62
+ app.listen(PORT, () => {
63
+ console.error(`Redmine Agent API (dev) http://localhost:${PORT} — use MCP in Cursor for phase 1`);
64
+ });
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":""}
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import * as z from "zod/v4";
5
+ import { logTimeWorkflow } from "../workflows/logTimeWorkflow.js";
6
+ import { workflowToMcpContent } from "../utils/mcpResponse.js";
7
+ const server = new McpServer({
8
+ name: "redmine-agent",
9
+ version: "3.4.1",
10
+ }, {
11
+ instructions: `Local Redmine tool: batch log time only (redmine_agent_log_time).
12
+ When needsInput and data.batchMode is true, show ALL items in questions[] in ONE AskQuestion. dateIssues ids are YYYY-MM-DD; pairHours/pairComments ids are YYYY-MM-DD:issueId.
13
+ Flow: dates → batch dateIssues → batch pairHours → batch pairComments → preview → confirmSave=yes (no yes/no pair step).`,
14
+ });
15
+ server.registerTool("redmine_agent_log_time", {
16
+ description: "Batch log time: dates → batch dateIssues (per date, one page) → batch pairHours → batch pairComments → preview → confirmSave=yes. Selecting issues per date defines what to log; no pairInclude step.",
17
+ inputSchema: {
18
+ promptHint: z
19
+ .string()
20
+ .optional()
21
+ .describe("User message text; if it mentions 'today', date step is skipped"),
22
+ dates: z
23
+ .array(z.string())
24
+ .optional()
25
+ .describe("Step 1 — Today | Multiple | Other, or YYYY-MM-DD list"),
26
+ spentOn: z
27
+ .string()
28
+ .optional()
29
+ .describe("Custom date YYYY-MM-DD when Other was chosen"),
30
+ pendingDates: z.array(z.string()).optional(),
31
+ activeDate: z.string().optional(),
32
+ dateIssues: z
33
+ .record(z.string(), z.union([
34
+ z.array(z.number().int().positive()),
35
+ z.string(),
36
+ ]))
37
+ .optional()
38
+ .describe("Step 2 batch — issue IDs per date (number[] or comma-separated string)"),
39
+ pendingIssueIds: z.array(z.number().int().positive()).optional(),
40
+ activeIssueId: z.number().int().positive().optional(),
41
+ issueIds: z
42
+ .array(z.number().int().positive())
43
+ .optional()
44
+ .describe("Legacy — fills all dates if dateIssues omitted (single date only)"),
45
+ pairInclude: z
46
+ .enum(["yes", "no"])
47
+ .optional()
48
+ .describe("Legacy single pair; prefer pairIncludes"),
49
+ pairIncludes: z
50
+ .record(z.string(), z.string())
51
+ .optional()
52
+ .describe('Step 3 batch — all yes/no keyed by "YYYY-MM-DD:issueId"'),
53
+ pairHours: z
54
+ .record(z.string(), z.union([z.number(), z.string()]))
55
+ .optional()
56
+ .describe("Step 4 batch — hours per included pair key"),
57
+ pairComments: z
58
+ .record(z.string(), z.string())
59
+ .optional()
60
+ .describe('Step 5 batch — "default" or custom text per pair key'),
61
+ issueSubjects: z
62
+ .record(z.string(), z.string())
63
+ .optional()
64
+ .describe("issueId → subject; pass back from data for question labels"),
65
+ issueOptions: z
66
+ .array(z.object({
67
+ issueId: z.number().int().positive(),
68
+ subject: z.string().optional(),
69
+ label: z.string().optional(),
70
+ }))
71
+ .optional(),
72
+ skippedPairs: z
73
+ .array(z.string())
74
+ .optional()
75
+ .describe('Skipped pair keys "YYYY-MM-DD:issueId"'),
76
+ issueId: z.number().int().positive().optional(),
77
+ hours: z.number().positive().optional().describe("Legacy single pair hours"),
78
+ commentChoice: z.enum(["default", "custom"]).optional(),
79
+ comments: z.string().optional(),
80
+ entries: z
81
+ .array(z.object({
82
+ issueId: z.number().int().positive(),
83
+ hours: z.number().positive(),
84
+ spentOn: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
85
+ comments: z.string(),
86
+ }))
87
+ .optional(),
88
+ confirmSave: z.enum(["yes", "no"]).optional(),
89
+ },
90
+ }, async (input) => workflowToMcpContent(await logTimeWorkflow({
91
+ ...(input.promptHint !== undefined
92
+ ? { promptHint: input.promptHint }
93
+ : {}),
94
+ ...(input.dates !== undefined ? { dates: input.dates } : {}),
95
+ ...(input.spentOn !== undefined
96
+ ? { spentOn: input.spentOn }
97
+ : {}),
98
+ ...(input.pendingDates !== undefined
99
+ ? { pendingDates: input.pendingDates }
100
+ : {}),
101
+ ...(input.activeDate !== undefined
102
+ ? { activeDate: input.activeDate }
103
+ : {}),
104
+ ...(input.dateIssues !== undefined
105
+ ? { dateIssues: input.dateIssues }
106
+ : {}),
107
+ ...(input.pendingIssueIds !== undefined
108
+ ? { pendingIssueIds: input.pendingIssueIds }
109
+ : {}),
110
+ ...(input.activeIssueId !== undefined
111
+ ? { activeIssueId: input.activeIssueId }
112
+ : {}),
113
+ ...(input.issueIds !== undefined
114
+ ? { issueIds: input.issueIds }
115
+ : {}),
116
+ ...(input.issueId !== undefined
117
+ ? { issueId: input.issueId }
118
+ : {}),
119
+ ...(input.hours !== undefined ? { hours: input.hours } : {}),
120
+ ...(input.pairInclude !== undefined
121
+ ? { pairInclude: input.pairInclude }
122
+ : {}),
123
+ ...(input.pairIncludes !== undefined
124
+ ? { pairIncludes: input.pairIncludes }
125
+ : {}),
126
+ ...(input.pairHours !== undefined
127
+ ? { pairHours: input.pairHours }
128
+ : {}),
129
+ ...(input.pairComments !== undefined
130
+ ? { pairComments: input.pairComments }
131
+ : {}),
132
+ ...(input.issueSubjects !== undefined
133
+ ? { issueSubjects: input.issueSubjects }
134
+ : {}),
135
+ ...(input.issueOptions !== undefined
136
+ ? { issueOptions: input.issueOptions }
137
+ : {}),
138
+ ...(input.skippedPairs !== undefined
139
+ ? { skippedPairs: input.skippedPairs }
140
+ : {}),
141
+ ...(input.commentChoice !== undefined
142
+ ? { commentChoice: input.commentChoice }
143
+ : {}),
144
+ ...(input.comments !== undefined
145
+ ? { comments: input.comments }
146
+ : {}),
147
+ ...(input.entries !== undefined
148
+ ? { entries: input.entries }
149
+ : {}),
150
+ ...(input.confirmSave !== undefined
151
+ ? { confirmSave: input.confirmSave }
152
+ : {}),
153
+ })));
154
+ async function main() {
155
+ const transport = new StdioServerTransport();
156
+ await server.connect(transport);
157
+ }
158
+ main().catch((error) => {
159
+ console.error("Redmine Agent MCP server error:", error);
160
+ process.exit(1);
161
+ });
162
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const operationalRules = "\nOperational Rules:\n\n1. Always ask for missing required information.\n2. Never assume issue IDs, projects, or environments.\n3. Confirm destructive actions before execution.\n4. Return structured responses.\n5. Keep workflow responses machine-readable.\n6. Operational logs (time entries) must only include the authenticated API user \u2014 never other users' entries.\n7. Comments on logs require permission check, user-selected target (issue or own time entry), comment text, and confirmSave=yes before writing.\n";
2
+ //# sourceMappingURL=operationalRules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operationalRules.d.ts","sourceRoot":"","sources":["../../src/prompts/operationalRules.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,2gBAU5B,CAAC"}
@@ -0,0 +1,12 @@
1
+ export const operationalRules = `
2
+ Operational Rules:
3
+
4
+ 1. Always ask for missing required information.
5
+ 2. Never assume issue IDs, projects, or environments.
6
+ 3. Confirm destructive actions before execution.
7
+ 4. Return structured responses.
8
+ 5. Keep workflow responses machine-readable.
9
+ 6. Operational logs (time entries) must only include the authenticated API user — never other users' entries.
10
+ 7. Comments on logs require permission check, user-selected target (issue or own time entry), comment text, and confirmSave=yes before writing.
11
+ `;
12
+ //# sourceMappingURL=operationalRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operationalRules.js","sourceRoot":"","sources":["../../src/prompts/operationalRules.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;CAU/B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { WorkflowQuestion } from "../types/workflow.js";
2
+ export declare const issueIdQuestion: WorkflowQuestion;
3
+ export declare const projectQuestion: WorkflowQuestion;
4
+ export declare const environmentQuestion: WorkflowQuestion;
5
+ export declare const timeframeQuestion: WorkflowQuestion;
6
+ export declare const customFromQuestion: WorkflowQuestion;
7
+ export declare const customToQuestion: WorkflowQuestion;
8
+ //# sourceMappingURL=questionFlows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questionFlows.d.ts","sourceRoot":"","sources":["../../src/prompts/questionFlows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,eAAO,MAAM,eAAe,EAAE,gBAG7B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,gBAG7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,gBAIjC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,gBAI/B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAGhC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,gBAG9B,CAAC"}
@@ -0,0 +1,27 @@
1
+ export const issueIdQuestion = {
2
+ field: "issueId",
3
+ question: "Please provide Redmine issue ID",
4
+ };
5
+ export const projectQuestion = {
6
+ field: "project",
7
+ question: "Select project",
8
+ };
9
+ export const environmentQuestion = {
10
+ field: "environment",
11
+ question: "Select environment",
12
+ options: ["staging", "production"],
13
+ };
14
+ export const timeframeQuestion = {
15
+ field: "timeframe",
16
+ question: "Select timeframe",
17
+ options: ["last 1 hour", "last 24 hours", "custom"],
18
+ };
19
+ export const customFromQuestion = {
20
+ field: "customFrom",
21
+ question: "Enter start date (YYYY-MM-DD)",
22
+ };
23
+ export const customToQuestion = {
24
+ field: "customTo",
25
+ question: "Enter end date (YYYY-MM-DD)",
26
+ };
27
+ //# sourceMappingURL=questionFlows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questionFlows.js","sourceRoot":"","sources":["../../src/prompts/questionFlows.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC7C,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,iCAAiC;CAC9C,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC7C,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,gBAAgB;CAC7B,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACjD,KAAK,EAAE,aAAa;IACpB,QAAQ,EAAE,oBAAoB;IAC9B,OAAO,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAqB;IAC/C,KAAK,EAAE,WAAW;IAClB,QAAQ,EAAE,kBAAkB;IAC5B,OAAO,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,QAAQ,CAAC;CACtD,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAqB;IAChD,KAAK,EAAE,YAAY;IACnB,QAAQ,EAAE,+BAA+B;CAC5C,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAqB;IAC9C,KAAK,EAAE,UAAU;IACjB,QAAQ,EAAE,6BAA6B;CAC1C,CAAC"}
@@ -0,0 +1,44 @@
1
+ import "../config/env.js";
2
+ export declare const redmine: import("axios").AxiosInstance;
3
+ export type ProbeResult = "ok" | "forbidden" | "error";
4
+ export declare function probeGet(path: string, params?: Record<string, string | number>): Promise<ProbeResult>;
5
+ export declare function probePut(path: string, body: unknown): Promise<ProbeResult>;
6
+ export declare function getProjects(): Promise<any>;
7
+ export declare function getCurrentUser(): Promise<any>;
8
+ export declare function getIssueById(issueId: number): Promise<any>;
9
+ export declare function getTimeEntryById(timeEntryId: number): Promise<any>;
10
+ export declare function getIssues(params: {
11
+ projectId?: string;
12
+ assignedToId?: "me" | number;
13
+ statusId?: "open" | "closed" | "*";
14
+ limit?: number;
15
+ offset?: number;
16
+ }): Promise<any>;
17
+ /** Time entries; pass userId to restrict to one user (required for operational logs). */
18
+ export declare function getTimeEntries(params: {
19
+ projectId: string;
20
+ from: string;
21
+ to: string;
22
+ userId: number;
23
+ limit?: number;
24
+ }): Promise<any>;
25
+ export declare function getTimeEntriesForUser(params: {
26
+ userId: number;
27
+ limit?: number;
28
+ }): Promise<any>;
29
+ export declare function addIssueComment(issueId: number, notes: string): Promise<any>;
30
+ export declare function logTimeEntry(params: {
31
+ issueId: number;
32
+ hours: number;
33
+ spentOn: string;
34
+ activityId: number;
35
+ billableHoursFieldId: number;
36
+ billableHours: string;
37
+ comments?: string;
38
+ }): Promise<any>;
39
+ export declare function updateTimeEntryComment(timeEntryId: number, comments: string, entry: {
40
+ hours: number;
41
+ activity_id: number;
42
+ spent_on: string;
43
+ }): Promise<any>;
44
+ //# sourceMappingURL=redmine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redmine.d.ts","sourceRoot":"","sources":["../../src/services/redmine.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,CAAC;AAK1B,eAAO,MAAM,OAAO,+BAMlB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,WAAW,GAAG,OAAO,CAAC;AAEvD,wBAAsB,QAAQ,CAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACzC,OAAO,CAAC,WAAW,CAAC,CAUtB;AAED,wBAAsB,QAAQ,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,CAAC,CAiBtB;AAED,wBAAsB,WAAW,iBAGhC;AAED,wBAAsB,cAAc,iBAGnC;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,gBAGjD;AAED,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,gBAGzD;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,GAAG,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,gBAqBA;AAED,yFAAyF;AACzF,wBAAsB,cAAc,CAAC,MAAM,EAAE;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,gBAWA;AAED,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB,gBAQA;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAKnE;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,gBAmBA;AAED,wBAAsB,sBAAsB,CACxC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;IACH,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACpB,gBAWJ"}
@@ -0,0 +1,139 @@
1
+ import axios from "axios";
2
+ import "../config/env.js";
3
+ import { requireRedmineEnv } from "../config/env.js";
4
+ const { baseUrl, apiKey } = requireRedmineEnv();
5
+ export const redmine = axios.create({
6
+ baseURL: baseUrl,
7
+ headers: {
8
+ "X-Redmine-API-Key": apiKey,
9
+ "Content-Type": "application/json",
10
+ },
11
+ });
12
+ export async function probeGet(path, params) {
13
+ try {
14
+ await redmine.get(path, { params });
15
+ return "ok";
16
+ }
17
+ catch (error) {
18
+ if (axios.isAxiosError(error) && error.response?.status === 403) {
19
+ return "forbidden";
20
+ }
21
+ return "error";
22
+ }
23
+ }
24
+ export async function probePut(path, body) {
25
+ try {
26
+ await redmine.put(path, body);
27
+ return "ok";
28
+ }
29
+ catch (error) {
30
+ if (axios.isAxiosError(error)) {
31
+ const status = error.response?.status;
32
+ if (status === 403) {
33
+ return "forbidden";
34
+ }
35
+ // Empty or unchanged body often returns 422 while still proving edit access
36
+ if (status === 422) {
37
+ return "ok";
38
+ }
39
+ }
40
+ return "error";
41
+ }
42
+ }
43
+ export async function getProjects() {
44
+ const response = await redmine.get("/projects.json");
45
+ return response.data;
46
+ }
47
+ export async function getCurrentUser() {
48
+ const response = await redmine.get("/users/current.json");
49
+ return response.data;
50
+ }
51
+ export async function getIssueById(issueId) {
52
+ const response = await redmine.get(`/issues/${issueId}.json`);
53
+ return response.data;
54
+ }
55
+ export async function getTimeEntryById(timeEntryId) {
56
+ const response = await redmine.get(`/time_entries/${timeEntryId}.json`);
57
+ return response.data;
58
+ }
59
+ export async function getIssues(params) {
60
+ const response = await redmine.get("/issues.json", {
61
+ params: {
62
+ ...(params.projectId
63
+ ? { project_id: params.projectId }
64
+ : {}),
65
+ ...(params.assignedToId
66
+ ? {
67
+ assigned_to_id: params.assignedToId === "me"
68
+ ? "me"
69
+ : params.assignedToId,
70
+ }
71
+ : {}),
72
+ ...(params.statusId ? { status_id: params.statusId } : {}),
73
+ limit: params.limit ?? 25,
74
+ offset: params.offset ?? 0,
75
+ sort: "updated_on:desc",
76
+ },
77
+ });
78
+ return response.data;
79
+ }
80
+ /** Time entries; pass userId to restrict to one user (required for operational logs). */
81
+ export async function getTimeEntries(params) {
82
+ const response = await redmine.get("/time_entries.json", {
83
+ params: {
84
+ project_id: params.projectId,
85
+ from: params.from,
86
+ to: params.to,
87
+ user_id: params.userId,
88
+ limit: params.limit ?? 100,
89
+ },
90
+ });
91
+ return response.data;
92
+ }
93
+ export async function getTimeEntriesForUser(params) {
94
+ const response = await redmine.get("/time_entries.json", {
95
+ params: {
96
+ user_id: params.userId,
97
+ limit: params.limit ?? 1,
98
+ },
99
+ });
100
+ return response.data;
101
+ }
102
+ export async function addIssueComment(issueId, notes) {
103
+ const response = await redmine.put(`/issues/${issueId}.json`, {
104
+ issue: { notes },
105
+ });
106
+ return response.data;
107
+ }
108
+ export async function logTimeEntry(params) {
109
+ const response = await redmine.post("/time_entries.json", {
110
+ time_entry: {
111
+ issue_id: params.issueId,
112
+ hours: params.hours,
113
+ activity_id: params.activityId,
114
+ spent_on: params.spentOn,
115
+ ...(params.comments !== undefined && params.comments !== ""
116
+ ? { comments: params.comments }
117
+ : {}),
118
+ custom_fields: [
119
+ {
120
+ id: params.billableHoursFieldId,
121
+ value: params.billableHours,
122
+ },
123
+ ],
124
+ },
125
+ });
126
+ return response.data;
127
+ }
128
+ export async function updateTimeEntryComment(timeEntryId, comments, entry) {
129
+ const response = await redmine.put(`/time_entries/${timeEntryId}.json`, {
130
+ time_entry: {
131
+ hours: entry.hours,
132
+ activity_id: entry.activity_id,
133
+ spent_on: entry.spent_on,
134
+ comments,
135
+ },
136
+ });
137
+ return response.data;
138
+ }
139
+ //# sourceMappingURL=redmine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redmine.js","sourceRoot":"","sources":["../../src/services/redmine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;AAEhD,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE;QACL,mBAAmB,EAAE,MAAM;QAC3B,cAAc,EAAE,kBAAkB;KACrC;CACJ,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC1B,IAAY,EACZ,MAAwC;IAExC,IAAI,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;YAC9D,OAAO,WAAW,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC1B,IAAY,EACZ,IAAa;IAEb,IAAI,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;YACtC,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACjB,OAAO,WAAW,CAAC;YACvB,CAAC;YACD,4EAA4E;YAC5E,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACjB,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC7B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAChC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAC1D,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe;IAC9C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,OAAO,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB;IACtD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,WAAW,OAAO,CAAC,CAAC;IACxE,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAM/B;IACG,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;QAC/C,MAAM,EAAE;YACJ,GAAG,CAAC,MAAM,CAAC,SAAS;gBAChB,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE;gBAClC,CAAC,CAAC,EAAE,CAAC;YACT,GAAG,CAAC,MAAM,CAAC,YAAY;gBACnB,CAAC,CAAC;oBACI,cAAc,EACV,MAAM,CAAC,YAAY,KAAK,IAAI;wBACxB,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,MAAM,CAAC,YAAY;iBAChC;gBACH,CAAC,CAAC,EAAE,CAAC;YACT,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC;YAC1B,IAAI,EAAE,iBAAiB;SAC1B;KACJ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAMpC;IACG,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE;QACrD,MAAM,EAAE;YACJ,UAAU,EAAE,MAAM,CAAC,SAAS;YAC5B,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,MAAM;YACtB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,GAAG;SAC7B;KACJ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAG3C;IACG,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE;QACrD,MAAM,EAAE;YACJ,OAAO,EAAE,MAAM,CAAC,MAAM;YACtB,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;SAC3B;KACJ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAe,EAAE,KAAa;IAChE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,OAAO,EAAE;QAC1D,KAAK,EAAE,EAAE,KAAK,EAAE;KACnB,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAQlC;IACG,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE;QACtD,UAAU,EAAE;YACR,QAAQ,EAAE,MAAM,CAAC,OAAO;YACxB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,WAAW,EAAE,MAAM,CAAC,UAAU;YAC9B,QAAQ,EAAE,MAAM,CAAC,OAAO;YACxB,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,EAAE;gBACvD,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE;gBAC/B,CAAC,CAAC,EAAE,CAAC;YACT,aAAa,EAAE;gBACX;oBACI,EAAE,EAAE,MAAM,CAAC,oBAAoB;oBAC/B,KAAK,EAAE,MAAM,CAAC,aAAa;iBAC9B;aACJ;SACJ;KACJ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CACxC,WAAmB,EACnB,QAAgB,EAChB,KAIC;IAED,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,WAAW,OAAO,EAAE;QACpE,UAAU,EAAE;YACR,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ;SACX;KACJ,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC;AACzB,CAAC"}