@studiometa/productive-mcp 0.6.4 → 0.8.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 (57) hide show
  1. package/dist/errors.d.ts +41 -0
  2. package/dist/errors.d.ts.map +1 -0
  3. package/dist/handlers/bookings.d.ts +1 -1
  4. package/dist/handlers/bookings.d.ts.map +1 -1
  5. package/dist/handlers/comments.d.ts +1 -1
  6. package/dist/handlers/comments.d.ts.map +1 -1
  7. package/dist/handlers/companies.d.ts +1 -1
  8. package/dist/handlers/companies.d.ts.map +1 -1
  9. package/dist/handlers/deals.d.ts +1 -1
  10. package/dist/handlers/deals.d.ts.map +1 -1
  11. package/dist/handlers/help.d.ts +13 -0
  12. package/dist/handlers/help.d.ts.map +1 -0
  13. package/dist/handlers/index.d.ts.map +1 -1
  14. package/dist/handlers/people.d.ts +1 -1
  15. package/dist/handlers/people.d.ts.map +1 -1
  16. package/dist/handlers/projects.d.ts +1 -1
  17. package/dist/handlers/projects.d.ts.map +1 -1
  18. package/dist/handlers/reports.d.ts +21 -0
  19. package/dist/handlers/reports.d.ts.map +1 -0
  20. package/dist/handlers/services.d.ts +1 -1
  21. package/dist/handlers/services.d.ts.map +1 -1
  22. package/dist/handlers/tasks.d.ts.map +1 -1
  23. package/dist/handlers/time.d.ts +1 -1
  24. package/dist/handlers/time.d.ts.map +1 -1
  25. package/dist/handlers/timers.d.ts.map +1 -1
  26. package/dist/handlers/types.d.ts +1 -0
  27. package/dist/handlers/types.d.ts.map +1 -1
  28. package/dist/handlers/utils.d.ts +12 -1
  29. package/dist/handlers/utils.d.ts.map +1 -1
  30. package/dist/handlers.js +1 -1
  31. package/dist/http.d.ts +1 -0
  32. package/dist/http.d.ts.map +1 -1
  33. package/dist/http.js +4 -3
  34. package/dist/http.js.map +1 -1
  35. package/dist/index-D743zTS1.js +1177 -0
  36. package/dist/index-D743zTS1.js.map +1 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +3 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/instructions.d.ts +11 -0
  41. package/dist/instructions.d.ts.map +1 -0
  42. package/dist/schema.d.ts +218 -0
  43. package/dist/schema.d.ts.map +1 -0
  44. package/dist/server.js +1 -1
  45. package/dist/stdio.js +1 -1
  46. package/dist/tools.d.ts +6 -0
  47. package/dist/tools.d.ts.map +1 -1
  48. package/dist/tools.js +61 -5
  49. package/dist/tools.js.map +1 -1
  50. package/dist/version-i2-GF6d1.js +21 -0
  51. package/dist/version-i2-GF6d1.js.map +1 -0
  52. package/package.json +13 -3
  53. package/skills/SKILL.md +330 -0
  54. package/dist/index-CmTDkz-y.js +0 -480
  55. package/dist/index-CmTDkz-y.js.map +0 -1
  56. package/dist/version-BRw90xAB.js +0 -5
  57. package/dist/version-BRw90xAB.js.map +0 -1
@@ -1,480 +0,0 @@
1
- import { formatBooking as formatBooking$1, formatListResponse as formatListResponse$1, formatDeal as formatDeal$1, formatTimer as formatTimer$1, formatComment as formatComment$1, formatCompany as formatCompany$1, formatPerson as formatPerson$1, formatService as formatService$1, formatTask as formatTask$1, formatTimeEntry as formatTimeEntry$1, formatProject as formatProject$1, ProductiveApi } from "@studiometa/productive-cli";
2
- const MCP_FORMAT_OPTIONS = {
3
- includeRelationshipIds: false,
4
- includeTimestamps: false,
5
- stripHtml: true
6
- };
7
- function compactify(obj, fieldsToRemove) {
8
- const result = { ...obj };
9
- for (const field of fieldsToRemove) {
10
- delete result[field];
11
- }
12
- return result;
13
- }
14
- function formatTimeEntry(entry, options) {
15
- const result = formatTimeEntry$1(entry, MCP_FORMAT_OPTIONS);
16
- if (options?.compact) {
17
- return compactify(result, ["note", "billable_time", "approved"]);
18
- }
19
- return result;
20
- }
21
- function formatProject(project, options) {
22
- const result = formatProject$1(project, MCP_FORMAT_OPTIONS);
23
- if (options?.compact) {
24
- return compactify(result, ["budget"]);
25
- }
26
- return result;
27
- }
28
- function formatTask(task, options) {
29
- const result = formatTask$1(task, { ...MCP_FORMAT_OPTIONS, included: options?.included });
30
- if (options?.compact) {
31
- return compactify(result, [
32
- "description",
33
- "initial_estimate",
34
- "worked_time",
35
- "remaining_time",
36
- "project",
37
- // Keep project_name but remove nested object
38
- "company"
39
- // Keep company name inline if needed
40
- ]);
41
- }
42
- return result;
43
- }
44
- function formatPerson(person, options) {
45
- const result = formatPerson$1(person, MCP_FORMAT_OPTIONS);
46
- if (options?.compact) {
47
- return compactify(result, ["title", "first_name", "last_name"]);
48
- }
49
- return result;
50
- }
51
- function formatService(service, options) {
52
- const result = formatService$1(service, MCP_FORMAT_OPTIONS);
53
- if (options?.compact) {
54
- return compactify(result, ["budgeted_time", "worked_time"]);
55
- }
56
- return result;
57
- }
58
- function formatCompany(company, options) {
59
- const result = formatCompany$1(company, MCP_FORMAT_OPTIONS);
60
- if (options?.compact) {
61
- return compactify(result, ["billing_name", "domain", "due_days"]);
62
- }
63
- return result;
64
- }
65
- function formatComment(comment, options) {
66
- const result = formatComment$1(comment, { ...MCP_FORMAT_OPTIONS, included: options?.included });
67
- return result;
68
- }
69
- function formatTimer(timer, _options) {
70
- const result = formatTimer$1(timer, MCP_FORMAT_OPTIONS);
71
- return result;
72
- }
73
- function formatDeal(deal, options) {
74
- const result = formatDeal$1(deal, { ...MCP_FORMAT_OPTIONS, included: options?.included });
75
- if (options?.compact) {
76
- return compactify(result, ["won_at", "lost_at"]);
77
- }
78
- return result;
79
- }
80
- function formatBooking(booking, options) {
81
- const result = formatBooking$1(booking, { ...MCP_FORMAT_OPTIONS, included: options?.included });
82
- if (options?.compact) {
83
- return compactify(result, ["approved_at", "rejected_at", "rejected_reason"]);
84
- }
85
- return result;
86
- }
87
- function formatListResponse(data, formatter, meta, options) {
88
- const wrappedFormatter = (item, _cliOptions) => {
89
- return formatter(item, options);
90
- };
91
- const result = formatListResponse$1(data, wrappedFormatter, meta, {
92
- ...MCP_FORMAT_OPTIONS,
93
- included: options?.included
94
- });
95
- return result;
96
- }
97
- function jsonResult(data) {
98
- return {
99
- content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
100
- };
101
- }
102
- function errorResult(message) {
103
- return {
104
- content: [{ type: "text", text: `Error: ${message}` }],
105
- isError: true
106
- };
107
- }
108
- function toStringFilter(filter) {
109
- if (!filter) return void 0;
110
- const result = {};
111
- for (const [key, value] of Object.entries(filter)) {
112
- if (value !== void 0 && value !== null) {
113
- result[key] = String(value);
114
- }
115
- }
116
- return Object.keys(result).length > 0 ? result : void 0;
117
- }
118
- async function handleBookings(action, args, ctx) {
119
- const { api, formatOptions, filter, page, perPage } = ctx;
120
- const { id, person_id, service_id, event_id, started_on, ended_on, time, note } = args;
121
- if (action === "get") {
122
- if (!id) return errorResult("id is required for get action");
123
- const result = await api.getBooking(id, { include: ["person", "service"] });
124
- return jsonResult(formatBooking(result.data, { ...formatOptions, included: result.included }));
125
- }
126
- if (action === "create") {
127
- if (!person_id || !started_on || !ended_on) {
128
- return errorResult("person_id, started_on, and ended_on are required for create");
129
- }
130
- if (!service_id && !event_id) {
131
- return errorResult("service_id or event_id is required for create");
132
- }
133
- const result = await api.createBooking({
134
- person_id,
135
- service_id,
136
- event_id,
137
- started_on,
138
- ended_on,
139
- time,
140
- note
141
- });
142
- return jsonResult({ success: true, ...formatBooking(result.data, formatOptions) });
143
- }
144
- if (action === "update") {
145
- if (!id) return errorResult("id is required for update action");
146
- const updateData = {};
147
- if (started_on !== void 0) updateData.started_on = started_on;
148
- if (ended_on !== void 0) updateData.ended_on = ended_on;
149
- if (time !== void 0) updateData.time = time;
150
- if (note !== void 0) updateData.note = note;
151
- const result = await api.updateBooking(id, updateData);
152
- return jsonResult({ success: true, ...formatBooking(result.data, formatOptions) });
153
- }
154
- if (action === "list") {
155
- const result = await api.getBookings({ filter, page, perPage, include: ["person", "service"] });
156
- return jsonResult(
157
- formatListResponse(result.data, formatBooking, result.meta, {
158
- ...formatOptions,
159
- included: result.included
160
- })
161
- );
162
- }
163
- return errorResult(`Invalid action "${action}" for bookings. Use: list, get, create, update`);
164
- }
165
- async function handleComments(action, args, ctx) {
166
- const { api, formatOptions, filter, page, perPage } = ctx;
167
- const { id, body, task_id, deal_id, company_id } = args;
168
- if (action === "get") {
169
- if (!id) return errorResult("id is required for get action");
170
- const result = await api.getComment(id, { include: ["creator"] });
171
- return jsonResult(formatComment(result.data, { ...formatOptions, included: result.included }));
172
- }
173
- if (action === "create") {
174
- if (!body) return errorResult("body is required for create");
175
- if (!task_id && !deal_id && !company_id) {
176
- return errorResult("task_id, deal_id, or company_id is required for create");
177
- }
178
- const result = await api.createComment({
179
- body,
180
- task_id,
181
- deal_id,
182
- company_id
183
- });
184
- return jsonResult({ success: true, ...formatComment(result.data, formatOptions) });
185
- }
186
- if (action === "update") {
187
- if (!id) return errorResult("id is required for update action");
188
- if (!body) return errorResult("body is required for update");
189
- const result = await api.updateComment(id, { body });
190
- return jsonResult({ success: true, ...formatComment(result.data, formatOptions) });
191
- }
192
- if (action === "list") {
193
- const result = await api.getComments({ filter, page, perPage, include: ["creator"] });
194
- return jsonResult(
195
- formatListResponse(result.data, formatComment, result.meta, {
196
- ...formatOptions,
197
- included: result.included
198
- })
199
- );
200
- }
201
- return errorResult(`Invalid action "${action}" for comments. Use: list, get, create, update`);
202
- }
203
- async function handleCompanies(action, args, ctx) {
204
- const { api, formatOptions, filter, page, perPage } = ctx;
205
- const { id, name } = args;
206
- if (action === "get") {
207
- if (!id) return errorResult("id is required for get action");
208
- const result = await api.getCompany(id);
209
- return jsonResult(formatCompany(result.data, formatOptions));
210
- }
211
- if (action === "create") {
212
- if (!name) return errorResult("name is required for create");
213
- const result = await api.createCompany({ name });
214
- return jsonResult({ success: true, ...formatCompany(result.data, formatOptions) });
215
- }
216
- if (action === "update") {
217
- if (!id) return errorResult("id is required for update action");
218
- const updateData = {};
219
- if (name !== void 0) updateData.name = name;
220
- const result = await api.updateCompany(id, updateData);
221
- return jsonResult({ success: true, ...formatCompany(result.data, formatOptions) });
222
- }
223
- if (action === "list") {
224
- const result = await api.getCompanies({ filter, page, perPage });
225
- return jsonResult(formatListResponse(result.data, formatCompany, result.meta, formatOptions));
226
- }
227
- return errorResult(`Invalid action "${action}" for companies. Use: list, get, create, update`);
228
- }
229
- async function handleDeals(action, args, ctx) {
230
- const { api, formatOptions, filter, page, perPage } = ctx;
231
- const { id, name, company_id } = args;
232
- if (action === "get") {
233
- if (!id) return errorResult("id is required for get action");
234
- const result = await api.getDeal(id, { include: ["company", "deal_status", "responsible"] });
235
- return jsonResult(formatDeal(result.data, { ...formatOptions, included: result.included }));
236
- }
237
- if (action === "create") {
238
- if (!name || !company_id) {
239
- return errorResult("name and company_id are required for create");
240
- }
241
- const result = await api.createDeal({ name, company_id });
242
- return jsonResult({ success: true, ...formatDeal(result.data, formatOptions) });
243
- }
244
- if (action === "update") {
245
- if (!id) return errorResult("id is required for update action");
246
- const updateData = {};
247
- if (name !== void 0) updateData.name = name;
248
- const result = await api.updateDeal(id, updateData);
249
- return jsonResult({ success: true, ...formatDeal(result.data, formatOptions) });
250
- }
251
- if (action === "list") {
252
- const result = await api.getDeals({
253
- filter,
254
- page,
255
- perPage,
256
- include: ["company", "deal_status"]
257
- });
258
- return jsonResult(
259
- formatListResponse(result.data, formatDeal, result.meta, {
260
- ...formatOptions,
261
- included: result.included
262
- })
263
- );
264
- }
265
- return errorResult(`Invalid action "${action}" for deals. Use: list, get, create, update`);
266
- }
267
- async function handlePeople(action, args, ctx, credentials) {
268
- const { api, formatOptions, filter, page, perPage } = ctx;
269
- const { id } = args;
270
- if (action === "get") {
271
- if (!id) return errorResult("id is required for get action");
272
- const result = await api.getPerson(id);
273
- return jsonResult(formatPerson(result.data, formatOptions));
274
- }
275
- if (action === "me") {
276
- if (credentials.userId) {
277
- const result = await api.getPerson(credentials.userId);
278
- return jsonResult(formatPerson(result.data, formatOptions));
279
- }
280
- return jsonResult({
281
- message: "User ID not configured. Set userId in credentials to use this action.",
282
- organizationId: credentials.organizationId
283
- });
284
- }
285
- if (action === "list") {
286
- const result = await api.getPeople({ filter, page, perPage });
287
- return jsonResult(formatListResponse(result.data, formatPerson, result.meta, formatOptions));
288
- }
289
- return errorResult(`Invalid action "${action}" for people. Use: list, get, me`);
290
- }
291
- async function handleProjects(action, args, ctx) {
292
- const { api, formatOptions, filter, page, perPage } = ctx;
293
- const { id } = args;
294
- if (action === "get") {
295
- if (!id) return errorResult("id is required for get action");
296
- const result = await api.getProject(id);
297
- return jsonResult(formatProject(result.data, formatOptions));
298
- }
299
- if (action === "list") {
300
- const result = await api.getProjects({ filter, page, perPage });
301
- return jsonResult(formatListResponse(result.data, formatProject, result.meta, formatOptions));
302
- }
303
- return errorResult(`Invalid action "${action}" for projects. Use: list, get`);
304
- }
305
- async function handleServices(action, _args, ctx) {
306
- const { api, formatOptions, filter, page, perPage } = ctx;
307
- if (action === "list") {
308
- const result = await api.getServices({ filter, page, perPage });
309
- return jsonResult(formatListResponse(result.data, formatService, result.meta, formatOptions));
310
- }
311
- return errorResult(`Invalid action "${action}" for services. Use: list`);
312
- }
313
- async function handleTasks(action, args, ctx) {
314
- const { api, formatOptions, filter, page, perPage } = ctx;
315
- const { id, title, project_id, task_list_id, description, assignee_id } = args;
316
- const include = ["project", "project.company"];
317
- if (action === "get") {
318
- if (!id) return errorResult("id is required for get action");
319
- const result = await api.getTask(id, { include });
320
- return jsonResult(formatTask(result.data, { ...formatOptions, included: result.included }));
321
- }
322
- if (action === "create") {
323
- if (!title || !project_id || !task_list_id) {
324
- return errorResult("title, project_id, and task_list_id are required for create");
325
- }
326
- const result = await api.createTask({
327
- title,
328
- project_id,
329
- task_list_id,
330
- assignee_id,
331
- description
332
- });
333
- return jsonResult({ success: true, ...formatTask(result.data, formatOptions) });
334
- }
335
- if (action === "update") {
336
- if (!id) return errorResult("id is required for update action");
337
- const updateData = {};
338
- if (title !== void 0) updateData.title = title;
339
- if (description !== void 0) updateData.description = description;
340
- if (assignee_id !== void 0) updateData.assignee_id = assignee_id;
341
- const result = await api.updateTask(id, updateData);
342
- return jsonResult({ success: true, ...formatTask(result.data, formatOptions) });
343
- }
344
- if (action === "list") {
345
- const result = await api.getTasks({ filter, page, perPage, include });
346
- return jsonResult(
347
- formatListResponse(result.data, formatTask, result.meta, {
348
- ...formatOptions,
349
- included: result.included
350
- })
351
- );
352
- }
353
- return errorResult(`Invalid action "${action}" for tasks. Use: list, get, create, update`);
354
- }
355
- async function handleTime(action, args, ctx) {
356
- const { api, formatOptions, filter, page, perPage } = ctx;
357
- const { id, person_id, service_id, task_id, time, date, note } = args;
358
- if (action === "get") {
359
- if (!id) return errorResult("id is required for get action");
360
- const result = await api.getTimeEntry(id);
361
- return jsonResult(formatTimeEntry(result.data, formatOptions));
362
- }
363
- if (action === "create") {
364
- if (!person_id || !service_id || !time || !date) {
365
- return errorResult("person_id, service_id, time, and date are required for create");
366
- }
367
- const result = await api.createTimeEntry({
368
- person_id,
369
- service_id,
370
- time,
371
- date,
372
- note,
373
- task_id
374
- });
375
- return jsonResult({ success: true, ...formatTimeEntry(result.data, formatOptions) });
376
- }
377
- if (action === "update") {
378
- if (!id) return errorResult("id is required for update action");
379
- const updateData = {};
380
- if (time !== void 0) updateData.time = time;
381
- if (date !== void 0) updateData.date = date;
382
- if (note !== void 0) updateData.note = note;
383
- const result = await api.updateTimeEntry(id, updateData);
384
- return jsonResult({ success: true, ...formatTimeEntry(result.data, formatOptions) });
385
- }
386
- if (action === "list") {
387
- const result = await api.getTimeEntries({ filter, page, perPage });
388
- return jsonResult(formatListResponse(result.data, formatTimeEntry, result.meta, formatOptions));
389
- }
390
- return errorResult(`Invalid action "${action}" for time. Use: list, get, create, update`);
391
- }
392
- async function handleTimers(action, args, ctx) {
393
- const { api, formatOptions, filter, page, perPage } = ctx;
394
- const { id, service_id, time_entry_id } = args;
395
- if (action === "get") {
396
- if (!id) return errorResult("id is required for get action");
397
- const result = await api.getTimer(id);
398
- return jsonResult(formatTimer(result.data));
399
- }
400
- if (action === "start" || action === "create") {
401
- if (!service_id && !time_entry_id) {
402
- return errorResult("service_id or time_entry_id is required to start a timer");
403
- }
404
- const result = await api.startTimer({ service_id, time_entry_id });
405
- return jsonResult({ success: true, ...formatTimer(result.data) });
406
- }
407
- if (action === "stop") {
408
- if (!id) return errorResult("id is required to stop a timer");
409
- const result = await api.stopTimer(id);
410
- return jsonResult({ success: true, ...formatTimer(result.data) });
411
- }
412
- if (action === "list") {
413
- const result = await api.getTimers({ filter, page, perPage });
414
- return jsonResult(formatListResponse(result.data, formatTimer, result.meta, formatOptions));
415
- }
416
- return errorResult(`Invalid action "${action}" for timers. Use: list, get, start, stop`);
417
- }
418
- const DEFAULT_PER_PAGE = 20;
419
- async function executeToolWithCredentials(name, args, credentials) {
420
- const api = new ProductiveApi({
421
- token: credentials.apiToken,
422
- "org-id": credentials.organizationId,
423
- "user-id": credentials.userId
424
- });
425
- if (name !== "productive") {
426
- return errorResult(`Unknown tool: ${name}`);
427
- }
428
- const {
429
- resource,
430
- action,
431
- filter,
432
- page,
433
- per_page,
434
- compact = true,
435
- ...restArgs
436
- } = args;
437
- const formatOptions = { compact };
438
- const stringFilter = toStringFilter(filter);
439
- const perPage = per_page ?? DEFAULT_PER_PAGE;
440
- const ctx = {
441
- api,
442
- formatOptions,
443
- filter: stringFilter,
444
- page,
445
- perPage
446
- };
447
- try {
448
- switch (resource) {
449
- case "projects":
450
- return await handleProjects(action, restArgs, ctx);
451
- case "time":
452
- return await handleTime(action, restArgs, ctx);
453
- case "tasks":
454
- return await handleTasks(action, restArgs, ctx);
455
- case "services":
456
- return await handleServices(action, restArgs, ctx);
457
- case "people":
458
- return await handlePeople(action, restArgs, ctx, credentials);
459
- case "companies":
460
- return await handleCompanies(action, restArgs, ctx);
461
- case "comments":
462
- return await handleComments(action, restArgs, ctx);
463
- case "timers":
464
- return await handleTimers(action, restArgs, ctx);
465
- case "deals":
466
- return await handleDeals(action, restArgs, ctx);
467
- case "bookings":
468
- return await handleBookings(action, restArgs, ctx);
469
- default:
470
- return errorResult(`Unknown resource: ${resource}`);
471
- }
472
- } catch (error) {
473
- const message = error instanceof Error ? error.message : String(error);
474
- return errorResult(message);
475
- }
476
- }
477
- export {
478
- executeToolWithCredentials as e
479
- };
480
- //# sourceMappingURL=index-CmTDkz-y.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CmTDkz-y.js","sources":["../src/formatters.ts","../src/handlers/utils.ts","../src/handlers/bookings.ts","../src/handlers/comments.ts","../src/handlers/companies.ts","../src/handlers/deals.ts","../src/handlers/people.ts","../src/handlers/projects.ts","../src/handlers/services.ts","../src/handlers/tasks.ts","../src/handlers/time.ts","../src/handlers/timers.ts","../src/handlers/index.ts"],"sourcesContent":["/**\n * Response formatters for agent-friendly output\n *\n * This module re-exports formatters from @studiometa/productive-cli\n * with MCP-specific defaults (no relationship IDs, no timestamps).\n *\n * Supports compact mode to reduce token usage by omitting verbose fields\n * like descriptions and notes from list responses.\n */\n\nimport {\n formatTimeEntry as cliFormatTimeEntry,\n formatProject as cliFormatProject,\n formatTask as cliFormatTask,\n formatPerson as cliFormatPerson,\n formatService as cliFormatService,\n formatCompany as cliFormatCompany,\n formatComment as cliFormatComment,\n formatTimer as cliFormatTimer,\n formatDeal as cliFormatDeal,\n formatBooking as cliFormatBooking,\n formatListResponse as cliFormatListResponse,\n type JsonApiResource,\n type JsonApiMeta,\n type FormatOptions,\n type FormattedPagination,\n} from '@studiometa/productive-cli';\n\n// Re-export types\nexport type { JsonApiResource, JsonApiMeta, FormatOptions, FormattedPagination };\n\n/**\n * MCP-specific format options\n * - No relationship IDs (cleaner output for agents)\n * - No timestamps (reduce noise)\n * - HTML stripping enabled\n */\nconst MCP_FORMAT_OPTIONS: FormatOptions = {\n includeRelationshipIds: false,\n includeTimestamps: false,\n stripHtml: true,\n};\n\n/**\n * Extended format options for MCP with compact mode\n */\nexport interface McpFormatOptions {\n compact?: boolean;\n included?: JsonApiResource[];\n}\n\n/**\n * Remove verbose fields from an object for compact output\n */\nfunction compactify<T extends Record<string, unknown>>(obj: T, fieldsToRemove: string[]): T {\n const result = { ...obj };\n for (const field of fieldsToRemove) {\n delete result[field];\n }\n return result;\n}\n\n/**\n * Format time entry for agent consumption\n */\nexport function formatTimeEntry(\n entry: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatTimeEntry(entry, MCP_FORMAT_OPTIONS);\n if (options?.compact) {\n return compactify(result, ['note', 'billable_time', 'approved']);\n }\n return result;\n}\n\n/**\n * Format project for agent consumption\n */\nexport function formatProject(\n project: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatProject(project, MCP_FORMAT_OPTIONS);\n if (options?.compact) {\n return compactify(result, ['budget']);\n }\n return result;\n}\n\n/**\n * Format task for agent consumption\n * Tasks use included resources to resolve project/company names\n */\nexport function formatTask(\n task: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatTask(task, { ...MCP_FORMAT_OPTIONS, included: options?.included });\n if (options?.compact) {\n return compactify(result, [\n 'description',\n 'initial_estimate',\n 'worked_time',\n 'remaining_time',\n 'project', // Keep project_name but remove nested object\n 'company', // Keep company name inline if needed\n ]);\n }\n return result;\n}\n\n/**\n * Format person for agent consumption\n */\nexport function formatPerson(\n person: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatPerson(person, MCP_FORMAT_OPTIONS);\n if (options?.compact) {\n return compactify(result, ['title', 'first_name', 'last_name']); // Keep 'name' which combines them\n }\n return result;\n}\n\n/**\n * Format service for agent consumption\n */\nexport function formatService(\n service: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatService(service, MCP_FORMAT_OPTIONS);\n if (options?.compact) {\n return compactify(result, ['budgeted_time', 'worked_time']);\n }\n return result;\n}\n\n/**\n * Format company for agent consumption\n */\nexport function formatCompany(\n company: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatCompany(company, MCP_FORMAT_OPTIONS);\n if (options?.compact) {\n return compactify(result, ['billing_name', 'domain', 'due_days']);\n }\n return result;\n}\n\n/**\n * Format comment for agent consumption\n */\nexport function formatComment(\n comment: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatComment(comment, { ...MCP_FORMAT_OPTIONS, included: options?.included });\n return result;\n}\n\n/**\n * Format timer for agent consumption\n */\nexport function formatTimer(\n timer: JsonApiResource,\n _options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatTimer(timer, MCP_FORMAT_OPTIONS);\n return result;\n}\n\n/**\n * Format deal for agent consumption\n */\nexport function formatDeal(\n deal: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatDeal(deal, { ...MCP_FORMAT_OPTIONS, included: options?.included });\n if (options?.compact) {\n return compactify(result, ['won_at', 'lost_at']);\n }\n return result;\n}\n\n/**\n * Format booking for agent consumption\n */\nexport function formatBooking(\n booking: JsonApiResource,\n options?: McpFormatOptions,\n): Record<string, unknown> {\n const result = cliFormatBooking(booking, { ...MCP_FORMAT_OPTIONS, included: options?.included });\n if (options?.compact) {\n return compactify(result, ['approved_at', 'rejected_at', 'rejected_reason']);\n }\n return result;\n}\n\n/**\n * Format list response with pagination\n *\n * @param data - Array of JSON:API resources\n * @param formatter - Formatter function (item, options?) => T\n * @param meta - Pagination metadata\n * @param options - MCP format options (compact, included)\n */\nexport function formatListResponse<T>(\n data: JsonApiResource[],\n formatter: (item: JsonApiResource, options?: McpFormatOptions) => T,\n meta?: JsonApiMeta,\n options?: McpFormatOptions,\n): { data: T[]; meta?: FormattedPagination } {\n // Create a wrapper that passes MCP options to the formatter\n const wrappedFormatter = (item: JsonApiResource, _cliOptions?: FormatOptions) => {\n return formatter(item, options);\n };\n\n const result = cliFormatListResponse(data, wrappedFormatter, meta, {\n ...MCP_FORMAT_OPTIONS,\n included: options?.included,\n });\n\n return result as { data: T[]; meta?: FormattedPagination };\n}\n","/**\n * Utility functions for resource handlers\n */\n\nimport type { ToolResult } from './types.js';\n\n/**\n * Helper to create a successful JSON response\n */\nexport function jsonResult(data: unknown): ToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n}\n\n/**\n * Helper to create an error response\n */\nexport function errorResult(message: string): ToolResult {\n return {\n content: [{ type: 'text', text: `Error: ${message}` }],\n isError: true,\n };\n}\n\n/**\n * Convert unknown filter to string filter for API\n */\nexport function toStringFilter(\n filter?: Record<string, unknown>,\n): Record<string, string> | undefined {\n if (!filter) return undefined;\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(filter)) {\n if (value !== undefined && value !== null) {\n result[key] = String(value);\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n","/**\n * Bookings resource handler\n */\n\nimport type { HandlerContext, BookingArgs, ToolResult } from './types.js';\n\nimport { formatBooking, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleBookings(\n action: string,\n args: BookingArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, person_id, service_id, event_id, started_on, ended_on, time, note } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getBooking(id, { include: ['person', 'service'] });\n return jsonResult(formatBooking(result.data, { ...formatOptions, included: result.included }));\n }\n\n if (action === 'create') {\n if (!person_id || !started_on || !ended_on) {\n return errorResult('person_id, started_on, and ended_on are required for create');\n }\n if (!service_id && !event_id) {\n return errorResult('service_id or event_id is required for create');\n }\n const result = await api.createBooking({\n person_id,\n service_id,\n event_id,\n started_on,\n ended_on,\n time,\n note,\n });\n return jsonResult({ success: true, ...formatBooking(result.data, formatOptions) });\n }\n\n if (action === 'update') {\n if (!id) return errorResult('id is required for update action');\n const updateData: Parameters<typeof api.updateBooking>[1] = {};\n if (started_on !== undefined) updateData.started_on = started_on;\n if (ended_on !== undefined) updateData.ended_on = ended_on;\n if (time !== undefined) updateData.time = time;\n if (note !== undefined) updateData.note = note;\n const result = await api.updateBooking(id, updateData);\n return jsonResult({ success: true, ...formatBooking(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getBookings({ filter, page, perPage, include: ['person', 'service'] });\n return jsonResult(\n formatListResponse(result.data, formatBooking, result.meta, {\n ...formatOptions,\n included: result.included,\n }),\n );\n }\n\n return errorResult(`Invalid action \"${action}\" for bookings. Use: list, get, create, update`);\n}\n","/**\n * Comments resource handler\n */\n\nimport type { HandlerContext, CommentArgs, ToolResult } from './types.js';\n\nimport { formatComment, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleComments(\n action: string,\n args: CommentArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, body, task_id, deal_id, company_id } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getComment(id, { include: ['creator'] });\n return jsonResult(formatComment(result.data, { ...formatOptions, included: result.included }));\n }\n\n if (action === 'create') {\n if (!body) return errorResult('body is required for create');\n if (!task_id && !deal_id && !company_id) {\n return errorResult('task_id, deal_id, or company_id is required for create');\n }\n const result = await api.createComment({\n body,\n task_id,\n deal_id,\n company_id,\n });\n return jsonResult({ success: true, ...formatComment(result.data, formatOptions) });\n }\n\n if (action === 'update') {\n if (!id) return errorResult('id is required for update action');\n if (!body) return errorResult('body is required for update');\n const result = await api.updateComment(id, { body });\n return jsonResult({ success: true, ...formatComment(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getComments({ filter, page, perPage, include: ['creator'] });\n return jsonResult(\n formatListResponse(result.data, formatComment, result.meta, {\n ...formatOptions,\n included: result.included,\n }),\n );\n }\n\n return errorResult(`Invalid action \"${action}\" for comments. Use: list, get, create, update`);\n}\n","/**\n * Companies resource handler\n */\n\nimport type { HandlerContext, CompanyArgs, ToolResult } from './types.js';\n\nimport { formatCompany, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleCompanies(\n action: string,\n args: CompanyArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, name } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getCompany(id);\n return jsonResult(formatCompany(result.data, formatOptions));\n }\n\n if (action === 'create') {\n if (!name) return errorResult('name is required for create');\n const result = await api.createCompany({ name });\n return jsonResult({ success: true, ...formatCompany(result.data, formatOptions) });\n }\n\n if (action === 'update') {\n if (!id) return errorResult('id is required for update action');\n const updateData: Parameters<typeof api.updateCompany>[1] = {};\n if (name !== undefined) updateData.name = name;\n const result = await api.updateCompany(id, updateData);\n return jsonResult({ success: true, ...formatCompany(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getCompanies({ filter, page, perPage });\n return jsonResult(formatListResponse(result.data, formatCompany, result.meta, formatOptions));\n }\n\n return errorResult(`Invalid action \"${action}\" for companies. Use: list, get, create, update`);\n}\n","/**\n * Deals resource handler\n */\n\nimport type { HandlerContext, DealArgs, ToolResult } from './types.js';\n\nimport { formatDeal, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleDeals(\n action: string,\n args: DealArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, name, company_id } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getDeal(id, { include: ['company', 'deal_status', 'responsible'] });\n return jsonResult(formatDeal(result.data, { ...formatOptions, included: result.included }));\n }\n\n if (action === 'create') {\n if (!name || !company_id) {\n return errorResult('name and company_id are required for create');\n }\n const result = await api.createDeal({ name, company_id });\n return jsonResult({ success: true, ...formatDeal(result.data, formatOptions) });\n }\n\n if (action === 'update') {\n if (!id) return errorResult('id is required for update action');\n const updateData: Parameters<typeof api.updateDeal>[1] = {};\n if (name !== undefined) updateData.name = name;\n const result = await api.updateDeal(id, updateData);\n return jsonResult({ success: true, ...formatDeal(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getDeals({\n filter,\n page,\n perPage,\n include: ['company', 'deal_status'],\n });\n return jsonResult(\n formatListResponse(result.data, formatDeal, result.meta, {\n ...formatOptions,\n included: result.included,\n }),\n );\n }\n\n return errorResult(`Invalid action \"${action}\" for deals. Use: list, get, create, update`);\n}\n","/**\n * People resource handler\n */\n\nimport type { ProductiveCredentials } from '../auth.js';\nimport type { HandlerContext, CommonArgs, ToolResult } from './types.js';\n\nimport { formatPerson, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handlePeople(\n action: string,\n args: CommonArgs,\n ctx: HandlerContext,\n credentials: ProductiveCredentials,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getPerson(id);\n return jsonResult(formatPerson(result.data, formatOptions));\n }\n\n if (action === 'me') {\n if (credentials.userId) {\n const result = await api.getPerson(credentials.userId);\n return jsonResult(formatPerson(result.data, formatOptions));\n }\n return jsonResult({\n message: 'User ID not configured. Set userId in credentials to use this action.',\n organizationId: credentials.organizationId,\n });\n }\n\n if (action === 'list') {\n const result = await api.getPeople({ filter, page, perPage });\n return jsonResult(formatListResponse(result.data, formatPerson, result.meta, formatOptions));\n }\n\n return errorResult(`Invalid action \"${action}\" for people. Use: list, get, me`);\n}\n","/**\n * Projects resource handler\n */\n\nimport type { HandlerContext, CommonArgs, ToolResult } from './types.js';\n\nimport { formatProject, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleProjects(\n action: string,\n args: CommonArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getProject(id);\n return jsonResult(formatProject(result.data, formatOptions));\n }\n\n if (action === 'list') {\n const result = await api.getProjects({ filter, page, perPage });\n return jsonResult(formatListResponse(result.data, formatProject, result.meta, formatOptions));\n }\n\n return errorResult(`Invalid action \"${action}\" for projects. Use: list, get`);\n}\n","/**\n * Services resource handler\n */\n\nimport type { HandlerContext, CommonArgs, ToolResult } from './types.js';\n\nimport { formatService, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleServices(\n action: string,\n _args: CommonArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n\n if (action === 'list') {\n const result = await api.getServices({ filter, page, perPage });\n return jsonResult(formatListResponse(result.data, formatService, result.meta, formatOptions));\n }\n\n return errorResult(`Invalid action \"${action}\" for services. Use: list`);\n}\n","/**\n * Tasks resource handler\n */\n\nimport type { HandlerContext, TaskArgs, ToolResult } from './types.js';\n\nimport { formatTask, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleTasks(\n action: string,\n args: TaskArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, title, project_id, task_list_id, description, assignee_id } = args;\n const include = ['project', 'project.company'];\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getTask(id, { include });\n return jsonResult(formatTask(result.data, { ...formatOptions, included: result.included }));\n }\n\n if (action === 'create') {\n if (!title || !project_id || !task_list_id) {\n return errorResult('title, project_id, and task_list_id are required for create');\n }\n const result = await api.createTask({\n title,\n project_id,\n task_list_id,\n assignee_id,\n description,\n });\n return jsonResult({ success: true, ...formatTask(result.data, formatOptions) });\n }\n\n if (action === 'update') {\n if (!id) return errorResult('id is required for update action');\n const updateData: Parameters<typeof api.updateTask>[1] = {};\n if (title !== undefined) updateData.title = title;\n if (description !== undefined) updateData.description = description;\n if (assignee_id !== undefined) updateData.assignee_id = assignee_id;\n const result = await api.updateTask(id, updateData);\n return jsonResult({ success: true, ...formatTask(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getTasks({ filter, page, perPage, include });\n return jsonResult(\n formatListResponse(result.data, formatTask, result.meta, {\n ...formatOptions,\n included: result.included,\n }),\n );\n }\n\n return errorResult(`Invalid action \"${action}\" for tasks. Use: list, get, create, update`);\n}\n","/**\n * Time entries resource handler\n */\n\nimport type { HandlerContext, CommonArgs, ToolResult } from './types.js';\n\nimport { formatTimeEntry, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleTime(\n action: string,\n args: CommonArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, person_id, service_id, task_id, time, date, note } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getTimeEntry(id);\n return jsonResult(formatTimeEntry(result.data, formatOptions));\n }\n\n if (action === 'create') {\n if (!person_id || !service_id || !time || !date) {\n return errorResult('person_id, service_id, time, and date are required for create');\n }\n const result = await api.createTimeEntry({\n person_id,\n service_id,\n time,\n date,\n note,\n task_id,\n });\n return jsonResult({ success: true, ...formatTimeEntry(result.data, formatOptions) });\n }\n\n if (action === 'update') {\n if (!id) return errorResult('id is required for update action');\n const updateData: Parameters<typeof api.updateTimeEntry>[1] = {};\n if (time !== undefined) updateData.time = time;\n if (date !== undefined) updateData.date = date;\n if (note !== undefined) updateData.note = note;\n const result = await api.updateTimeEntry(id, updateData);\n return jsonResult({ success: true, ...formatTimeEntry(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getTimeEntries({ filter, page, perPage });\n return jsonResult(formatListResponse(result.data, formatTimeEntry, result.meta, formatOptions));\n }\n\n return errorResult(`Invalid action \"${action}\" for time. Use: list, get, create, update`);\n}\n","/**\n * Timers resource handler\n */\n\nimport type { HandlerContext, TimerArgs, ToolResult } from './types.js';\n\nimport { formatTimer, formatListResponse } from '../formatters.js';\nimport { jsonResult, errorResult } from './utils.js';\n\nexport async function handleTimers(\n action: string,\n args: TimerArgs,\n ctx: HandlerContext,\n): Promise<ToolResult> {\n const { api, formatOptions, filter, page, perPage } = ctx;\n const { id, service_id, time_entry_id } = args;\n\n if (action === 'get') {\n if (!id) return errorResult('id is required for get action');\n const result = await api.getTimer(id);\n return jsonResult(formatTimer(result.data, formatOptions));\n }\n\n if (action === 'start' || action === 'create') {\n if (!service_id && !time_entry_id) {\n return errorResult('service_id or time_entry_id is required to start a timer');\n }\n const result = await api.startTimer({ service_id, time_entry_id });\n return jsonResult({ success: true, ...formatTimer(result.data, formatOptions) });\n }\n\n if (action === 'stop') {\n if (!id) return errorResult('id is required to stop a timer');\n const result = await api.stopTimer(id);\n return jsonResult({ success: true, ...formatTimer(result.data, formatOptions) });\n }\n\n if (action === 'list') {\n const result = await api.getTimers({ filter, page, perPage });\n return jsonResult(formatListResponse(result.data, formatTimer, result.meta, formatOptions));\n }\n\n return errorResult(`Invalid action \"${action}\" for timers. Use: list, get, start, stop`);\n}\n","/**\n * Tool execution handlers for Productive MCP server\n * These are shared between stdio and HTTP transports\n *\n * Single consolidated tool for minimal token overhead:\n * - productive: resource + action based API\n */\n\nimport { ProductiveApi } from '@studiometa/productive-cli';\n\nimport type { ProductiveCredentials } from '../auth.js';\nimport type { McpFormatOptions } from '../formatters.js';\nimport type { ToolResult, HandlerContext } from './types.js';\n\nimport { handleBookings } from './bookings.js';\nimport { handleComments } from './comments.js';\nimport { handleCompanies } from './companies.js';\nimport { handleDeals } from './deals.js';\nimport { handlePeople } from './people.js';\n// Resource handlers\nimport { handleProjects } from './projects.js';\nimport { handleServices } from './services.js';\nimport { handleTasks } from './tasks.js';\nimport { handleTime } from './time.js';\nimport { handleTimers } from './timers.js';\nimport { toStringFilter, errorResult } from './utils.js';\n\n// Re-export types\nexport type { ToolResult } from './types.js';\n\n/** Default page size for MCP (smaller than CLI to reduce token usage) */\nconst DEFAULT_PER_PAGE = 20;\n\n/**\n * Args interface for the consolidated tool\n */\ninterface ProductiveArgs {\n resource: string;\n action: string;\n id?: string;\n filter?: Record<string, unknown>;\n page?: number;\n per_page?: number;\n compact?: boolean;\n // Common fields\n person_id?: string;\n service_id?: string;\n task_id?: string;\n company_id?: string;\n time?: number;\n date?: string;\n note?: string;\n // Task fields\n title?: string;\n project_id?: string;\n task_list_id?: string;\n description?: string;\n assignee_id?: string;\n // Company fields\n name?: string;\n // Comment fields\n body?: string;\n deal_id?: string;\n // Timer fields\n time_entry_id?: string;\n // Booking fields\n started_on?: string;\n ended_on?: string;\n event_id?: string;\n}\n\n/**\n * Execute a tool with the given credentials and arguments\n */\nexport async function executeToolWithCredentials(\n name: string,\n args: Record<string, unknown>,\n credentials: ProductiveCredentials,\n): Promise<ToolResult> {\n // Initialize API client with provided credentials\n const api = new ProductiveApi({\n token: credentials.apiToken,\n 'org-id': credentials.organizationId,\n 'user-id': credentials.userId,\n } as Record<string, string>);\n\n // Handle the single consolidated tool\n if (name !== 'productive') {\n return errorResult(`Unknown tool: ${name}`);\n }\n\n const {\n resource,\n action,\n filter,\n page,\n per_page,\n compact = true,\n ...restArgs\n } = args as unknown as ProductiveArgs;\n\n const formatOptions: McpFormatOptions = { compact };\n const stringFilter = toStringFilter(filter);\n const perPage = per_page ?? DEFAULT_PER_PAGE;\n\n // Build handler context\n const ctx: HandlerContext = {\n api,\n formatOptions,\n filter: stringFilter,\n page,\n perPage,\n };\n\n try {\n // Route to appropriate resource handler\n switch (resource) {\n case 'projects':\n return await handleProjects(action, restArgs, ctx);\n\n case 'time':\n return await handleTime(action, restArgs, ctx);\n\n case 'tasks':\n return await handleTasks(action, restArgs, ctx);\n\n case 'services':\n return await handleServices(action, restArgs, ctx);\n\n case 'people':\n return await handlePeople(action, restArgs, ctx, credentials);\n\n case 'companies':\n return await handleCompanies(action, restArgs, ctx);\n\n case 'comments':\n return await handleComments(action, restArgs, ctx);\n\n case 'timers':\n return await handleTimers(action, restArgs, ctx);\n\n case 'deals':\n return await handleDeals(action, restArgs, ctx);\n\n case 'bookings':\n return await handleBookings(action, restArgs, ctx);\n\n default:\n return errorResult(`Unknown resource: ${resource}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return errorResult(message);\n }\n}\n"],"names":["cliFormatTimeEntry","cliFormatProject","cliFormatTask","cliFormatPerson","cliFormatService","cliFormatCompany","cliFormatComment","cliFormatTimer","cliFormatDeal","cliFormatBooking","cliFormatListResponse"],"mappings":";AAqCA,MAAM,qBAAoC;AAAA,EACxC,wBAAwB;AAAA,EACxB,mBAAmB;AAAA,EACnB,WAAW;AACb;AAaA,SAAS,WAA8C,KAAQ,gBAA6B;AAC1F,QAAM,SAAS,EAAE,GAAG,IAAA;AACpB,aAAW,SAAS,gBAAgB;AAClC,WAAO,OAAO,KAAK;AAAA,EACrB;AACA,SAAO;AACT;AAKO,SAAS,gBACd,OACA,SACyB;AACzB,QAAM,SAASA,kBAAmB,OAAO,kBAAkB;AAC3D,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,QAAQ,iBAAiB,UAAU,CAAC;AAAA,EACjE;AACA,SAAO;AACT;AAKO,SAAS,cACd,SACA,SACyB;AACzB,QAAM,SAASC,gBAAiB,SAAS,kBAAkB;AAC3D,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,QAAQ,CAAC;AAAA,EACtC;AACA,SAAO;AACT;AAMO,SAAS,WACd,MACA,SACyB;AACzB,QAAM,SAASC,aAAc,MAAM,EAAE,GAAG,oBAAoB,UAAU,SAAS,UAAU;AACzF,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,IAAA,CACD;AAAA,EACH;AACA,SAAO;AACT;AAKO,SAAS,aACd,QACA,SACyB;AACzB,QAAM,SAASC,eAAgB,QAAQ,kBAAkB;AACzD,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,SAAS,cAAc,WAAW,CAAC;AAAA,EAChE;AACA,SAAO;AACT;AAKO,SAAS,cACd,SACA,SACyB;AACzB,QAAM,SAASC,gBAAiB,SAAS,kBAAkB;AAC3D,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,iBAAiB,aAAa,CAAC;AAAA,EAC5D;AACA,SAAO;AACT;AAKO,SAAS,cACd,SACA,SACyB;AACzB,QAAM,SAASC,gBAAiB,SAAS,kBAAkB;AAC3D,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,gBAAgB,UAAU,UAAU,CAAC;AAAA,EAClE;AACA,SAAO;AACT;AAKO,SAAS,cACd,SACA,SACyB;AACzB,QAAM,SAASC,gBAAiB,SAAS,EAAE,GAAG,oBAAoB,UAAU,SAAS,UAAU;AAC/F,SAAO;AACT;AAKO,SAAS,YACd,OACA,UACyB;AACzB,QAAM,SAASC,cAAe,OAAO,kBAAkB;AACvD,SAAO;AACT;AAKO,SAAS,WACd,MACA,SACyB;AACzB,QAAM,SAASC,aAAc,MAAM,EAAE,GAAG,oBAAoB,UAAU,SAAS,UAAU;AACzF,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,UAAU,SAAS,CAAC;AAAA,EACjD;AACA,SAAO;AACT;AAKO,SAAS,cACd,SACA,SACyB;AACzB,QAAM,SAASC,gBAAiB,SAAS,EAAE,GAAG,oBAAoB,UAAU,SAAS,UAAU;AAC/F,MAAI,SAAS,SAAS;AACpB,WAAO,WAAW,QAAQ,CAAC,eAAe,eAAe,iBAAiB,CAAC;AAAA,EAC7E;AACA,SAAO;AACT;AAUO,SAAS,mBACd,MACA,WACA,MACA,SAC2C;AAE3C,QAAM,mBAAmB,CAAC,MAAuB,gBAAgC;AAC/E,WAAO,UAAU,MAAM,OAAO;AAAA,EAChC;AAEA,QAAM,SAASC,qBAAsB,MAAM,kBAAkB,MAAM;AAAA,IACjE,GAAG;AAAA,IACH,UAAU,SAAS;AAAA,EAAA,CACpB;AAED,SAAO;AACT;AC5NO,SAAS,WAAW,MAA2B;AACpD,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,EAAA,CAAG;AAAA,EAAA;AAEnE;AAKO,SAAS,YAAY,SAA6B;AACvD,SAAO;AAAA,IACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,UAAU,OAAO,IAAI;AAAA,IACrD,SAAS;AAAA,EAAA;AAEb;AAKO,SAAS,eACd,QACoC;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAiC,CAAA;AACvC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,UAAU,UAAa,UAAU,MAAM;AACzC,aAAO,GAAG,IAAI,OAAO,KAAK;AAAA,IAC5B;AAAA,EACF;AACA,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AACnD;AC9BA,eAAsB,eACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,WAAW,YAAY,UAAU,YAAY,UAAU,MAAM,KAAA,IAAS;AAElF,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,WAAW,IAAI,EAAE,SAAS,CAAC,UAAU,SAAS,GAAG;AAC1E,WAAO,WAAW,cAAc,OAAO,MAAM,EAAE,GAAG,eAAe,UAAU,OAAO,SAAA,CAAU,CAAC;AAAA,EAC/F;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,aAAa,CAAC,cAAc,CAAC,UAAU;AAC1C,aAAO,YAAY,6DAA6D;AAAA,IAClF;AACA,QAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,aAAO,YAAY,+CAA+C;AAAA,IACpE;AACA,UAAM,SAAS,MAAM,IAAI,cAAc;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AACD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,cAAc,OAAO,MAAM,aAAa,GAAG;AAAA,EACnF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,GAAI,QAAO,YAAY,kCAAkC;AAC9D,UAAM,aAAsD,CAAA;AAC5D,QAAI,eAAe,OAAW,YAAW,aAAa;AACtD,QAAI,aAAa,OAAW,YAAW,WAAW;AAClD,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,UAAM,SAAS,MAAM,IAAI,cAAc,IAAI,UAAU;AACrD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,cAAc,OAAO,MAAM,aAAa,GAAG;AAAA,EACnF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,YAAY,EAAE,QAAQ,MAAM,SAAS,SAAS,CAAC,UAAU,SAAS,GAAG;AAC9F,WAAO;AAAA,MACL,mBAAmB,OAAO,MAAM,eAAe,OAAO,MAAM;AAAA,QAC1D,GAAG;AAAA,QACH,UAAU,OAAO;AAAA,MAAA,CAClB;AAAA,IAAA;AAAA,EAEL;AAEA,SAAO,YAAY,mBAAmB,MAAM,gDAAgD;AAC9F;ACvDA,eAAsB,eACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,MAAM,SAAS,SAAS,eAAe;AAEnD,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,WAAW,IAAI,EAAE,SAAS,CAAC,SAAS,GAAG;AAChE,WAAO,WAAW,cAAc,OAAO,MAAM,EAAE,GAAG,eAAe,UAAU,OAAO,SAAA,CAAU,CAAC;AAAA,EAC/F;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,KAAM,QAAO,YAAY,6BAA6B;AAC3D,QAAI,CAAC,WAAW,CAAC,WAAW,CAAC,YAAY;AACvC,aAAO,YAAY,wDAAwD;AAAA,IAC7E;AACA,UAAM,SAAS,MAAM,IAAI,cAAc;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AACD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,cAAc,OAAO,MAAM,aAAa,GAAG;AAAA,EACnF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,GAAI,QAAO,YAAY,kCAAkC;AAC9D,QAAI,CAAC,KAAM,QAAO,YAAY,6BAA6B;AAC3D,UAAM,SAAS,MAAM,IAAI,cAAc,IAAI,EAAE,MAAM;AACnD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,cAAc,OAAO,MAAM,aAAa,GAAG;AAAA,EACnF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,YAAY,EAAE,QAAQ,MAAM,SAAS,SAAS,CAAC,SAAS,EAAA,CAAG;AACpF,WAAO;AAAA,MACL,mBAAmB,OAAO,MAAM,eAAe,OAAO,MAAM;AAAA,QAC1D,GAAG;AAAA,QACH,UAAU,OAAO;AAAA,MAAA,CAClB;AAAA,IAAA;AAAA,EAEL;AAEA,SAAO,YAAY,mBAAmB,MAAM,gDAAgD;AAC9F;AC9CA,eAAsB,gBACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,KAAA,IAAS;AAErB,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,WAAW,EAAE;AACtC,WAAO,WAAW,cAAc,OAAO,MAAM,aAAa,CAAC;AAAA,EAC7D;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,KAAM,QAAO,YAAY,6BAA6B;AAC3D,UAAM,SAAS,MAAM,IAAI,cAAc,EAAE,MAAM;AAC/C,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,cAAc,OAAO,MAAM,aAAa,GAAG;AAAA,EACnF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,GAAI,QAAO,YAAY,kCAAkC;AAC9D,UAAM,aAAsD,CAAA;AAC5D,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,UAAM,SAAS,MAAM,IAAI,cAAc,IAAI,UAAU;AACrD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,cAAc,OAAO,MAAM,aAAa,GAAG;AAAA,EACnF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,aAAa,EAAE,QAAQ,MAAM,SAAS;AAC/D,WAAO,WAAW,mBAAmB,OAAO,MAAM,eAAe,OAAO,MAAM,aAAa,CAAC;AAAA,EAC9F;AAEA,SAAO,YAAY,mBAAmB,MAAM,iDAAiD;AAC/F;AClCA,eAAsB,YACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,MAAM,WAAA,IAAe;AAEjC,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,QAAQ,IAAI,EAAE,SAAS,CAAC,WAAW,eAAe,aAAa,EAAA,CAAG;AAC3F,WAAO,WAAW,WAAW,OAAO,MAAM,EAAE,GAAG,eAAe,UAAU,OAAO,SAAA,CAAU,CAAC;AAAA,EAC5F;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,QAAQ,CAAC,YAAY;AACxB,aAAO,YAAY,6CAA6C;AAAA,IAClE;AACA,UAAM,SAAS,MAAM,IAAI,WAAW,EAAE,MAAM,YAAY;AACxD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,WAAW,OAAO,MAAM,aAAa,GAAG;AAAA,EAChF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,GAAI,QAAO,YAAY,kCAAkC;AAC9D,UAAM,aAAmD,CAAA;AACzD,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,UAAM,SAAS,MAAM,IAAI,WAAW,IAAI,UAAU;AAClD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,WAAW,OAAO,MAAM,aAAa,GAAG;AAAA,EAChF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,SAAS;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,CAAC,WAAW,aAAa;AAAA,IAAA,CACnC;AACD,WAAO;AAAA,MACL,mBAAmB,OAAO,MAAM,YAAY,OAAO,MAAM;AAAA,QACvD,GAAG;AAAA,QACH,UAAU,OAAO;AAAA,MAAA,CAClB;AAAA,IAAA;AAAA,EAEL;AAEA,SAAO,YAAY,mBAAmB,MAAM,6CAA6C;AAC3F;AC7CA,eAAsB,aACpB,QACA,MACA,KACA,aACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,OAAO;AAEf,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,UAAU,EAAE;AACrC,WAAO,WAAW,aAAa,OAAO,MAAM,aAAa,CAAC;AAAA,EAC5D;AAEA,MAAI,WAAW,MAAM;AACnB,QAAI,YAAY,QAAQ;AACtB,YAAM,SAAS,MAAM,IAAI,UAAU,YAAY,MAAM;AACrD,aAAO,WAAW,aAAa,OAAO,MAAM,aAAa,CAAC;AAAA,IAC5D;AACA,WAAO,WAAW;AAAA,MAChB,SAAS;AAAA,MACT,gBAAgB,YAAY;AAAA,IAAA,CAC7B;AAAA,EACH;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,UAAU,EAAE,QAAQ,MAAM,SAAS;AAC5D,WAAO,WAAW,mBAAmB,OAAO,MAAM,cAAc,OAAO,MAAM,aAAa,CAAC;AAAA,EAC7F;AAEA,SAAO,YAAY,mBAAmB,MAAM,kCAAkC;AAChF;ACjCA,eAAsB,eACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,OAAO;AAEf,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,WAAW,EAAE;AACtC,WAAO,WAAW,cAAc,OAAO,MAAM,aAAa,CAAC;AAAA,EAC7D;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,YAAY,EAAE,QAAQ,MAAM,SAAS;AAC9D,WAAO,WAAW,mBAAmB,OAAO,MAAM,eAAe,OAAO,MAAM,aAAa,CAAC;AAAA,EAC9F;AAEA,SAAO,YAAY,mBAAmB,MAAM,gCAAgC;AAC9E;ACpBA,eAAsB,eACpB,QACA,OACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AAEtD,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,YAAY,EAAE,QAAQ,MAAM,SAAS;AAC9D,WAAO,WAAW,mBAAmB,OAAO,MAAM,eAAe,OAAO,MAAM,aAAa,CAAC;AAAA,EAC9F;AAEA,SAAO,YAAY,mBAAmB,MAAM,2BAA2B;AACzE;ACbA,eAAsB,YACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,OAAO,YAAY,cAAc,aAAa,gBAAgB;AAC1E,QAAM,UAAU,CAAC,WAAW,iBAAiB;AAE7C,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,QAAQ,IAAI,EAAE,SAAS;AAChD,WAAO,WAAW,WAAW,OAAO,MAAM,EAAE,GAAG,eAAe,UAAU,OAAO,SAAA,CAAU,CAAC;AAAA,EAC5F;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,SAAS,CAAC,cAAc,CAAC,cAAc;AAC1C,aAAO,YAAY,6DAA6D;AAAA,IAClF;AACA,UAAM,SAAS,MAAM,IAAI,WAAW;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AACD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,WAAW,OAAO,MAAM,aAAa,GAAG;AAAA,EAChF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,GAAI,QAAO,YAAY,kCAAkC;AAC9D,UAAM,aAAmD,CAAA;AACzD,QAAI,UAAU,OAAW,YAAW,QAAQ;AAC5C,QAAI,gBAAgB,OAAW,YAAW,cAAc;AACxD,QAAI,gBAAgB,OAAW,YAAW,cAAc;AACxD,UAAM,SAAS,MAAM,IAAI,WAAW,IAAI,UAAU;AAClD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,WAAW,OAAO,MAAM,aAAa,GAAG;AAAA,EAChF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,SAAS,EAAE,QAAQ,MAAM,SAAS,SAAS;AACpE,WAAO;AAAA,MACL,mBAAmB,OAAO,MAAM,YAAY,OAAO,MAAM;AAAA,QACvD,GAAG;AAAA,QACH,UAAU,OAAO;AAAA,MAAA,CAClB;AAAA,IAAA;AAAA,EAEL;AAEA,SAAO,YAAY,mBAAmB,MAAM,6CAA6C;AAC3F;AClDA,eAAsB,WACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,WAAW,YAAY,SAAS,MAAM,MAAM,SAAS;AAEjE,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,aAAa,EAAE;AACxC,WAAO,WAAW,gBAAgB,OAAO,MAAM,aAAa,CAAC;AAAA,EAC/D;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,aAAa,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM;AAC/C,aAAO,YAAY,+DAA+D;AAAA,IACpF;AACA,UAAM,SAAS,MAAM,IAAI,gBAAgB;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AACD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,gBAAgB,OAAO,MAAM,aAAa,GAAG;AAAA,EACrF;AAEA,MAAI,WAAW,UAAU;AACvB,QAAI,CAAC,GAAI,QAAO,YAAY,kCAAkC;AAC9D,UAAM,aAAwD,CAAA;AAC9D,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,QAAI,SAAS,OAAW,YAAW,OAAO;AAC1C,UAAM,SAAS,MAAM,IAAI,gBAAgB,IAAI,UAAU;AACvD,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,gBAAgB,OAAO,MAAM,aAAa,GAAG;AAAA,EACrF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,eAAe,EAAE,QAAQ,MAAM,SAAS;AACjE,WAAO,WAAW,mBAAmB,OAAO,MAAM,iBAAiB,OAAO,MAAM,aAAa,CAAC;AAAA,EAChG;AAEA,SAAO,YAAY,mBAAmB,MAAM,4CAA4C;AAC1F;AC7CA,eAAsB,aACpB,QACA,MACA,KACqB;AACrB,QAAM,EAAE,KAAK,eAAe,QAAQ,MAAM,YAAY;AACtD,QAAM,EAAE,IAAI,YAAY,cAAA,IAAkB;AAE1C,MAAI,WAAW,OAAO;AACpB,QAAI,CAAC,GAAI,QAAO,YAAY,+BAA+B;AAC3D,UAAM,SAAS,MAAM,IAAI,SAAS,EAAE;AACpC,WAAO,WAAW,YAAY,OAAO,IAAmB,CAAC;AAAA,EAC3D;AAEA,MAAI,WAAW,WAAW,WAAW,UAAU;AAC7C,QAAI,CAAC,cAAc,CAAC,eAAe;AACjC,aAAO,YAAY,0DAA0D;AAAA,IAC/E;AACA,UAAM,SAAS,MAAM,IAAI,WAAW,EAAE,YAAY,eAAe;AACjE,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,YAAY,OAAO,IAAmB,GAAG;AAAA,EACjF;AAEA,MAAI,WAAW,QAAQ;AACrB,QAAI,CAAC,GAAI,QAAO,YAAY,gCAAgC;AAC5D,UAAM,SAAS,MAAM,IAAI,UAAU,EAAE;AACrC,WAAO,WAAW,EAAE,SAAS,MAAM,GAAG,YAAY,OAAO,IAAmB,GAAG;AAAA,EACjF;AAEA,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,IAAI,UAAU,EAAE,QAAQ,MAAM,SAAS;AAC5D,WAAO,WAAW,mBAAmB,OAAO,MAAM,aAAa,OAAO,MAAM,aAAa,CAAC;AAAA,EAC5F;AAEA,SAAO,YAAY,mBAAmB,MAAM,2CAA2C;AACzF;ACZA,MAAM,mBAAmB;AA2CzB,eAAsB,2BACpB,MACA,MACA,aACqB;AAErB,QAAM,MAAM,IAAI,cAAc;AAAA,IAC5B,OAAO,YAAY;AAAA,IACnB,UAAU,YAAY;AAAA,IACtB,WAAW,YAAY;AAAA,EAAA,CACE;AAG3B,MAAI,SAAS,cAAc;AACzB,WAAO,YAAY,iBAAiB,IAAI,EAAE;AAAA,EAC5C;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,GAAG;AAAA,EAAA,IACD;AAEJ,QAAM,gBAAkC,EAAE,QAAA;AAC1C,QAAM,eAAe,eAAe,MAAM;AAC1C,QAAM,UAAU,YAAY;AAG5B,QAAM,MAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EAAA;AAGF,MAAI;AAEF,YAAQ,UAAA;AAAA,MACN,KAAK;AACH,eAAO,MAAM,eAAe,QAAQ,UAAU,GAAG;AAAA,MAEnD,KAAK;AACH,eAAO,MAAM,WAAW,QAAQ,UAAU,GAAG;AAAA,MAE/C,KAAK;AACH,eAAO,MAAM,YAAY,QAAQ,UAAU,GAAG;AAAA,MAEhD,KAAK;AACH,eAAO,MAAM,eAAe,QAAQ,UAAU,GAAG;AAAA,MAEnD,KAAK;AACH,eAAO,MAAM,aAAa,QAAQ,UAAU,KAAK,WAAW;AAAA,MAE9D,KAAK;AACH,eAAO,MAAM,gBAAgB,QAAQ,UAAU,GAAG;AAAA,MAEpD,KAAK;AACH,eAAO,MAAM,eAAe,QAAQ,UAAU,GAAG;AAAA,MAEnD,KAAK;AACH,eAAO,MAAM,aAAa,QAAQ,UAAU,GAAG;AAAA,MAEjD,KAAK;AACH,eAAO,MAAM,YAAY,QAAQ,UAAU,GAAG;AAAA,MAEhD,KAAK;AACH,eAAO,MAAM,eAAe,QAAQ,UAAU,GAAG;AAAA,MAEnD;AACE,eAAO,YAAY,qBAAqB,QAAQ,EAAE;AAAA,IAAA;AAAA,EAExD,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,WAAO,YAAY,OAAO;AAAA,EAC5B;AACF;"}
@@ -1,5 +0,0 @@
1
- const VERSION = "0.6.4";
2
- export {
3
- VERSION as V
4
- };
5
- //# sourceMappingURL=version-BRw90xAB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"version-BRw90xAB.js","sources":["../src/version.ts"],"sourcesContent":["/**\n * Package version - injected from package.json at build time\n */\ndeclare const __VERSION__: string;\nexport const VERSION = __VERSION__;\n"],"names":[],"mappings":"AAIO,MAAM,UAAU;"}