clokio-mcp 0.28.0 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tools/attendance.js +31 -8
- package/package.json +1 -1
package/dist/tools/attendance.js
CHANGED
|
@@ -54,12 +54,20 @@ export function entryClock(e, opts = {}) {
|
|
|
54
54
|
* The zone is the entry's `timezone` (local times) or UTC (an older server).
|
|
55
55
|
* `zone: false` drops a local entry's zone, for a page whose header names it once.
|
|
56
56
|
*/
|
|
57
|
+
/**
|
|
58
|
+
* What an entry is on, in words: its task, else its project (task #5775: an
|
|
59
|
+
* entry may be on a project with no task), else nothing. ONE copy for every
|
|
60
|
+
* line that names it (timeEntryLine, clokio_delete_time_entry), so they
|
|
61
|
+
* cannot drift (MCP QA 0.28.0).
|
|
62
|
+
*/
|
|
63
|
+
export function entryTarget(e) {
|
|
64
|
+
if (e?.task)
|
|
65
|
+
return `task #${e.task.id} ${e.task.title}`;
|
|
66
|
+
return e?.project?.name ? `no task, project ${e.project.name}` : 'no task';
|
|
67
|
+
}
|
|
57
68
|
export function timeEntryLine(e, opts = {}) {
|
|
58
69
|
const id = e?.id === undefined || e?.id === null ? '(no id: server older than 2026-10-16)' : `#${e.id}`;
|
|
59
|
-
|
|
60
|
-
const task = e?.task
|
|
61
|
-
? `task #${e.task.id} ${e.task.title}`
|
|
62
|
-
: e?.project?.name ? `no task, project ${e.project.name}` : 'no task';
|
|
70
|
+
const task = entryTarget(e);
|
|
63
71
|
return `${id} ${e?.date ?? '-'} ${entryClock(e, opts)} ${e?.work_hour ?? 0}h | ${e?.employee_code ?? '-'} | ${task} | ${e?.description ?? ''}`;
|
|
64
72
|
}
|
|
65
73
|
const ZONE_NOTE = "the person's CURRENT location zone, which clokio_update_time_entry reads date/start/end in (after a location change it may differ from where the entry was logged)";
|
|
@@ -211,6 +219,21 @@ export function withShortEntryWarning(res) {
|
|
|
211
219
|
return { ...res, warning };
|
|
212
220
|
}
|
|
213
221
|
/** #3: the line clokio_stop_timer adds when the stopped entry lasted under a minute, else null. */
|
|
222
|
+
/**
|
|
223
|
+
* clokio_start_timer's answer: the entry line, and when force: true stopped a
|
|
224
|
+
* running timer (the server's `stopped_entry`, backend 2026-10-21), a
|
|
225
|
+
* "Stopped first" line naming it and, for one under a minute, the same
|
|
226
|
+
* warning clokio_stop_timer gives (MCP QA 0.28.0). An older server sends no
|
|
227
|
+
* stopped_entry and the answer is as before.
|
|
228
|
+
*/
|
|
229
|
+
export function withStoppedFirst(res) {
|
|
230
|
+
const out = withEntryLine(res);
|
|
231
|
+
const stopped = res?.stopped_entry;
|
|
232
|
+
if (!stopped || typeof stopped !== 'object' || out === null || typeof out !== 'object' || Array.isArray(out))
|
|
233
|
+
return out;
|
|
234
|
+
const warning = shortEntryWarning(stopped);
|
|
235
|
+
return { ...out, stopped_first: `Stopped first: ${timeEntryLine(stopped)}`, ...(warning ? { warning } : {}) };
|
|
236
|
+
}
|
|
214
237
|
export function shortEntryWarning(entry) {
|
|
215
238
|
const a = Date.parse(entry?.check_in ?? '');
|
|
216
239
|
const b = Date.parse(entry?.check_out ?? '');
|
|
@@ -465,7 +488,8 @@ export function registerAttendanceTools(server, config) {
|
|
|
465
488
|
name: 'clokio_start_timer',
|
|
466
489
|
description: 'Start a running timer on a task, a project, or neither (a personal timer). ' + actingPerson + ' ' + targetRule + ' ' +
|
|
467
490
|
'If a timer is already running the call is refused (409) and the running entry is returned; ' +
|
|
468
|
-
'pass force: true to stop that timer and start this one
|
|
491
|
+
'pass force: true to stop that timer and start this one (the answer then names the stopped entry under stopped_first, ' +
|
|
492
|
+
'with a warning when it lasted under a minute). The description defaults to the task title (empty without a task). ' +
|
|
469
493
|
'clokio_stop_timer stops any timer; the web Timer page asks for a project and a description before its own Stop, ' +
|
|
470
494
|
'so give a personal timer a description (and stop it here) if the person may stop it on the web. ' +
|
|
471
495
|
ENTRY_LINE_NOTE,
|
|
@@ -479,7 +503,7 @@ export function registerAttendanceTools(server, config) {
|
|
|
479
503
|
mutates: true,
|
|
480
504
|
handler: async (args, cfg) => {
|
|
481
505
|
try {
|
|
482
|
-
return
|
|
506
|
+
return withStoppedFirst(await request(cfg, '/timer/start', {
|
|
483
507
|
method: 'POST',
|
|
484
508
|
body: { task_id: args.task_id, project_id: args.project_id, description: args.description, force: args.force },
|
|
485
509
|
}));
|
|
@@ -558,8 +582,7 @@ export function registerAttendanceTools(server, config) {
|
|
|
558
582
|
handler: async (args, cfg) => {
|
|
559
583
|
const res = await request(cfg, `/time-entries/${seg(args.id)}`, { method: 'DELETE' });
|
|
560
584
|
const e = res?.entry ?? {};
|
|
561
|
-
|
|
562
|
-
return `Deleted entry ${e.id ?? args.id}: ${e.date ?? '-'} ${entryClock(e)}, ${task}`;
|
|
585
|
+
return `Deleted entry ${e.id ?? args.id}: ${e.date ?? '-'} ${entryClock(e)}, ${entryTarget(e)}`;
|
|
563
586
|
},
|
|
564
587
|
});
|
|
565
588
|
registerTool(server, config, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clokio-mcp",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for Clokio - manage tasks, projects, clients, employees, attendance and documents from Claude and any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|