@wilnertech/halopsa-mcp-server 1.0.1 → 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/README.md +54 -7
- package/dist/api/client.d.ts +7 -2
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +35 -8
- package/dist/api/client.js.map +1 -1
- package/dist/cache/memory-cache.d.ts +7 -0
- package/dist/cache/memory-cache.d.ts.map +1 -1
- package/dist/cache/memory-cache.js +7 -0
- package/dist/cache/memory-cache.js.map +1 -1
- package/dist/cache/prewarm.d.ts +3 -1
- package/dist/cache/prewarm.d.ts.map +1 -1
- package/dist/cache/prewarm.js +17 -1
- package/dist/cache/prewarm.js.map +1 -1
- package/dist/schemas/common.d.ts +30 -99
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/common.js +2 -2
- package/dist/schemas/common.js.map +1 -1
- package/dist/tools/assets.d.ts +73 -298
- package/dist/tools/assets.d.ts.map +1 -1
- package/dist/tools/assets.js +15 -7
- package/dist/tools/assets.js.map +1 -1
- package/dist/tools/batch-operations.d.ts +49 -81
- package/dist/tools/batch-operations.d.ts.map +1 -1
- package/dist/tools/batch-operations.js +62 -0
- package/dist/tools/batch-operations.js.map +1 -1
- package/dist/tools/clients.d.ts +24 -92
- package/dist/tools/clients.d.ts.map +1 -1
- package/dist/tools/reference-data.d.ts +44 -72
- package/dist/tools/reference-data.d.ts.map +1 -1
- package/dist/tools/reference-data.js +37 -4
- package/dist/tools/reference-data.js.map +1 -1
- package/dist/tools/registrations.d.ts +7 -1
- package/dist/tools/registrations.d.ts.map +1 -1
- package/dist/tools/registrations.js +43 -7
- package/dist/tools/registrations.js.map +1 -1
- package/dist/tools/registry.d.ts +12 -5
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +26 -2
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/sites.d.ts +19 -111
- package/dist/tools/sites.d.ts.map +1 -1
- package/dist/tools/sites.js +3 -3
- package/dist/tools/sites.js.map +1 -1
- package/dist/tools/ticket-actions.d.ts +41 -0
- package/dist/tools/ticket-actions.d.ts.map +1 -0
- package/dist/tools/ticket-actions.js +222 -0
- package/dist/tools/ticket-actions.js.map +1 -0
- package/dist/tools/ticket-custom-fields.d.ts +33 -0
- package/dist/tools/ticket-custom-fields.d.ts.map +1 -0
- package/dist/tools/ticket-custom-fields.js +155 -0
- package/dist/tools/ticket-custom-fields.js.map +1 -0
- package/dist/tools/ticket-reference-data.d.ts +88 -0
- package/dist/tools/ticket-reference-data.d.ts.map +1 -0
- package/dist/tools/ticket-reference-data.js +185 -0
- package/dist/tools/ticket-reference-data.js.map +1 -0
- package/dist/tools/tickets.d.ts +168 -0
- package/dist/tools/tickets.d.ts.map +1 -0
- package/dist/tools/tickets.js +572 -0
- package/dist/tools/tickets.js.map +1 -0
- package/dist/tools/users.d.ts +43 -190
- package/dist/tools/users.d.ts.map +1 -1
- package/dist/tools/users.js +25 -7
- package/dist/tools/users.js.map +1 -1
- package/dist/types/tickets.d.ts +193 -0
- package/dist/types/tickets.d.ts.map +1 -0
- package/dist/types/tickets.js +14 -0
- package/dist/types/tickets.js.map +1 -0
- package/dist/utils/formatter.d.ts +15 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +52 -6
- package/dist/utils/formatter.js.map +1 -1
- package/package.json +10 -3
- package/dist/utils/zod-to-schema.d.ts +0 -29
- package/dist/utils/zod-to-schema.d.ts.map +0 -1
- package/dist/utils/zod-to-schema.js +0 -182
- package/dist/utils/zod-to-schema.js.map +0 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HaloPSA Ticket Reference Data tools.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the existing pattern in `src/tools/reference-data.ts` for asset
|
|
5
|
+
* reference data. All five tools default to compact responses (token
|
|
6
|
+
* optimization) and use 1-hour cache TTLs because reference data on a
|
|
7
|
+
* Halo tenant changes infrequently — most reads should hit cache.
|
|
8
|
+
*
|
|
9
|
+
* The tools deliberately accept BOTH a `full` boolean shortcut AND the
|
|
10
|
+
* standard `format_options` block so callers can choose their style:
|
|
11
|
+
* `{ full: true }` is the path-of-least-surprise for ad-hoc lookups,
|
|
12
|
+
* while `format_options` keeps parity with the rest of the MCP surface.
|
|
13
|
+
*/
|
|
14
|
+
import { z } from 'zod';
|
|
15
|
+
import { formatResponse } from '../utils/formatter.js';
|
|
16
|
+
import { TTL } from '../cache/memory-cache.js';
|
|
17
|
+
import { FormatOptionsSchema } from '../schemas/common.js';
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Schemas
|
|
20
|
+
// =============================================================================
|
|
21
|
+
const ListTicketTypesArgsSchema = z.object({
|
|
22
|
+
full: z.boolean().optional()
|
|
23
|
+
.describe('Return full records instead of compact (default false). Equivalent to format_options.format="detailed".'),
|
|
24
|
+
format_options: FormatOptionsSchema,
|
|
25
|
+
});
|
|
26
|
+
const GetTicketTypeArgsSchema = z.object({
|
|
27
|
+
tickettype_id: z.number().int()
|
|
28
|
+
.describe('HaloPSA ticket type ID'),
|
|
29
|
+
format_options: FormatOptionsSchema,
|
|
30
|
+
});
|
|
31
|
+
const ListTicketStatusesArgsSchema = z.object({
|
|
32
|
+
full: z.boolean().optional()
|
|
33
|
+
.describe('Return full records instead of compact (default false).'),
|
|
34
|
+
format_options: FormatOptionsSchema,
|
|
35
|
+
});
|
|
36
|
+
const ListTicketPrioritiesArgsSchema = z.object({
|
|
37
|
+
full: z.boolean().optional()
|
|
38
|
+
.describe('Return full records instead of compact (default false).'),
|
|
39
|
+
format_options: FormatOptionsSchema,
|
|
40
|
+
});
|
|
41
|
+
const ListTicketCategoriesArgsSchema = z.object({
|
|
42
|
+
full: z.boolean().optional()
|
|
43
|
+
.describe('Return full records instead of compact (default false).'),
|
|
44
|
+
format_options: FormatOptionsSchema,
|
|
45
|
+
});
|
|
46
|
+
// =============================================================================
|
|
47
|
+
// Helpers
|
|
48
|
+
// =============================================================================
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the effective FormatOptions from caller input, defaulting to
|
|
51
|
+
* compact unless the user opted in to a fuller view via `full: true` or
|
|
52
|
+
* an explicit `format_options.format`.
|
|
53
|
+
*/
|
|
54
|
+
function resolveFormat(full, formatOptions) {
|
|
55
|
+
const opts = { ...(formatOptions || {}) };
|
|
56
|
+
if (full && !opts.format) {
|
|
57
|
+
opts.format = 'detailed';
|
|
58
|
+
}
|
|
59
|
+
if (!opts.format) {
|
|
60
|
+
opts.format = 'compact';
|
|
61
|
+
}
|
|
62
|
+
return opts;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Normalize a raw /Priority record.
|
|
66
|
+
*
|
|
67
|
+
* The raw API shape has:
|
|
68
|
+
* - `id`: GUID string — uniquely identifies this priority+SLA combo
|
|
69
|
+
* - `priorityid`: integer 1-4 — the value Faults.priority_id expects
|
|
70
|
+
*
|
|
71
|
+
* We promote `priorityid` to `id` and expose the GUID as `sla_priority_id`
|
|
72
|
+
* to prevent callers from accidentally passing the GUID as priority_id.
|
|
73
|
+
*/
|
|
74
|
+
function normalizePriority(p) {
|
|
75
|
+
return {
|
|
76
|
+
id: p.priorityid,
|
|
77
|
+
name: p.name,
|
|
78
|
+
sla_priority_id: p.id,
|
|
79
|
+
slaid: p.slaid,
|
|
80
|
+
fixtime: p.fixtime,
|
|
81
|
+
fixunits: p.fixunits,
|
|
82
|
+
responsetime: p.responsetime,
|
|
83
|
+
responseunits: p.responseunits,
|
|
84
|
+
colour: p.colour,
|
|
85
|
+
firstresponsetime: p.firstresponsetime,
|
|
86
|
+
firstresponseunits: p.firstresponseunits,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Halo list endpoints return either bare arrays or `{ <plural>: [...] }`. */
|
|
90
|
+
function unwrapList(response, preferredKey) {
|
|
91
|
+
if (Array.isArray(response)) {
|
|
92
|
+
return { items: response, record_count: response.length };
|
|
93
|
+
}
|
|
94
|
+
const wrapped = response;
|
|
95
|
+
const items = wrapped[preferredKey] ?? [];
|
|
96
|
+
const record_count = wrapped.record_count ?? items.length;
|
|
97
|
+
return { items, record_count };
|
|
98
|
+
}
|
|
99
|
+
// =============================================================================
|
|
100
|
+
// Implementations
|
|
101
|
+
// =============================================================================
|
|
102
|
+
export async function listTicketTypes(client, args) {
|
|
103
|
+
const formatOpts = resolveFormat(args.full, args.format_options);
|
|
104
|
+
const response = await client.getCached('/TicketType', { count: 500 }, {
|
|
105
|
+
enabled: true,
|
|
106
|
+
ttl: TTL.TICKET_TYPES,
|
|
107
|
+
keyPrefix: 'tickettypes:all',
|
|
108
|
+
});
|
|
109
|
+
const { items, record_count } = unwrapList(response, 'tickettypes');
|
|
110
|
+
return formatResponse(items, formatOpts, { record_count });
|
|
111
|
+
}
|
|
112
|
+
export async function getTicketType(client, args) {
|
|
113
|
+
const formatOpts = args.format_options || { format: 'standard' };
|
|
114
|
+
const response = await client.getCached(`/TicketType/${args.tickettype_id}`, undefined, {
|
|
115
|
+
enabled: true,
|
|
116
|
+
ttl: TTL.TICKET_TYPES,
|
|
117
|
+
keyPrefix: `tickettype:${args.tickettype_id}`,
|
|
118
|
+
});
|
|
119
|
+
return formatResponse(response, formatOpts);
|
|
120
|
+
}
|
|
121
|
+
export async function listTicketStatuses(client, args) {
|
|
122
|
+
const formatOpts = resolveFormat(args.full, args.format_options);
|
|
123
|
+
const response = await client.getCached('/Status', { count: 500 }, {
|
|
124
|
+
enabled: true,
|
|
125
|
+
ttl: TTL.TICKET_STATUSES,
|
|
126
|
+
keyPrefix: 'ticketstatuses:all',
|
|
127
|
+
});
|
|
128
|
+
const { items, record_count } = unwrapList(response, 'statuses');
|
|
129
|
+
return formatResponse(items, formatOpts, { record_count });
|
|
130
|
+
}
|
|
131
|
+
export async function listTicketPriorities(client, args) {
|
|
132
|
+
const formatOpts = resolveFormat(args.full, args.format_options);
|
|
133
|
+
const response = await client.getCached('/Priority', { count: 500 }, {
|
|
134
|
+
enabled: true,
|
|
135
|
+
ttl: TTL.TICKET_PRIORITIES,
|
|
136
|
+
keyPrefix: 'ticketpriorities:all',
|
|
137
|
+
});
|
|
138
|
+
const { items: rawItems, record_count } = unwrapList(response, 'priorities');
|
|
139
|
+
const items = rawItems.map(normalizePriority);
|
|
140
|
+
return formatResponse(items, formatOpts, { record_count });
|
|
141
|
+
}
|
|
142
|
+
export async function listTicketCategories(client, args) {
|
|
143
|
+
const formatOpts = resolveFormat(args.full, args.format_options);
|
|
144
|
+
const response = await client.getCached('/Category', { count: 500 }, {
|
|
145
|
+
enabled: true,
|
|
146
|
+
ttl: TTL.TICKET_CATEGORIES,
|
|
147
|
+
keyPrefix: 'ticketcategories:all',
|
|
148
|
+
});
|
|
149
|
+
const { items, record_count } = unwrapList(response, 'categories');
|
|
150
|
+
return formatResponse(items, formatOpts, { record_count });
|
|
151
|
+
}
|
|
152
|
+
// =============================================================================
|
|
153
|
+
// Tool Definitions
|
|
154
|
+
// =============================================================================
|
|
155
|
+
export const listTicketTypesTool = {
|
|
156
|
+
name: 'list_halopsa_tickettypes',
|
|
157
|
+
description: 'List all HaloPSA ticket types (Incident, Service Request, Change, etc.) with 1h cache. Compact by default; pass full=true for full records.',
|
|
158
|
+
schema: ListTicketTypesArgsSchema,
|
|
159
|
+
handler: listTicketTypes,
|
|
160
|
+
};
|
|
161
|
+
export const getTicketTypeTool = {
|
|
162
|
+
name: 'get_halopsa_tickettype',
|
|
163
|
+
description: 'Get a single HaloPSA ticket type by ID. Cached 1h.',
|
|
164
|
+
schema: GetTicketTypeArgsSchema,
|
|
165
|
+
handler: getTicketType,
|
|
166
|
+
};
|
|
167
|
+
export const listTicketStatusesTool = {
|
|
168
|
+
name: 'list_halopsa_ticket_statuses',
|
|
169
|
+
description: 'List HaloPSA ticket statuses. Each record carries `type` (0=regular ticket statuses, 1=Order, 2=Item, 3=Action Required/Invoiced/With CAB) and `sequence` (UI ordering). NOTE: the API does NOT return `complete` / `is_closed` / `is_active` flags despite some prior documentation. To find the canonical Closed status, match `name === "Closed" && type === 0` (returns id=9 on this tenant). For Order/Item flavours, see id=13 "Closed Order" (type=1) and id=15 "Closed Item" (type=2). Cached 1h.',
|
|
170
|
+
schema: ListTicketStatusesArgsSchema,
|
|
171
|
+
handler: listTicketStatuses,
|
|
172
|
+
};
|
|
173
|
+
export const listTicketPrioritiesTool = {
|
|
174
|
+
name: 'list_halopsa_ticket_priorities',
|
|
175
|
+
description: 'List HaloPSA ticket priorities. The `id` field is the integer priority value (1-4) that maps to `Faults.priority_id` on ticket creates — NOT the underlying GUID, which is per-SLA and exposed as `sla_priority_id`. Pass `id` to create/update_halopsa_ticket. Names duplicate across SLAs (3 Critical, 3 High, 3 Medium, 3 Low — one per SLA). Includes fix/response time hints. Cached 1h.',
|
|
176
|
+
schema: ListTicketPrioritiesArgsSchema,
|
|
177
|
+
handler: listTicketPriorities,
|
|
178
|
+
};
|
|
179
|
+
export const listTicketCategoriesTool = {
|
|
180
|
+
name: 'list_halopsa_ticket_categories',
|
|
181
|
+
description: 'List all HaloPSA ticket categories (used for category_1..category_4 fields on tickets). Cached 1h.',
|
|
182
|
+
schema: ListTicketCategoriesArgsSchema,
|
|
183
|
+
handler: listTicketCategories,
|
|
184
|
+
};
|
|
185
|
+
//# sourceMappingURL=ticket-reference-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket-reference-data.js","sourceRoot":"","sources":["../../src/tools/ticket-reference-data.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HaloPSA Ticket CRUD tools.
|
|
3
|
+
*
|
|
4
|
+
* Tickets are append-only business events — unlike assets/users/sites,
|
|
5
|
+
* there is no `find_*_match` deduplication step. Update by explicit id
|
|
6
|
+
* always.
|
|
7
|
+
*
|
|
8
|
+
* Update mechanics mirror `updateAsset` in `src/tools/assets.ts`:
|
|
9
|
+
* Halo's POST /api/Tickets is REPLACE-not-PATCH, so we read the current
|
|
10
|
+
* record first and spread it under the partial payload before sending.
|
|
11
|
+
*
|
|
12
|
+
* Compact responses INTENTIONALLY omit `details_html` (HTML body, can be
|
|
13
|
+
* 50KB+) and `customfields[]` to keep MCP responses sub-second and
|
|
14
|
+
* within token budgets. Callers that need them call `get_halopsa_ticket`
|
|
15
|
+
* or pass `format_options.format = 'detailed'` / `full: true`.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
import type { HaloPSAAPIClient } from '../api/client.js';
|
|
19
|
+
import type { ZodToolDefinition } from './registry.js';
|
|
20
|
+
export declare const ListTicketsArgsSchema: z.ZodObject<{
|
|
21
|
+
client_id: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
client_ids: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
23
|
+
site_id: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
user_id: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
agent_id: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
agent: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
27
|
+
team_id: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
tickettype_id: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
29
|
+
status_id: z.ZodOptional<z.ZodNumber>;
|
|
30
|
+
category_1: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
31
|
+
category_2: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
32
|
+
category_3: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
33
|
+
category_4: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>;
|
|
34
|
+
search: z.ZodOptional<z.ZodString>;
|
|
35
|
+
open_only: z.ZodOptional<z.ZodBoolean>;
|
|
36
|
+
date_from: z.ZodOptional<z.ZodString>;
|
|
37
|
+
date_to: z.ZodOptional<z.ZodString>;
|
|
38
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
39
|
+
page_no: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
format_options: z.ZodOptional<z.ZodObject<{
|
|
41
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
42
|
+
compact: "compact";
|
|
43
|
+
standard: "standard";
|
|
44
|
+
detailed: "detailed";
|
|
45
|
+
}>>;
|
|
46
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
47
|
+
omit_empty: z.ZodOptional<z.ZodBoolean>;
|
|
48
|
+
}, z.core.$strip>>;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
export declare const GetTicketArgsSchema: z.ZodObject<{
|
|
51
|
+
ticket_id: z.ZodNumber;
|
|
52
|
+
format_options: z.ZodOptional<z.ZodObject<{
|
|
53
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
compact: "compact";
|
|
55
|
+
standard: "standard";
|
|
56
|
+
detailed: "detailed";
|
|
57
|
+
}>>;
|
|
58
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
59
|
+
omit_empty: z.ZodOptional<z.ZodBoolean>;
|
|
60
|
+
}, z.core.$strip>>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export declare const SearchTicketsArgsSchema: z.ZodObject<{
|
|
63
|
+
search: z.ZodString;
|
|
64
|
+
client_id: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
open_only: z.ZodOptional<z.ZodBoolean>;
|
|
66
|
+
count: z.ZodOptional<z.ZodNumber>;
|
|
67
|
+
format_options: z.ZodOptional<z.ZodObject<{
|
|
68
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
69
|
+
compact: "compact";
|
|
70
|
+
standard: "standard";
|
|
71
|
+
detailed: "detailed";
|
|
72
|
+
}>>;
|
|
73
|
+
fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
74
|
+
omit_empty: z.ZodOptional<z.ZodBoolean>;
|
|
75
|
+
}, z.core.$strip>>;
|
|
76
|
+
}, z.core.$strip>;
|
|
77
|
+
export declare const CreateTicketArgsSchema: z.ZodObject<{
|
|
78
|
+
summary: z.ZodString;
|
|
79
|
+
tickettype_id: z.ZodNumber;
|
|
80
|
+
client_id: z.ZodNumber;
|
|
81
|
+
details_html: z.ZodOptional<z.ZodString>;
|
|
82
|
+
category_1: z.ZodOptional<z.ZodString>;
|
|
83
|
+
priority_id: z.ZodOptional<z.ZodNumber>;
|
|
84
|
+
status_id: z.ZodOptional<z.ZodNumber>;
|
|
85
|
+
source: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
agent_id: z.ZodOptional<z.ZodNumber>;
|
|
87
|
+
team_id: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
site_id: z.ZodOptional<z.ZodNumber>;
|
|
89
|
+
user_id: z.ZodOptional<z.ZodNumber>;
|
|
90
|
+
parent_id: z.ZodOptional<z.ZodNumber>;
|
|
91
|
+
dateoccurred: z.ZodOptional<z.ZodString>;
|
|
92
|
+
startdate: z.ZodOptional<z.ZodString>;
|
|
93
|
+
customfields: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
id: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
name: z.ZodOptional<z.ZodString>;
|
|
96
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
97
|
+
}, z.core.$strip>>>;
|
|
98
|
+
}, z.core.$strip>;
|
|
99
|
+
export declare const UpdateTicketArgsSchema: z.ZodObject<{
|
|
100
|
+
ticket_id: z.ZodNumber;
|
|
101
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
102
|
+
details_html: z.ZodOptional<z.ZodString>;
|
|
103
|
+
tickettype_id: z.ZodOptional<z.ZodNumber>;
|
|
104
|
+
status_id: z.ZodOptional<z.ZodNumber>;
|
|
105
|
+
priority_id: z.ZodOptional<z.ZodNumber>;
|
|
106
|
+
category_1: z.ZodOptional<z.ZodString>;
|
|
107
|
+
agent_id: z.ZodOptional<z.ZodNumber>;
|
|
108
|
+
team_id: z.ZodOptional<z.ZodNumber>;
|
|
109
|
+
site_id: z.ZodOptional<z.ZodNumber>;
|
|
110
|
+
user_id: z.ZodOptional<z.ZodNumber>;
|
|
111
|
+
parent_id: z.ZodOptional<z.ZodNumber>;
|
|
112
|
+
dateoccurred: z.ZodOptional<z.ZodString>;
|
|
113
|
+
startdate: z.ZodOptional<z.ZodString>;
|
|
114
|
+
source: z.ZodOptional<z.ZodNumber>;
|
|
115
|
+
customfields: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
116
|
+
id: z.ZodOptional<z.ZodNumber>;
|
|
117
|
+
name: z.ZodOptional<z.ZodString>;
|
|
118
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>;
|
|
119
|
+
}, z.core.$strip>>>;
|
|
120
|
+
}, z.core.$strip>;
|
|
121
|
+
export declare const CloseTicketArgsSchema: z.ZodObject<{
|
|
122
|
+
ticket_id: z.ZodNumber;
|
|
123
|
+
resolution_note: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strip>;
|
|
125
|
+
export declare const DeleteTicketArgsSchema: z.ZodObject<{
|
|
126
|
+
ticket_id: z.ZodNumber;
|
|
127
|
+
reason: z.ZodString;
|
|
128
|
+
confirm_destructive: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
129
|
+
}, z.core.$strip>;
|
|
130
|
+
export declare function listTickets(client: HaloPSAAPIClient, args: z.infer<typeof ListTicketsArgsSchema>): Promise<string>;
|
|
131
|
+
export declare function getTicket(client: HaloPSAAPIClient, args: z.infer<typeof GetTicketArgsSchema>): Promise<string>;
|
|
132
|
+
export declare function searchTickets(client: HaloPSAAPIClient, args: z.infer<typeof SearchTicketsArgsSchema>): Promise<string>;
|
|
133
|
+
export declare function createTicket(client: HaloPSAAPIClient, args: z.infer<typeof CreateTicketArgsSchema>): Promise<string>;
|
|
134
|
+
export declare function updateTicket(client: HaloPSAAPIClient, args: z.infer<typeof UpdateTicketArgsSchema>): Promise<string>;
|
|
135
|
+
/**
|
|
136
|
+
* Permanently delete a HaloPSA ticket by ID after running four safety
|
|
137
|
+
* pre-flight checks:
|
|
138
|
+
*
|
|
139
|
+
* 1. Financial — refuses if `timetaken > 0` or `hoursinvoiced > 0` (billable
|
|
140
|
+
* history would be destroyed on delete).
|
|
141
|
+
* 2. Cascade — refuses if `child_count > 0` (children would orphan; Halo
|
|
142
|
+
* cascade behavior is undocumented).
|
|
143
|
+
* 3. Historical — refuses if the ticket is closed or completed. Uses a
|
|
144
|
+
* tenant-portable dual-check: primary `hasbeenclosed === true` (Halo
|
|
145
|
+
* boolean); secondary fetches `/Status` (cached 1h) and matches against
|
|
146
|
+
* known closed-flavour names (Closed, Closed Order, Closed Item, Completed).
|
|
147
|
+
* 4. Authorship — refuses unless `who === 'claude_mcp'` (prevents accidental
|
|
148
|
+
* deletion of human-created tickets).
|
|
149
|
+
*
|
|
150
|
+
* OVERRIDE mechanism: when violations exist, pass `confirm_destructive: true`
|
|
151
|
+
* AND include the substring `"OVERRIDE"` (case-sensitive) in `reason` to
|
|
152
|
+
* bypass all checks and proceed with the DELETE.
|
|
153
|
+
*
|
|
154
|
+
* Return shapes:
|
|
155
|
+
* - `{ already_absent: true, deleted_id }` — 404 on GET (idempotent).
|
|
156
|
+
* - `{ deleted: false, refused: true, violations, remediation }` — safety block.
|
|
157
|
+
* - `{ deleted: true, ticket_id, reason, override_used, safety_violations_bypassed? }` — success.
|
|
158
|
+
*/
|
|
159
|
+
export declare function deleteTicket(client: HaloPSAAPIClient, args: z.infer<typeof DeleteTicketArgsSchema>): Promise<string>;
|
|
160
|
+
export declare function closeTicket(client: HaloPSAAPIClient, args: z.infer<typeof CloseTicketArgsSchema>): Promise<string>;
|
|
161
|
+
export declare const listTicketsTool: ZodToolDefinition;
|
|
162
|
+
export declare const getTicketTool: ZodToolDefinition;
|
|
163
|
+
export declare const searchTicketsTool: ZodToolDefinition;
|
|
164
|
+
export declare const createTicketTool: ZodToolDefinition;
|
|
165
|
+
export declare const updateTicketTool: ZodToolDefinition;
|
|
166
|
+
export declare const closeTicketTool: ZodToolDefinition;
|
|
167
|
+
export declare const deleteTicketTool: ZodToolDefinition;
|
|
168
|
+
//# sourceMappingURL=tickets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickets.d.ts","sourceRoot":"","sources":["../../src/tools/tickets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AA+BvD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwChC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;iBAI9B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;iBAUlC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;iBAiCjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;iBAuBjC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;iBAKhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;iBAQjC,CAAC;AAoGH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1C,OAAO,CAAC,MAAM,CAAC,CAwCjB;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,GACxC,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,GAC3C,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,GAC3C,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAgBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,GAC3C,OAAO,CAAC,MAAM,CAAC,CA0HjB;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1C,OAAO,CAAC,MAAM,CAAC,CAiBjB;AAMD,eAAO,MAAM,eAAe,EAAE,iBAK7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,iBAK3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAK/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,iBAK9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,iBAK9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,iBAK7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,iBAK9B,CAAC"}
|