@codegame.dev/careerflow-mcp 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.
- package/LICENSE +21 -0
- package/README.md +398 -0
- package/dist/client.js +110 -0
- package/dist/client.js.map +1 -0
- package/dist/config.js +37 -0
- package/dist/config.js.map +1 -0
- package/dist/helpers.js +192 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.js +194 -0
- package/dist/index.js.map +1 -0
- package/dist/setup.js +296 -0
- package/dist/setup.js.map +1 -0
- package/dist/tools/admin.js +232 -0
- package/dist/tools/admin.js.map +1 -0
- package/dist/tools/benefit-funds.js +243 -0
- package/dist/tools/benefit-funds.js.map +1 -0
- package/dist/tools/chat-extra.js +172 -0
- package/dist/tools/chat-extra.js.map +1 -0
- package/dist/tools/chat.js +125 -0
- package/dist/tools/chat.js.map +1 -0
- package/dist/tools/cms.js +145 -0
- package/dist/tools/cms.js.map +1 -0
- package/dist/tools/crm-admin.js +269 -0
- package/dist/tools/crm-admin.js.map +1 -0
- package/dist/tools/crm.js +632 -0
- package/dist/tools/crm.js.map +1 -0
- package/dist/tools/dev-tickets.js +94 -0
- package/dist/tools/dev-tickets.js.map +1 -0
- package/dist/tools/forms.js +105 -0
- package/dist/tools/forms.js.map +1 -0
- package/dist/tools/hr.js +517 -0
- package/dist/tools/hr.js.map +1 -0
- package/dist/tools/kanban-extra.js +403 -0
- package/dist/tools/kanban-extra.js.map +1 -0
- package/dist/tools/misc.js +159 -0
- package/dist/tools/misc.js.map +1 -0
- package/dist/tools/projects.js +138 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/tasks.js +342 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/time.js +129 -0
- package/dist/tools/time.js.map +1 -0
- package/dist/tools/workplace.js +110 -0
- package/dist/tools/workplace.js.map +1 -0
- package/dist/tools/workspace.js +199 -0
- package/dist/tools/workspace.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { companyIdSchema, resolveCompanyId, safeHandler, textResult } from "../helpers.js";
|
|
3
|
+
/**
|
|
4
|
+
* Project administration tools: creating and configuring projects, and
|
|
5
|
+
* managing who belongs to them. Everyday task tools already resolve
|
|
6
|
+
* project/board ids via list_projects/list_boards — these are for changing the
|
|
7
|
+
* projects themselves.
|
|
8
|
+
*/
|
|
9
|
+
export function registerProjectTools(server, client) {
|
|
10
|
+
server.registerTool("create_project", {
|
|
11
|
+
title: "Create a project",
|
|
12
|
+
description: "Create a project. 'special' projects carry a due date and completion/late bonuses; " +
|
|
13
|
+
"'normal' projects don't.",
|
|
14
|
+
inputSchema: {
|
|
15
|
+
company_id: companyIdSchema,
|
|
16
|
+
name: z.string().min(1),
|
|
17
|
+
description: z.string().optional(),
|
|
18
|
+
type: z.enum(["normal", "special"]).optional().default("normal"),
|
|
19
|
+
due_date: z.string().optional().describe("Only meaningful for type 'special'."),
|
|
20
|
+
completion_bonus: z.number().optional(),
|
|
21
|
+
late_penalty: z.number().optional(),
|
|
22
|
+
priority: z.enum(["low", "medium", "high", "urgent"]).optional().default("medium"),
|
|
23
|
+
allow_editor_create_tasks: z.boolean().optional(),
|
|
24
|
+
is_manager: z.boolean().optional().describe("Add the caller as the project's manager immediately.")
|
|
25
|
+
}
|
|
26
|
+
}, safeHandler(async (args) => {
|
|
27
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
28
|
+
const response = await client.post("projects/create", {
|
|
29
|
+
company_id: companyId,
|
|
30
|
+
name: args.name,
|
|
31
|
+
description: args.description,
|
|
32
|
+
type: args.type,
|
|
33
|
+
due_date: args.due_date,
|
|
34
|
+
completion_bonus: args.completion_bonus,
|
|
35
|
+
late_penalty: args.late_penalty,
|
|
36
|
+
priority: args.priority,
|
|
37
|
+
allow_editor_create_tasks: args.allow_editor_create_tasks,
|
|
38
|
+
is_manager: args.is_manager
|
|
39
|
+
});
|
|
40
|
+
return textResult({ created: true, project: response.data });
|
|
41
|
+
}));
|
|
42
|
+
server.registerTool("update_project", {
|
|
43
|
+
title: "Update a project",
|
|
44
|
+
description: "Change a project's name, description, or (for 'special' projects) its due date and bonuses.",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
company_id: companyIdSchema,
|
|
47
|
+
project_id: z.number().int(),
|
|
48
|
+
name: z.string().min(1).optional(),
|
|
49
|
+
description: z.string().optional(),
|
|
50
|
+
due_date: z.string().optional(),
|
|
51
|
+
completion_bonus: z.number().optional(),
|
|
52
|
+
late_penalty: z.number().optional(),
|
|
53
|
+
priority: z.enum(["low", "medium", "high", "urgent"]).optional(),
|
|
54
|
+
allow_editor_create_tasks: z.boolean().optional()
|
|
55
|
+
}
|
|
56
|
+
}, safeHandler(async (args) => {
|
|
57
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
58
|
+
const response = await client.post("projects/edit", {
|
|
59
|
+
company_id: companyId,
|
|
60
|
+
id: args.project_id,
|
|
61
|
+
name: args.name,
|
|
62
|
+
description: args.description,
|
|
63
|
+
due_date: args.due_date,
|
|
64
|
+
completion_bonus: args.completion_bonus,
|
|
65
|
+
late_penalty: args.late_penalty,
|
|
66
|
+
priority: args.priority,
|
|
67
|
+
allow_editor_create_tasks: args.allow_editor_create_tasks
|
|
68
|
+
});
|
|
69
|
+
return textResult({ updated: true, project: response.data });
|
|
70
|
+
}));
|
|
71
|
+
server.registerTool("archive_project", {
|
|
72
|
+
title: "Archive or restore a project",
|
|
73
|
+
description: "Archive a project, or restore a previously archived one. Personal/inbox projects cannot be archived.",
|
|
74
|
+
inputSchema: {
|
|
75
|
+
company_id: companyIdSchema,
|
|
76
|
+
project_id: z.number().int(),
|
|
77
|
+
restore: z.boolean().optional().default(false)
|
|
78
|
+
}
|
|
79
|
+
}, safeHandler(async (args) => {
|
|
80
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
81
|
+
const path = args.restore ? `projects/restore/${args.project_id}` : `projects/delete/${args.project_id}`;
|
|
82
|
+
await client.post(path, { company_id: companyId });
|
|
83
|
+
return textResult({ project_id: args.project_id, archived: !args.restore });
|
|
84
|
+
}));
|
|
85
|
+
server.registerTool("project_stats", {
|
|
86
|
+
title: "Get project statistics",
|
|
87
|
+
description: "Task-count breakdowns for a project: by board, due date, member, label, and priority.",
|
|
88
|
+
inputSchema: { company_id: companyIdSchema, project_id: z.number().int() }
|
|
89
|
+
}, safeHandler(async (args) => {
|
|
90
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
91
|
+
const response = await client.get("projects/stats", {
|
|
92
|
+
company_id: companyId,
|
|
93
|
+
project_id: args.project_id
|
|
94
|
+
});
|
|
95
|
+
return textResult(response.data);
|
|
96
|
+
}));
|
|
97
|
+
server.registerTool("invite_project_member", {
|
|
98
|
+
title: "Invite or update a project member",
|
|
99
|
+
description: "Add a user to a project (or change their access level). Access levels: visitor (read-only), " +
|
|
100
|
+
"editor (can create/edit tasks), manager (full control). Omitting access removes the member.",
|
|
101
|
+
inputSchema: {
|
|
102
|
+
company_id: companyIdSchema,
|
|
103
|
+
project_id: z.number().int(),
|
|
104
|
+
user_id: z.number().int(),
|
|
105
|
+
access: z.enum(["visitor", "editor", "manager"]).optional().describe("Omit to remove the member."),
|
|
106
|
+
comment: z.string().optional()
|
|
107
|
+
}
|
|
108
|
+
}, safeHandler(async (args) => {
|
|
109
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
110
|
+
const response = await client.post("projects/users/edit", {
|
|
111
|
+
company_id: companyId,
|
|
112
|
+
project_id: args.project_id,
|
|
113
|
+
user_id: args.user_id,
|
|
114
|
+
request_type: "intra-company",
|
|
115
|
+
type: args.access,
|
|
116
|
+
comment: args.comment
|
|
117
|
+
});
|
|
118
|
+
return textResult({ project_id: args.project_id, user_id: args.user_id, project_users: response.data });
|
|
119
|
+
}));
|
|
120
|
+
server.registerTool("authorize_project_member", {
|
|
121
|
+
title: "Accept or reject a project membership request",
|
|
122
|
+
description: "Approve or deny a pending request to join a project.",
|
|
123
|
+
inputSchema: {
|
|
124
|
+
company_id: companyIdSchema,
|
|
125
|
+
project_user_id: z.number().int(),
|
|
126
|
+
status: z.enum(["accepted", "rejected"])
|
|
127
|
+
}
|
|
128
|
+
}, safeHandler(async (args) => {
|
|
129
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
130
|
+
const response = await client.post("projects/users/authorize", {
|
|
131
|
+
company_id: companyId,
|
|
132
|
+
project_user_id: args.project_user_id,
|
|
133
|
+
status: args.status
|
|
134
|
+
});
|
|
135
|
+
return textResult({ updated: true, project_user: response.data });
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { boolParam, companyIdSchema, extractList, currentUserId, fetchTask, mergeTaskEdit, resolveCompanyId, safeHandler, summariseTask, textResult } from "../helpers.js";
|
|
3
|
+
const prioritySchema = z.enum(["low", "medium", "high", "urgent"]);
|
|
4
|
+
/**
|
|
5
|
+
* Task tools — the day-to-day surface for staff and supervisors.
|
|
6
|
+
*
|
|
7
|
+
* Every write goes through the same REST endpoints the web app uses, so the
|
|
8
|
+
* caller's existing project role still decides what actually succeeds; these
|
|
9
|
+
* tools add no privilege of their own.
|
|
10
|
+
*/
|
|
11
|
+
export function registerTaskTools(server, client) {
|
|
12
|
+
server.registerTool("list_my_tasks", {
|
|
13
|
+
title: "List my tasks",
|
|
14
|
+
description: "List tasks assigned to the authenticated user. Use this for 'what am I working on', " +
|
|
15
|
+
"'what's due', or 'what's overdue'. Returns open tasks by default.",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
company_id: companyIdSchema,
|
|
18
|
+
project_id: z.number().int().optional().describe("Restrict to one project."),
|
|
19
|
+
is_completed: z
|
|
20
|
+
.boolean()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Filter by completion. Omit to return both open and completed tasks."),
|
|
23
|
+
is_overdue: z.boolean().optional().describe("Only tasks past their due date."),
|
|
24
|
+
search: z.string().optional().describe("Free-text match on the task title."),
|
|
25
|
+
limit: z.number().int().min(1).max(50).optional().default(20),
|
|
26
|
+
page: z.number().int().min(1).optional().default(1),
|
|
27
|
+
order_by: z.enum(["created", "updated", "num", "global_num"]).optional().default("updated"),
|
|
28
|
+
direction: z.enum(["asc", "desc"]).optional().default("desc")
|
|
29
|
+
}
|
|
30
|
+
}, safeHandler(async (args) => {
|
|
31
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
32
|
+
const myId = await currentUserId(client);
|
|
33
|
+
const response = await client.get("kanbans/tasks/search", {
|
|
34
|
+
company_id: companyId,
|
|
35
|
+
member_id: myId,
|
|
36
|
+
project_id: args.project_id,
|
|
37
|
+
is_completed: boolParam(args.is_completed),
|
|
38
|
+
is_overdue: boolParam(args.is_overdue),
|
|
39
|
+
search: args.search,
|
|
40
|
+
limit: args.limit,
|
|
41
|
+
page: args.page,
|
|
42
|
+
order_by: args.order_by,
|
|
43
|
+
direction: args.direction
|
|
44
|
+
});
|
|
45
|
+
const { items: tasks, total } = extractList(response.data, "tasks");
|
|
46
|
+
return textResult({ count: total ?? tasks.length, tasks: tasks.map(summariseTask) });
|
|
47
|
+
}));
|
|
48
|
+
server.registerTool("search_tasks", {
|
|
49
|
+
title: "Search tasks",
|
|
50
|
+
description: "Search tasks across a company or project, optionally filtered by assignee or supervisor. " +
|
|
51
|
+
"Supervisors use member_id to see one report's work, or supervisor_id to see a whole team's.",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
company_id: companyIdSchema,
|
|
54
|
+
project_id: z.number().int().optional(),
|
|
55
|
+
member_id: z.number().int().optional().describe("Only tasks assigned to this user id."),
|
|
56
|
+
supervisor_id: z
|
|
57
|
+
.number()
|
|
58
|
+
.int()
|
|
59
|
+
.optional()
|
|
60
|
+
.describe("Tasks belonging to everyone reporting to this supervisor id."),
|
|
61
|
+
search: z.string().optional(),
|
|
62
|
+
is_completed: z.boolean().optional(),
|
|
63
|
+
is_overdue: z.boolean().optional(),
|
|
64
|
+
review_status: z
|
|
65
|
+
.enum(["pending", "accepted"])
|
|
66
|
+
.optional()
|
|
67
|
+
.describe("Filter by review state; 'pending' finds work awaiting a supervisor's review."),
|
|
68
|
+
from_date: z.string().optional().describe("Lower date bound, YYYY-MM-DD."),
|
|
69
|
+
to_date: z.string().optional().describe("Upper date bound, YYYY-MM-DD."),
|
|
70
|
+
date_target: z
|
|
71
|
+
.enum(["created", "updated", "completion_date", "member_date"])
|
|
72
|
+
.optional()
|
|
73
|
+
.describe("Which date the from/to bounds apply to."),
|
|
74
|
+
limit: z.number().int().min(1).max(50).optional().default(20),
|
|
75
|
+
page: z.number().int().min(1).optional().default(1),
|
|
76
|
+
order_by: z.enum(["created", "updated", "num", "global_num"]).optional().default("updated"),
|
|
77
|
+
direction: z.enum(["asc", "desc"]).optional().default("desc")
|
|
78
|
+
}
|
|
79
|
+
}, safeHandler(async (args) => {
|
|
80
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
81
|
+
const response = await client.get("kanbans/tasks/search", {
|
|
82
|
+
company_id: companyId,
|
|
83
|
+
project_id: args.project_id,
|
|
84
|
+
member_id: args.member_id,
|
|
85
|
+
supervisor_id: args.supervisor_id,
|
|
86
|
+
search: args.search,
|
|
87
|
+
is_completed: boolParam(args.is_completed),
|
|
88
|
+
is_overdue: boolParam(args.is_overdue),
|
|
89
|
+
review_status: args.review_status,
|
|
90
|
+
from_date: args.from_date,
|
|
91
|
+
to_date: args.to_date,
|
|
92
|
+
date_target: args.date_target,
|
|
93
|
+
limit: args.limit,
|
|
94
|
+
page: args.page,
|
|
95
|
+
order_by: args.order_by,
|
|
96
|
+
direction: args.direction
|
|
97
|
+
});
|
|
98
|
+
const { items: tasks, total } = extractList(response.data, "tasks");
|
|
99
|
+
return textResult({ count: total ?? tasks.length, tasks: tasks.map(summariseTask) });
|
|
100
|
+
}));
|
|
101
|
+
server.registerTool("get_task", {
|
|
102
|
+
title: "Get a task",
|
|
103
|
+
description: "Fetch one task in full by its id, including members, labels and checklists.",
|
|
104
|
+
inputSchema: {
|
|
105
|
+
company_id: companyIdSchema,
|
|
106
|
+
task_id: z.number().int().describe("The task id.")
|
|
107
|
+
}
|
|
108
|
+
}, safeHandler(async (args) => {
|
|
109
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
110
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
111
|
+
return textResult(summariseTask(task));
|
|
112
|
+
}));
|
|
113
|
+
server.registerTool("create_task", {
|
|
114
|
+
title: "Create a task",
|
|
115
|
+
description: "Create a task on a board. Requires the project and board ids — use list_projects and " +
|
|
116
|
+
"list_boards first when they are not already known.",
|
|
117
|
+
inputSchema: {
|
|
118
|
+
company_id: companyIdSchema,
|
|
119
|
+
project_id: z.number().int(),
|
|
120
|
+
board_id: z.number().int().describe("The board (column) the task is created in."),
|
|
121
|
+
title: z.string().min(1),
|
|
122
|
+
description: z.string().optional(),
|
|
123
|
+
assigned_user_id: z
|
|
124
|
+
.number()
|
|
125
|
+
.int()
|
|
126
|
+
.optional()
|
|
127
|
+
.describe("User to assign. Must already be an accepted member of the project."),
|
|
128
|
+
priority: prioritySchema.optional().default("medium"),
|
|
129
|
+
start_date: z.string().optional().describe("YYYY-MM-DD HH:MM:SS"),
|
|
130
|
+
due_date: z.string().optional().describe("YYYY-MM-DD HH:MM:SS"),
|
|
131
|
+
time_estimate_minutes: z.number().int().min(0).max(3600).optional()
|
|
132
|
+
}
|
|
133
|
+
}, safeHandler(async (args) => {
|
|
134
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
135
|
+
const response = await client.post("kanbans/tasks/create", {
|
|
136
|
+
company_id: companyId,
|
|
137
|
+
project_id: args.project_id,
|
|
138
|
+
board_id: args.board_id,
|
|
139
|
+
title: args.title,
|
|
140
|
+
description: args.description,
|
|
141
|
+
assigned_user_id: args.assigned_user_id,
|
|
142
|
+
priority: args.priority,
|
|
143
|
+
start_date: args.start_date,
|
|
144
|
+
due_date: args.due_date,
|
|
145
|
+
time_estimate_minutes: args.time_estimate_minutes
|
|
146
|
+
});
|
|
147
|
+
const task = response.data?.task;
|
|
148
|
+
return textResult({
|
|
149
|
+
created: true,
|
|
150
|
+
task: task ? summariseTask(task) : undefined
|
|
151
|
+
});
|
|
152
|
+
}));
|
|
153
|
+
server.registerTool("update_task", {
|
|
154
|
+
title: "Update a task",
|
|
155
|
+
description: "Change fields on an existing task. Only the fields passed are altered — the task is read " +
|
|
156
|
+
"first and unmentioned fields keep their current values.",
|
|
157
|
+
inputSchema: {
|
|
158
|
+
company_id: companyIdSchema,
|
|
159
|
+
task_id: z.number().int(),
|
|
160
|
+
title: z.string().min(1).optional(),
|
|
161
|
+
description: z.string().optional(),
|
|
162
|
+
priority: prioritySchema.optional(),
|
|
163
|
+
start_date: z.string().nullable().optional().describe("YYYY-MM-DD HH:MM:SS, or null to clear."),
|
|
164
|
+
due_date: z.string().nullable().optional().describe("YYYY-MM-DD HH:MM:SS, or null to clear."),
|
|
165
|
+
time_estimate_minutes: z.number().int().min(0).nullable().optional()
|
|
166
|
+
}
|
|
167
|
+
}, safeHandler(async (args) => {
|
|
168
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
169
|
+
const current = await fetchTask(client, companyId, args.task_id);
|
|
170
|
+
const body = mergeTaskEdit(current, companyId, {
|
|
171
|
+
title: args.title,
|
|
172
|
+
description: args.description,
|
|
173
|
+
priority: args.priority,
|
|
174
|
+
start_date: args.start_date,
|
|
175
|
+
due_date: args.due_date,
|
|
176
|
+
time_estimate_minutes: args.time_estimate_minutes
|
|
177
|
+
});
|
|
178
|
+
const response = await client.post("kanbans/tasks/edit", body);
|
|
179
|
+
const task = response.data?.task;
|
|
180
|
+
return textResult({ updated: true, task: task ? summariseTask(task) : undefined });
|
|
181
|
+
}));
|
|
182
|
+
server.registerTool("complete_task", {
|
|
183
|
+
title: "Complete or reopen a task",
|
|
184
|
+
description: "Mark a task complete, or reopen it with completed=false. Other fields are preserved.",
|
|
185
|
+
inputSchema: {
|
|
186
|
+
company_id: companyIdSchema,
|
|
187
|
+
task_id: z.number().int(),
|
|
188
|
+
completed: z.boolean().optional().default(true)
|
|
189
|
+
}
|
|
190
|
+
}, safeHandler(async (args) => {
|
|
191
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
192
|
+
const current = await fetchTask(client, companyId, args.task_id);
|
|
193
|
+
const body = mergeTaskEdit(current, companyId, {
|
|
194
|
+
is_completed: boolParam(args.completed ?? true)
|
|
195
|
+
});
|
|
196
|
+
await client.post("kanbans/tasks/edit", body);
|
|
197
|
+
return textResult({
|
|
198
|
+
task_id: args.task_id,
|
|
199
|
+
is_completed: args.completed ?? true,
|
|
200
|
+
title: current.title
|
|
201
|
+
});
|
|
202
|
+
}));
|
|
203
|
+
server.registerTool("assign_task", {
|
|
204
|
+
title: "Assign or unassign a task member",
|
|
205
|
+
description: "Add or remove a member on a task. The user must already be an accepted member of the " +
|
|
206
|
+
"task's project.",
|
|
207
|
+
inputSchema: {
|
|
208
|
+
company_id: companyIdSchema,
|
|
209
|
+
task_id: z.number().int(),
|
|
210
|
+
user_id: z.number().int().describe("The user to assign or unassign."),
|
|
211
|
+
assign: z.boolean().optional().default(true).describe("true adds the member, false removes them.")
|
|
212
|
+
}
|
|
213
|
+
}, safeHandler(async (args) => {
|
|
214
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
215
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
216
|
+
await client.post("kanbans/tasks/edit-member", {
|
|
217
|
+
company_id: companyId,
|
|
218
|
+
project_id: task.project_id,
|
|
219
|
+
board_id: task.board_id,
|
|
220
|
+
task_id: args.task_id,
|
|
221
|
+
user_id: args.user_id,
|
|
222
|
+
add: boolParam(args.assign ?? true)
|
|
223
|
+
});
|
|
224
|
+
return textResult({
|
|
225
|
+
task_id: args.task_id,
|
|
226
|
+
user_id: args.user_id,
|
|
227
|
+
assigned: args.assign ?? true
|
|
228
|
+
});
|
|
229
|
+
}));
|
|
230
|
+
server.registerTool("move_task", {
|
|
231
|
+
title: "Move a task to another board",
|
|
232
|
+
description: "Move a task to a different board (column), optionally in a different project — the usual " +
|
|
233
|
+
"way to advance work through a workflow.",
|
|
234
|
+
inputSchema: {
|
|
235
|
+
company_id: companyIdSchema,
|
|
236
|
+
task_id: z.number().int(),
|
|
237
|
+
destination_board_id: z.number().int(),
|
|
238
|
+
destination_project_id: z.number().int().optional().describe("Defaults to the task's current project.")
|
|
239
|
+
}
|
|
240
|
+
}, safeHandler(async (args) => {
|
|
241
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
242
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
243
|
+
await client.post("kanbans/tasks/move", {
|
|
244
|
+
company_id: companyId,
|
|
245
|
+
source_project_id: task.project_id,
|
|
246
|
+
source_board_id: task.board_id,
|
|
247
|
+
task_id: args.task_id,
|
|
248
|
+
destination_project_id: args.destination_project_id ?? task.project_id,
|
|
249
|
+
destination_board_id: args.destination_board_id,
|
|
250
|
+
// appended to the end of the destination board; the API renumbers
|
|
251
|
+
// the column afterwards, so a large sentinel is the documented way
|
|
252
|
+
// to say "put it last" without reading the board's current order
|
|
253
|
+
destination_num: 999999,
|
|
254
|
+
destination_global_num: 999999
|
|
255
|
+
});
|
|
256
|
+
return textResult({
|
|
257
|
+
task_id: args.task_id,
|
|
258
|
+
moved_to_board: args.destination_board_id,
|
|
259
|
+
title: task.title
|
|
260
|
+
});
|
|
261
|
+
}));
|
|
262
|
+
server.registerTool("review_task", {
|
|
263
|
+
title: "Review a task",
|
|
264
|
+
description: "Supervisor action: accept a completed task and score it 0-5, or send it back by setting " +
|
|
265
|
+
"review_status to 'pending'.",
|
|
266
|
+
inputSchema: {
|
|
267
|
+
company_id: companyIdSchema,
|
|
268
|
+
task_id: z.number().int(),
|
|
269
|
+
review_status: z.enum(["pending", "accepted"]),
|
|
270
|
+
review_score: z.number().min(0).max(5).describe("Score from 0 to 5.")
|
|
271
|
+
}
|
|
272
|
+
}, safeHandler(async (args) => {
|
|
273
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
274
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
275
|
+
await client.post("kanbans/tasks/review", {
|
|
276
|
+
company_id: companyId,
|
|
277
|
+
project_id: task.project_id,
|
|
278
|
+
board_id: task.board_id,
|
|
279
|
+
task_id: args.task_id,
|
|
280
|
+
review_status: args.review_status,
|
|
281
|
+
review_score: args.review_score
|
|
282
|
+
});
|
|
283
|
+
return textResult({
|
|
284
|
+
task_id: args.task_id,
|
|
285
|
+
review_status: args.review_status,
|
|
286
|
+
review_score: args.review_score
|
|
287
|
+
});
|
|
288
|
+
}));
|
|
289
|
+
server.registerTool("list_task_comments", {
|
|
290
|
+
title: "List task comments",
|
|
291
|
+
description: "Read the comment thread on a task.",
|
|
292
|
+
inputSchema: {
|
|
293
|
+
company_id: companyIdSchema,
|
|
294
|
+
task_id: z.number().int(),
|
|
295
|
+
limit: z.number().int().min(1).max(50).optional().default(20),
|
|
296
|
+
page: z.number().int().min(1).optional().default(1)
|
|
297
|
+
}
|
|
298
|
+
}, safeHandler(async (args) => {
|
|
299
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
300
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
301
|
+
const response = await client.get("kanbans/tasks/comments/search", {
|
|
302
|
+
company_id: companyId,
|
|
303
|
+
project_id: task.project_id,
|
|
304
|
+
board_id: task.board_id,
|
|
305
|
+
task_id: args.task_id,
|
|
306
|
+
limit: args.limit,
|
|
307
|
+
page: args.page
|
|
308
|
+
});
|
|
309
|
+
const { items: comments, total } = extractList(response.data, "task_comments");
|
|
310
|
+
return textResult({
|
|
311
|
+
count: total ?? comments.length,
|
|
312
|
+
comments: comments.map((c) => ({
|
|
313
|
+
id: c.id,
|
|
314
|
+
content: c.content,
|
|
315
|
+
user_id: c.user_id,
|
|
316
|
+
author: [c.firstname, c.lastname].filter(Boolean).join(" ") || undefined,
|
|
317
|
+
created: c.created
|
|
318
|
+
}))
|
|
319
|
+
});
|
|
320
|
+
}));
|
|
321
|
+
server.registerTool("add_task_comment", {
|
|
322
|
+
title: "Comment on a task",
|
|
323
|
+
description: "Post a comment to a task's thread.",
|
|
324
|
+
inputSchema: {
|
|
325
|
+
company_id: companyIdSchema,
|
|
326
|
+
task_id: z.number().int(),
|
|
327
|
+
content: z.string().min(1).describe("The comment body.")
|
|
328
|
+
}
|
|
329
|
+
}, safeHandler(async (args) => {
|
|
330
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
331
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
332
|
+
await client.post("kanbans/tasks/comments/add", {
|
|
333
|
+
company_id: companyId,
|
|
334
|
+
project_id: task.project_id,
|
|
335
|
+
board_id: task.board_id,
|
|
336
|
+
task_id: args.task_id,
|
|
337
|
+
content: args.content
|
|
338
|
+
});
|
|
339
|
+
return textResult({ task_id: args.task_id, commented: true });
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { companyIdSchema, currentUserId, extractList, fetchTask, resolveCompanyId, safeHandler, textResult } from "../helpers.js";
|
|
3
|
+
const userIdSchema = z.number().int().optional().describe("Whose time this is. Defaults to the authenticated user.");
|
|
4
|
+
/** The API expects local-time "YYYY-MM-DD HH:MM:SS", not an ISO-8601 string. */
|
|
5
|
+
function formatApiDate(date) {
|
|
6
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
7
|
+
return (`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` +
|
|
8
|
+
`${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Time-tracking tools.
|
|
12
|
+
*
|
|
13
|
+
* Timers and manual entries both belong to the calling user; the API takes the
|
|
14
|
+
* user from the token, so none of these tools accept a user id.
|
|
15
|
+
*/
|
|
16
|
+
export function registerTimeTools(server, client) {
|
|
17
|
+
server.registerTool("start_timer", {
|
|
18
|
+
title: "Start a task timer",
|
|
19
|
+
description: "Start tracking time against a task for the authenticated user.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
company_id: companyIdSchema,
|
|
22
|
+
task_id: z.number().int(),
|
|
23
|
+
user_id: userIdSchema
|
|
24
|
+
}
|
|
25
|
+
}, safeHandler(async (args) => {
|
|
26
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
27
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
28
|
+
await client.post("kanbans/tasks/times/start-timer", {
|
|
29
|
+
company_id: companyId,
|
|
30
|
+
project_id: task.project_id,
|
|
31
|
+
board_id: task.board_id,
|
|
32
|
+
task_id: args.task_id,
|
|
33
|
+
user_id: args.user_id ?? (await currentUserId(client))
|
|
34
|
+
});
|
|
35
|
+
return textResult({ task_id: args.task_id, title: task.title, timer: "started" });
|
|
36
|
+
}));
|
|
37
|
+
server.registerTool("stop_timer", {
|
|
38
|
+
title: "Stop a task timer",
|
|
39
|
+
description: "Stop the running timer on a task and record the elapsed time.",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
company_id: companyIdSchema,
|
|
42
|
+
task_id: z.number().int(),
|
|
43
|
+
user_id: userIdSchema
|
|
44
|
+
}
|
|
45
|
+
}, safeHandler(async (args) => {
|
|
46
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
47
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
48
|
+
await client.post("kanbans/tasks/times/stop-timer", {
|
|
49
|
+
company_id: companyId,
|
|
50
|
+
project_id: task.project_id,
|
|
51
|
+
board_id: task.board_id,
|
|
52
|
+
task_id: args.task_id,
|
|
53
|
+
user_id: args.user_id ?? (await currentUserId(client))
|
|
54
|
+
});
|
|
55
|
+
return textResult({ task_id: args.task_id, title: task.title, timer: "stopped" });
|
|
56
|
+
}));
|
|
57
|
+
server.registerTool("log_time", {
|
|
58
|
+
title: "Log time on a task",
|
|
59
|
+
description: "Record a block of time already spent on a task, for work done away from a running timer.",
|
|
60
|
+
inputSchema: {
|
|
61
|
+
company_id: companyIdSchema,
|
|
62
|
+
task_id: z.number().int(),
|
|
63
|
+
duration_minutes: z.number().int().min(1).describe("Minutes spent."),
|
|
64
|
+
date: z.string().optional().describe("When the work happened, YYYY-MM-DD HH:MM:SS. Defaults to now."),
|
|
65
|
+
comment: z.string().optional().describe("What the time was spent on."),
|
|
66
|
+
user_id: userIdSchema
|
|
67
|
+
}
|
|
68
|
+
}, safeHandler(async (args) => {
|
|
69
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
70
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
71
|
+
await client.post("kanbans/tasks/times/add", {
|
|
72
|
+
company_id: companyId,
|
|
73
|
+
project_id: task.project_id,
|
|
74
|
+
board_id: task.board_id,
|
|
75
|
+
task_id: args.task_id,
|
|
76
|
+
user_id: args.user_id ?? (await currentUserId(client)),
|
|
77
|
+
duration_minutes: args.duration_minutes,
|
|
78
|
+
// the endpoint requires a date; "when it happened" defaults to now so
|
|
79
|
+
// a caller logging time they just spent does not have to supply one
|
|
80
|
+
date: args.date ?? formatApiDate(new Date()),
|
|
81
|
+
comment: args.comment
|
|
82
|
+
});
|
|
83
|
+
return textResult({
|
|
84
|
+
task_id: args.task_id,
|
|
85
|
+
title: task.title,
|
|
86
|
+
logged_minutes: args.duration_minutes
|
|
87
|
+
});
|
|
88
|
+
}));
|
|
89
|
+
server.registerTool("list_task_time", {
|
|
90
|
+
title: "List time entries on a task",
|
|
91
|
+
description: "Show the time entries recorded against a task, and who logged them.",
|
|
92
|
+
inputSchema: {
|
|
93
|
+
company_id: companyIdSchema,
|
|
94
|
+
task_id: z.number().int(),
|
|
95
|
+
from_date: z.string().optional().describe("Lower bound, YYYY-MM-DD."),
|
|
96
|
+
to_date: z.string().optional().describe("Upper bound, YYYY-MM-DD."),
|
|
97
|
+
limit: z.number().int().min(1).max(50).optional().default(25),
|
|
98
|
+
page: z.number().int().min(1).optional().default(1)
|
|
99
|
+
}
|
|
100
|
+
}, safeHandler(async (args) => {
|
|
101
|
+
const companyId = resolveCompanyId(client, args.company_id);
|
|
102
|
+
const task = await fetchTask(client, companyId, args.task_id);
|
|
103
|
+
const response = await client.get("kanbans/tasks/times/search", {
|
|
104
|
+
company_id: companyId,
|
|
105
|
+
project_id: task.project_id,
|
|
106
|
+
board_id: task.board_id,
|
|
107
|
+
task_id: args.task_id,
|
|
108
|
+
from_date: args.from_date,
|
|
109
|
+
to_date: args.to_date,
|
|
110
|
+
limit: args.limit,
|
|
111
|
+
page: args.page
|
|
112
|
+
});
|
|
113
|
+
const { items: times, total } = extractList(response.data, "task_times");
|
|
114
|
+
return textResult({
|
|
115
|
+
count: total ?? times.length,
|
|
116
|
+
total_minutes: times.reduce((sum, t) => sum + (Number(t.duration_minutes) || 0), 0),
|
|
117
|
+
entries: times.map((t) => ({
|
|
118
|
+
id: t.id,
|
|
119
|
+
user_id: t.user_id,
|
|
120
|
+
user: [t.firstname, t.lastname].filter(Boolean).join(" ") || undefined,
|
|
121
|
+
duration_minutes: t.duration_minutes,
|
|
122
|
+
date: t.date,
|
|
123
|
+
comment: t.comment || undefined,
|
|
124
|
+
status: t.status || undefined
|
|
125
|
+
}))
|
|
126
|
+
});
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=time.js.map
|