@wilnertech/halopsa-mcp-server 1.4.0 → 1.6.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 (51) hide show
  1. package/README.md +8 -1
  2. package/dist/api/client.d.ts +51 -2
  3. package/dist/api/client.d.ts.map +1 -1
  4. package/dist/api/client.js +124 -9
  5. package/dist/api/client.js.map +1 -1
  6. package/dist/api/errors.d.ts +16 -3
  7. package/dist/api/errors.d.ts.map +1 -1
  8. package/dist/api/errors.js +107 -30
  9. package/dist/api/errors.js.map +1 -1
  10. package/dist/cache/memory-cache.d.ts +1 -0
  11. package/dist/cache/memory-cache.d.ts.map +1 -1
  12. package/dist/cache/memory-cache.js +6 -0
  13. package/dist/cache/memory-cache.js.map +1 -1
  14. package/dist/cache/prewarm.d.ts +1 -0
  15. package/dist/cache/prewarm.d.ts.map +1 -1
  16. package/dist/cache/prewarm.js +8 -0
  17. package/dist/cache/prewarm.js.map +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +12 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/tools/batch-operations.js +10 -10
  22. package/dist/tools/batch-operations.js.map +1 -1
  23. package/dist/tools/budgets.d.ts.map +1 -1
  24. package/dist/tools/budgets.js +7 -4
  25. package/dist/tools/budgets.js.map +1 -1
  26. package/dist/tools/milestones.d.ts.map +1 -1
  27. package/dist/tools/milestones.js +12 -9
  28. package/dist/tools/milestones.js.map +1 -1
  29. package/dist/tools/registrations.d.ts +8 -3
  30. package/dist/tools/registrations.d.ts.map +1 -1
  31. package/dist/tools/registrations.js +21 -12
  32. package/dist/tools/registrations.js.map +1 -1
  33. package/dist/tools/ticket-actions.d.ts +46 -0
  34. package/dist/tools/ticket-actions.d.ts.map +1 -1
  35. package/dist/tools/ticket-actions.js +236 -32
  36. package/dist/tools/ticket-actions.js.map +1 -1
  37. package/dist/tools/ticket-reference-data.d.ts +70 -1
  38. package/dist/tools/ticket-reference-data.d.ts.map +1 -1
  39. package/dist/tools/ticket-reference-data.js +340 -11
  40. package/dist/tools/ticket-reference-data.js.map +1 -1
  41. package/dist/tools/tickets.d.ts +53 -0
  42. package/dist/tools/tickets.d.ts.map +1 -1
  43. package/dist/tools/tickets.js +394 -22
  44. package/dist/tools/tickets.js.map +1 -1
  45. package/dist/types/tickets.d.ts +127 -0
  46. package/dist/types/tickets.d.ts.map +1 -1
  47. package/dist/utils/formatter.d.ts +18 -0
  48. package/dist/utils/formatter.d.ts.map +1 -1
  49. package/dist/utils/formatter.js +108 -22
  50. package/dist/utils/formatter.js.map +1 -1
  51. package/package.json +1 -1
@@ -2,15 +2,20 @@
2
2
  * Central tool registration — imports all ZodToolDefinition exports
3
3
  * and registers them with a ToolRegistry instance.
4
4
  *
5
- * Tool inventory (67 total):
5
+ * Tool inventory (71 total):
6
6
  * Assets (11), Users (7), Sites (4), Clients (3),
7
- * Reference data (4), Ticket reference data (5),
8
- * Tickets (7), Ticket actions (2), Ticket custom fields (2),
7
+ * Reference data (4), Ticket reference data (6 — incl. outcomes),
8
+ * Tickets (8 incl. validateCreateTicket; getTicketsBatch counted under Batch),
9
+ * Ticket actions (4 — incl. SLA hold/release),
10
+ * Ticket custom fields (2),
9
11
  * Batch operations (5 — assets, users, sites, tickets, bulk-update),
10
12
  * Ticket links (1 — read-side only),
11
13
  * Workflows (6 — list/get/list-steps/create/update/delete),
12
14
  * Ticket milestones (5 — list/set/add/remove + get-current),
13
15
  * Budgets (5 — list/create/delete BudgetType, get/set per-ticket)
16
+ *
17
+ * COUNT BREAKDOWN: 11+7+4+3+4+6+8+4+2+5+1+6+5+5 = 71
18
+ * The `allTools` array is the authoritative source; verify with allTools.length.
14
19
  */
15
20
  // Asset tools (11)
16
21
  import { listAssetsTool, getAssetTool, searchAssetsBySerialTool, searchAssetsByHostnameTool, createAssetTool, updateAssetTool, deleteAssetTool, listAssetCustomFieldsTool, getAssetFieldSchemaTool, findAssetMatchTool, scanAssetDuplicatesTool, } from './assets.js';
@@ -22,12 +27,12 @@ import { listSitesTool, getSiteTool, createSiteTool, findSiteMatchTool, } from '
22
27
  import { listClientsTool, getClientTool, searchClientsTool, } from './clients.js';
23
28
  // Reference data tools (4)
24
29
  import { listAssetTypesTool, listAssetStatusesTool, listContactTypesTool, listAgentsTool, } from './reference-data.js';
25
- // Ticket reference data tools (5)
26
- import { listTicketTypesTool, getTicketTypeTool, listTicketStatusesTool, listTicketPrioritiesTool, listTicketCategoriesTool, } from './ticket-reference-data.js';
27
- // Ticket tools (7 here; getTicketsBatchTool is the 8th and lives in batch-operations.ts)
28
- import { listTicketsTool, getTicketTool, searchTicketsTool, createTicketTool, updateTicketTool, closeTicketTool, deleteTicketTool, } from './tickets.js';
29
- // Ticket action tools (2)
30
- import { addTicketActionTool, listTicketActionsTool, } from './ticket-actions.js';
30
+ // Ticket reference data tools (6)
31
+ import { listTicketTypesTool, getTicketTypeTool, listTicketStatusesTool, listTicketPrioritiesTool, listTicketCategoriesTool, listTicketOutcomesTool, } from './ticket-reference-data.js';
32
+ // Ticket tools (8 getTicketsBatchTool lives in batch-operations.ts and is counted there)
33
+ import { listTicketsTool, getTicketTool, searchTicketsTool, createTicketTool, updateTicketTool, closeTicketTool, deleteTicketTool, validateCreateTicketTool, } from './tickets.js';
34
+ // Ticket action tools (4)
35
+ import { addTicketActionTool, listTicketActionsTool, holdTicketSlaTool, releaseTicketSlaTool, } from './ticket-actions.js';
31
36
  // Ticket custom field tools (2)
32
37
  import { listTicketCustomFieldsTool, getTicketFieldSchemaTool, } from './ticket-custom-fields.js';
33
38
  // Batch operations tools (5)
@@ -75,13 +80,14 @@ const allTools = [
75
80
  listAssetStatusesTool,
76
81
  listContactTypesTool,
77
82
  listAgentsTool,
78
- // Ticket reference data (5)
83
+ // Ticket reference data (6)
79
84
  listTicketTypesTool,
80
85
  getTicketTypeTool,
81
86
  listTicketStatusesTool,
82
87
  listTicketPrioritiesTool,
83
88
  listTicketCategoriesTool,
84
- // Tickets (7)
89
+ listTicketOutcomesTool,
90
+ // Tickets (8 — getTicketsBatchTool counted under Batch operations below)
85
91
  listTicketsTool,
86
92
  getTicketTool,
87
93
  searchTicketsTool,
@@ -89,9 +95,12 @@ const allTools = [
89
95
  updateTicketTool,
90
96
  closeTicketTool,
91
97
  deleteTicketTool,
92
- // Ticket actions (2)
98
+ validateCreateTicketTool,
99
+ // Ticket actions (4)
93
100
  addTicketActionTool,
94
101
  listTicketActionsTool,
102
+ holdTicketSlaTool,
103
+ releaseTicketSlaTool,
95
104
  // Ticket custom fields (2)
96
105
  listTicketCustomFieldsTool,
97
106
  getTicketFieldSchemaTool,
@@ -1 +1 @@
1
- {"version":3,"file":"registrations.js","sourceRoot":"","sources":["../../src/tools/registrations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registrations.js","sourceRoot":"","sources":["../../src/tools/registrations.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,12 @@ export declare const AddTicketActionArgsSchema: z.ZodObject<{
19
19
  outcome_id: z.ZodOptional<z.ZodNumber>;
20
20
  email_reply: z.ZodOptional<z.ZodBoolean>;
21
21
  hiddenfromuser: z.ZodOptional<z.ZodBoolean>;
22
+ timetaken: z.ZodOptional<z.ZodNumber>;
23
+ chargehours: z.ZodOptional<z.ZodNumber>;
24
+ nonchargeable: z.ZodOptional<z.ZodBoolean>;
25
+ chargerate: z.ZodOptional<z.ZodNumber>;
26
+ start_datetime: z.ZodOptional<z.ZodString>;
27
+ end_datetime: z.ZodOptional<z.ZodString>;
22
28
  format_options: z.ZodOptional<z.ZodObject<{
23
29
  format: z.ZodOptional<z.ZodEnum<{
24
30
  compact: "compact";
@@ -43,8 +49,48 @@ export declare const ListTicketActionsArgsSchema: z.ZodObject<{
43
49
  omit_empty: z.ZodOptional<z.ZodBoolean>;
44
50
  }, z.core.$strip>>;
45
51
  }, z.core.$strip>;
52
+ export declare const HoldTicketSlaArgsSchema: z.ZodObject<{
53
+ ticket_id: z.ZodNumber;
54
+ reason: z.ZodOptional<z.ZodString>;
55
+ format_options: z.ZodOptional<z.ZodObject<{
56
+ format: z.ZodOptional<z.ZodEnum<{
57
+ compact: "compact";
58
+ standard: "standard";
59
+ detailed: "detailed";
60
+ }>>;
61
+ fields: z.ZodOptional<z.ZodArray<z.ZodString>>;
62
+ omit_empty: z.ZodOptional<z.ZodBoolean>;
63
+ }, z.core.$strip>>;
64
+ }, z.core.$strip>;
65
+ export declare const ReleaseTicketSlaArgsSchema: z.ZodObject<{
66
+ ticket_id: 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>;
46
77
  export declare function addTicketAction(client: HaloPSAAPIClient, args: z.infer<typeof AddTicketActionArgsSchema>): Promise<string>;
47
78
  export declare function listTicketActions(client: HaloPSAAPIClient, args: z.infer<typeof ListTicketActionsArgsSchema>): Promise<string>;
79
+ /**
80
+ * Hold/Release SLA — uses the ticket's `onhold` boolean field directly.
81
+ *
82
+ * Most Halo tenants (incl. Wilner Tech) do NOT have configured SLA-Hold
83
+ * outcomes; SLA control is via the ticket's `onhold` field and the "On Hold"
84
+ * status (status_id=21 on Wilner Tech tenant — verify on yours). This is the
85
+ * write path the Halo UI's SLA toggle uses.
86
+ *
87
+ * No outcome discovery needed. Direct ticket update with onhold + optionally
88
+ * a note action recording the reason.
89
+ */
90
+ export declare function holdTicketSla(client: HaloPSAAPIClient, args: z.infer<typeof HoldTicketSlaArgsSchema>): Promise<string>;
91
+ export declare function releaseTicketSla(client: HaloPSAAPIClient, args: z.infer<typeof ReleaseTicketSlaArgsSchema>): Promise<string>;
48
92
  export declare const addTicketActionTool: ZodToolDefinition;
49
93
  export declare const listTicketActionsTool: ZodToolDefinition;
94
+ export declare const holdTicketSlaTool: ZodToolDefinition;
95
+ export declare const releaseTicketSlaTool: ZodToolDefinition;
50
96
  //# sourceMappingURL=ticket-actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ticket-actions.d.ts","sourceRoot":"","sources":["../../src/tools/ticket-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAevD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;iBAYpC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;iBAQtC,CAAC;AA2IH,wBAAsB,eAAe,CACnC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,GAC9C,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,GAChD,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAMD,eAAO,MAAM,mBAAmB,EAAE,iBAKjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,iBAKnC,CAAC"}
1
+ {"version":3,"file":"ticket-actions.d.ts","sourceRoot":"","sources":["../../src/tools/ticket-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAgBvD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;iBA4BpC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;iBAQtC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBAMlC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;iBAIrC,CAAC;AA0MH,wBAAsB,eAAe,CACnC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,GAC9C,OAAO,CAAC,MAAM,CAAC,CA0FjB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,GAChD,OAAO,CAAC,MAAM,CAAC,CA0BjB;AAaD;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,GAC/C,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAMD,eAAO,MAAM,mBAAmB,EAAE,iBAKjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,iBAKnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAK/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,iBAKlC,CAAC"}
@@ -12,9 +12,10 @@
12
12
  */
13
13
  import { z } from 'zod';
14
14
  import { HaloPSAError } from '../api/errors.js';
15
- import { formatResponse, stripWriteResponse } from '../utils/formatter.js';
15
+ import { formatResponse, stripWriteResponse, withCompactDefaults } from '../utils/formatter.js';
16
16
  import { TTL } from '../cache/memory-cache.js';
17
17
  import { FormatOptionsSchema } from '../schemas/common.js';
18
+ import { getOutcomesForTicketType } from './ticket-reference-data.js';
18
19
  // =============================================================================
19
20
  // Schemas
20
21
  // =============================================================================
@@ -29,6 +30,22 @@ export const AddTicketActionArgsSchema = z.object({
29
30
  .describe('If true, sends the note as an email reply to the ticket requester'),
30
31
  hiddenfromuser: z.boolean().optional()
31
32
  .describe('If true, hides the action from the customer portal'),
33
+ // Time-entry fields (Bug 1 — billing)
34
+ timetaken: z.number().min(0).optional()
35
+ // Hours must be non-negative — wire-key fix in v1.6.0 activated live billing path.
36
+ .describe('Hours worked on this action (decimal, >= 0). Drives ticket.timetaken rollup and billing.'),
37
+ chargehours: z.number().min(0).optional()
38
+ // Hours must be non-negative — wire-key fix in v1.6.0 activated live billing path.
39
+ .describe('Chargeable hours (>= 0; may differ from timetaken if some time is non-chargeable).'),
40
+ nonchargeable: z.boolean().optional()
41
+ .describe('True to mark this action non-billable. Default false.'),
42
+ chargerate: z.number().int().min(0).optional()
43
+ // non-negative integer FK per v1.6.0 billing-guard principle
44
+ .describe('Override hourly rate (integer FK; int32 per halopsa-swagger.json Actions.chargerate). Defaults to the ticket\'s contract rate.'),
45
+ start_datetime: z.string().optional()
46
+ .describe('ISO 8601 when work started (e.g., 2026-05-12T09:00:00Z). If both start/end supplied, timetaken can be derived.'),
47
+ end_datetime: z.string().optional()
48
+ .describe('ISO 8601 when work ended.'),
32
49
  format_options: FormatOptionsSchema,
33
50
  });
34
51
  export const ListTicketActionsArgsSchema = z.object({
@@ -40,53 +57,84 @@ export const ListTicketActionsArgsSchema = z.object({
40
57
  .describe('Page number (1-indexed)'),
41
58
  format_options: FormatOptionsSchema,
42
59
  });
60
+ export const HoldTicketSlaArgsSchema = z.object({
61
+ ticket_id: z.number().int()
62
+ .describe('HaloPSA ticket ID whose SLA clock should be held'),
63
+ reason: z.string().optional()
64
+ .describe('Note to attach to the hold action. Defaults to "SLA hold — waiting on customer".'),
65
+ format_options: FormatOptionsSchema,
66
+ });
67
+ export const ReleaseTicketSlaArgsSchema = z.object({
68
+ ticket_id: z.number().int()
69
+ .describe('HaloPSA ticket ID whose SLA clock should be released'),
70
+ format_options: FormatOptionsSchema,
71
+ });
43
72
  // =============================================================================
44
73
  // Helpers
45
74
  // =============================================================================
46
75
  const ACTION_PREVIEW_LEN = 200;
76
+ /**
77
+ * Default compact fields for add_halopsa_ticket_action (Bug 3 wiring).
78
+ * Matches the shape that compactAction() produces plus standard billing fields.
79
+ *
80
+ * Note: Halo's Actions schema does not declare a "date work performed" field
81
+ * separately from datetime (action submission). The field `actiondate` is NOT
82
+ * declared on components.schemas.Actions in halopsa-swagger.json — it appears
83
+ * only on components.schemas.Outgoingemail. Future v1.7+ work item: live-tenant
84
+ * probe to confirm whether datetime suffices for work-performed semantics.
85
+ */
86
+ const ACTION_COMPACT_DEFAULTS = [
87
+ 'id', 'ticket_id', 'outcome_id', 'outcome', 'timetaken', 'actionchargehours', 'chargerate',
88
+ 'who', 'datetime', 'note_preview',
89
+ ];
47
90
  /**
48
91
  * Regex to detect Halo 400 messages that indicate a missing or invalid
49
92
  * outcome_id — covers both "An Outcome must be entered for this Action"
50
93
  * and "You do not have access to this Action at the moment."
51
94
  */
52
95
  const OUTCOME_ERROR_RE = /Outcome must be entered|access to this Action/i;
53
- /**
54
- * Scan an arbitrary object for any key whose name contains "outcome"
55
- * (case-insensitive) and whose value is an array. Returns that array,
56
- * or an empty array if nothing is found.
57
- */
58
- function extractOutcomeHint(obj) {
59
- for (const key of Object.keys(obj)) {
60
- if (/outcome/i.test(key)) {
61
- const val = obj[key];
62
- if (Array.isArray(val)) {
63
- return val;
64
- }
65
- }
66
- }
67
- return [];
68
- }
69
96
  /**
70
97
  * When POST /Actions returns a 400 matching the outcome-required pattern,
71
98
  * fetch the parent ticket and its tickettype config, then return a structured
72
99
  * "refusal" object (not a thrown error) so the caller sees discovery info.
100
+ *
101
+ * Bug 4 enrichments:
102
+ * - tickettype_name resolved from cached /TicketType list (not from ticket.tickettype_name
103
+ * which is often absent); falls back to ticket.tickettype_name only if cache misses.
104
+ * - valid_outcomes_hint populated via getOutcomesForTicketType() helper (sorted by
105
+ * sequence then id, sliced to first 10), not via fragile extractOutcomeHint regex.
106
+ * - If any secondary lookup fails, discovery_warning documents what failed; the refusal
107
+ * is always returned (never re-thrown).
108
+ */
109
+ /**
110
+ * Clamp a halo error message to 500 characters for inclusion in refusal objects.
111
+ * 500 chars matches the bodyExcerpt budget in errors.ts and gives enough context
112
+ * to diagnose most API errors without bloating token output.
113
+ * If truncated, appends the ellipsis character and sets halo_error_truncated: true
114
+ * on the result object. Returns the (possibly clamped) message string.
73
115
  */
116
+ function clampHaloError(msg, result) {
117
+ const MAX = 500;
118
+ if (msg.length <= MAX)
119
+ return msg;
120
+ result['halo_error_truncated'] = true;
121
+ return msg.slice(0, MAX) + '…';
122
+ }
74
123
  async function buildOutcomeDiscoveryRefusal(client, ticketId, haloError) {
75
124
  const discoveryWarnings = [];
76
125
  // --- Step 1: fetch the parent ticket ---
77
126
  let tickettypeId;
78
- let tickettypeName;
127
+ let tickettypeNameFallback;
79
128
  try {
80
129
  const ticket = await client.get(`/Tickets/${ticketId}`, { includedetails: true });
81
130
  tickettypeId = ticket.tickettype_id;
82
- tickettypeName = ticket.tickettype_name;
131
+ tickettypeNameFallback = ticket.tickettype_name;
83
132
  }
84
133
  catch (innerErr) {
85
134
  const msg = innerErr instanceof Error ? innerErr.message : String(innerErr);
86
135
  discoveryWarnings.push('ticket lookup failed: ' + msg);
87
- return {
136
+ const earlyResult = {
88
137
  action_created: false,
89
- halo_error: haloError,
90
138
  diagnosis: 'outcome_id is required for this tickettype and was either missing or invalid',
91
139
  tickettype_id: null,
92
140
  tickettype_name: null,
@@ -95,29 +143,62 @@ async function buildOutcomeDiscoveryRefusal(client, ticketId, haloError) {
95
143
  remediation: 'Either retry with a valid outcome_id (check Halo admin: Configuration > Tickets > Outcomes), ' +
96
144
  'or fall back to update_halopsa_ticket to set details_html / status_id without going through the Actions surface.',
97
145
  };
146
+ earlyResult['halo_error'] = clampHaloError(haloError, earlyResult);
147
+ return earlyResult;
98
148
  }
99
- // --- Step 2: fetch the tickettype config ---
149
+ // --- Step 2: resolve tickettype_name from cached /TicketType list (Bug 4) ---
150
+ // ticket.tickettype_name is often absent from the detail response; the global
151
+ // tickettypes list (cached 1h) is more reliable.
152
+ let tickettypeName = null;
153
+ if (tickettypeId !== undefined) {
154
+ try {
155
+ const ttList = await client.getCached('/TicketType', { count: 500 }, {
156
+ enabled: true,
157
+ ttl: TTL.TICKET_TYPES,
158
+ keyPrefix: 'tickettypes:all',
159
+ });
160
+ const ttItems = Array.isArray(ttList)
161
+ ? ttList
162
+ : (ttList.tickettypes ?? []);
163
+ const found = ttItems.find((t) => t.id === tickettypeId);
164
+ tickettypeName = found?.name ?? tickettypeNameFallback ?? null;
165
+ }
166
+ catch (innerErr) {
167
+ const msg = innerErr instanceof Error ? innerErr.message : String(innerErr);
168
+ discoveryWarnings.push('tickettypes list lookup failed: ' + msg);
169
+ // Fall back to the field on the ticket (often absent)
170
+ tickettypeName = tickettypeNameFallback ?? null;
171
+ }
172
+ }
173
+ // --- Step 3: fetch valid outcomes via shared helper (Bug 4) ---
174
+ // Sort by sequence (ascending), then by id (ascending) as tiebreaker.
175
+ // Slice to first 10 for response compactness.
100
176
  let validOutcomesHint = [];
101
177
  if (tickettypeId !== undefined) {
102
178
  try {
103
- const ttConfig = await client.get(`/TicketType/${tickettypeId}`, { includedetails: true });
104
- validOutcomesHint = extractOutcomeHint(ttConfig);
179
+ const outcomes = await getOutcomesForTicketType(client, tickettypeId);
180
+ const sorted = outcomes.slice().sort((a, b) => {
181
+ const seqA = a.sequence ?? 999999;
182
+ const seqB = b.sequence ?? 999999;
183
+ return seqA !== seqB ? seqA - seqB : a.id - b.id;
184
+ });
185
+ validOutcomesHint = sorted.slice(0, 10).map((o) => ({ id: o.id, name: o.name }));
105
186
  }
106
187
  catch (innerErr) {
107
188
  const msg = innerErr instanceof Error ? innerErr.message : String(innerErr);
108
- discoveryWarnings.push('tickettype lookup failed: ' + msg);
189
+ discoveryWarnings.push('outcomes lookup failed: ' + msg);
109
190
  }
110
191
  }
111
192
  const result = {
112
193
  action_created: false,
113
- halo_error: haloError,
114
194
  diagnosis: 'outcome_id is required for this tickettype and was either missing or invalid',
115
195
  tickettype_id: tickettypeId ?? null,
116
- tickettype_name: tickettypeName ?? null,
196
+ tickettype_name: tickettypeName,
117
197
  valid_outcomes_hint: validOutcomesHint,
118
198
  remediation: 'Either retry with a valid outcome_id from the list above, ' +
119
199
  'or fall back to update_halopsa_ticket to set details_html / status_id without going through the Actions surface.',
120
200
  };
201
+ result['halo_error'] = clampHaloError(haloError, result);
121
202
  if (discoveryWarnings.length > 0) {
122
203
  result['discovery_warning'] = discoveryWarnings.join('; ');
123
204
  }
@@ -135,6 +216,13 @@ function compactAction(action) {
135
216
  who: action.who,
136
217
  datetime: action.datetime,
137
218
  outcome: action.outcome,
219
+ outcome_id: action.outcome_id,
220
+ // Q5 billing fields — must be carried through the compact projection so the
221
+ // caller can verify what hours/rate landed on the action (POST /Actions is
222
+ // at-most-once; the compact response is the only audit signal on success).
223
+ timetaken: action.timetaken,
224
+ actionchargehours: action.actionchargehours,
225
+ chargerate: action.chargerate,
138
226
  note_preview: note.length > ACTION_PREVIEW_LEN
139
227
  ? note.slice(0, ACTION_PREVIEW_LEN) + '…'
140
228
  : note,
@@ -163,6 +251,44 @@ export async function addTicketAction(client, args) {
163
251
  payload.email_reply = args.email_reply;
164
252
  if (args.hiddenfromuser !== undefined)
165
253
  payload.hiddenfromuser = args.hiddenfromuser;
254
+ // Time-entry fields. Caller-facing input names are mapped to Halo's documented
255
+ // Actions property names below. Verified 2026-05-12 against
256
+ // components.schemas.Actions in halopsa-swagger.json (508 properties):
257
+ // timetaken → timetaken (in Actions schema, swagger-confirmed)
258
+ // chargehours → actionchargehours (Actions uses `actionchargehours`,
259
+ // NOT `chargehours`; `chargehours` is
260
+ // on Faults/Faults_List (ticket-level
261
+ // rollup) — NOT on Actions schema)
262
+ // chargerate → chargerate (in Actions schema, int32 FK)
263
+ // nonchargeable → nonchargeable (NOT in swagger; zero occurrences in
264
+ // halopsa-swagger.json; accepted by
265
+ // empirical observation on live tenants.
266
+ // Documented Actions field is
267
+ // actionnonchargehours: number (not
268
+ // boolean). v1.8+ TODO: live-tenant
269
+ // probe before renaming.)
270
+ // start_datetime → start_datetime (NOT in swagger; observation only)
271
+ // end_datetime → end_datetime (NOT in swagger; observation only)
272
+ if (args.timetaken !== undefined)
273
+ payload.timetaken = args.timetaken;
274
+ // Map the caller-facing `chargehours` input to Halo's documented Actions
275
+ // property `actionchargehours`. `chargehours` is NOT declared on Actions —
276
+ // it is a ticket-level rollup field on components.schemas.Faults and
277
+ // components.schemas.Faults_List only. Sending `chargehours` on POST /Actions
278
+ // would be silently dropped by Halo's deserializer (unknown DataMember).
279
+ if (args.chargehours !== undefined)
280
+ payload.actionchargehours = args.chargehours;
281
+ // nonchargeable: undocumented on Actions schema in halopsa-swagger.json. Tenant-accepted
282
+ // alias observed empirically. Documented field is actionnonchargehours: number (not boolean).
283
+ // v1.8+ TODO: live-tenant probe before renaming.
284
+ if (args.nonchargeable !== undefined)
285
+ payload.nonchargeable = args.nonchargeable;
286
+ if (args.chargerate !== undefined)
287
+ payload.chargerate = args.chargerate;
288
+ if (args.start_datetime !== undefined)
289
+ payload.start_datetime = args.start_datetime;
290
+ if (args.end_datetime !== undefined)
291
+ payload.end_datetime = args.end_datetime;
166
292
  // Halo's array-body write may return `[{...}]` or `{...}` depending on
167
293
  // tenant — normalize to a single object before formatting.
168
294
  let raw;
@@ -173,9 +299,10 @@ export async function addTicketAction(client, args) {
173
299
  // When Halo returns 400 for a missing or invalid outcome_id, surface a
174
300
  // structured refusal with discovery info instead of re-throwing the raw
175
301
  // error. This lets the caller retry with a valid outcome_id.
176
- const haloMessage = error instanceof HaloPSAError ? error.message : String(error);
177
- if (OUTCOME_ERROR_RE.test(haloMessage)) {
178
- const refusal = await buildOutcomeDiscoveryRefusal(client, args.ticket_id, haloMessage);
302
+ const rawHaloMessage = error instanceof HaloPSAError ? error.message : String(error);
303
+ if (OUTCOME_ERROR_RE.test(rawHaloMessage)) {
304
+ const refusal = await buildOutcomeDiscoveryRefusal(client, args.ticket_id, rawHaloMessage);
305
+ // v1.7+ TODO: route through formatResponse() or apply scrubCredentials() before stringify. Low current risk: refusal fields are id+name+error_msg+remediation; CREDENTIAL_KEY_RE matches JSON keys, and Halo 400 messages on outcome failures empirically don't contain credential strings. Documented in 2026-05-12_review-protocol-validation.md.
179
306
  return JSON.stringify(refusal);
180
307
  }
181
308
  throw error;
@@ -184,7 +311,17 @@ export async function addTicketAction(client, args) {
184
311
  client.invalidateCache(`ticket-actions:${args.ticket_id}*`);
185
312
  client.invalidateCache(`ticket:${args.ticket_id}*`);
186
313
  const format = args.format_options?.format ?? 'compact';
187
- return formatResponse(stripWriteResponse(created, format, 'action'), { format });
314
+ // Fix 3: apply compactAction() BEFORE formatResponse on the compact path to
315
+ // ensure note_preview (synthesized, truncated) is present and the raw `note`
316
+ // body does not leak through Branch 2's extras-merge loop.
317
+ // For non-compact formats (detailed, raw), pass `created` directly so the
318
+ // caller sees all fields from the POST /Actions response.
319
+ const compacted = format === 'compact' ? compactAction(created) : created;
320
+ // Bug 3: wire per-tool compact defaults so action responses include billing
321
+ // fields (timetaken, actionchargehours) rather than being stripped by legacy compactItem().
322
+ // Pass full format_options so caller-supplied fields[] flow through to processItem.
323
+ const formatOpts = withCompactDefaults(args.format_options ?? { format: 'compact' }, ACTION_COMPACT_DEFAULTS);
324
+ return formatResponse(stripWriteResponse(compacted, format, 'action'), formatOpts);
188
325
  }
189
326
  export async function listTicketActions(client, args) {
190
327
  const params = { ticket_id: args.ticket_id };
@@ -207,11 +344,66 @@ export async function listTicketActions(client, args) {
207
344
  return formatResponse(items, formatOpts, { record_count });
208
345
  }
209
346
  // =============================================================================
347
+ // SLA Hold/Release uses direct ticket.onhold field — no outcome discovery needed.
348
+ // Most Halo tenants do not have configured SLA-Hold outcomes; the UI control
349
+ // just flips ticket.onhold via a direct field update. See holdTicketSla /
350
+ // releaseTicketSla below.
351
+ // =============================================================================
352
+ // =============================================================================
353
+ // SLA Hold/Release — Implementations
354
+ // =============================================================================
355
+ /**
356
+ * Hold/Release SLA — uses the ticket's `onhold` boolean field directly.
357
+ *
358
+ * Most Halo tenants (incl. Wilner Tech) do NOT have configured SLA-Hold
359
+ * outcomes; SLA control is via the ticket's `onhold` field and the "On Hold"
360
+ * status (status_id=21 on Wilner Tech tenant — verify on yours). This is the
361
+ * write path the Halo UI's SLA toggle uses.
362
+ *
363
+ * No outcome discovery needed. Direct ticket update with onhold + optionally
364
+ * a note action recording the reason.
365
+ */
366
+ export async function holdTicketSla(client, args) {
367
+ // Read-before-write merge to preserve other ticket fields under Halo's REPLACE semantics.
368
+ const existing = await client.get(`/Tickets/${args.ticket_id}`, { includedetails: true });
369
+ const payload = { ...existing, id: args.ticket_id, onhold: true };
370
+ await client.post('/Tickets', [payload]);
371
+ client.invalidateCache(`ticket:${args.ticket_id}*`);
372
+ client.invalidateCache('tickets:*');
373
+ const note = args.reason ?? 'SLA hold — waiting on customer';
374
+ // v1.7+ TODO: route through formatResponse() or apply scrubCredentials() before stringify.
375
+ // Low current risk: SLA hold/release response object fields are held+ticket_id+reason+note (audit prose);
376
+ // CREDENTIAL_KEY_RE matches JSON keys, and Halo 200 responses on onhold updates empirically
377
+ // don't contain credential strings. Documented in 2026-05-12_review-protocol-validation.md.
378
+ return JSON.stringify({
379
+ held: true,
380
+ ticket_id: args.ticket_id,
381
+ reason: note,
382
+ note: 'Halo flipped onhold=true via direct field update. To leave a visible audit-trail note, follow with add_halopsa_ticket_action(outcome_id=<your-note-outcome>, note).',
383
+ }, null, 2);
384
+ }
385
+ export async function releaseTicketSla(client, args) {
386
+ const existing = await client.get(`/Tickets/${args.ticket_id}`, { includedetails: true });
387
+ const payload = { ...existing, id: args.ticket_id, onhold: false };
388
+ await client.post('/Tickets', [payload]);
389
+ client.invalidateCache(`ticket:${args.ticket_id}*`);
390
+ client.invalidateCache('tickets:*');
391
+ // v1.7+ TODO: route through formatResponse() or apply scrubCredentials() before stringify.
392
+ // Low current risk: SLA hold/release response object fields are released+ticket_id+note (audit prose);
393
+ // CREDENTIAL_KEY_RE matches JSON keys, and Halo 200 responses on onhold updates empirically
394
+ // don't contain credential strings. Documented in 2026-05-12_review-protocol-validation.md.
395
+ return JSON.stringify({
396
+ released: true,
397
+ ticket_id: args.ticket_id,
398
+ note: 'Halo flipped onhold=false via direct field update.',
399
+ }, null, 2);
400
+ }
401
+ // =============================================================================
210
402
  // Tool Definitions
211
403
  // =============================================================================
212
404
  export const addTicketActionTool = {
213
405
  name: 'add_halopsa_ticket_action',
214
- description: 'Append an action (note, email reply, status change journal entry) to a HaloPSA ticket. POST /Actions with array body wrapper. Invalidates ticket and action caches.',
406
+ description: 'Append an action (note, email reply, status change journal entry, time entry) to a HaloPSA ticket. POST /Actions with array body wrapper. Supports time-entry billing fields: timetaken, chargehours, nonchargeable, chargerate, start_datetime, end_datetime. Invalidates ticket and action caches. Note: outcome_id is not pre-validated against the tickettype\'s allowed_actions allowlist; enforcement is server-side. Use list_halopsa_ticket_outcomes with the same tickettype_id to discover permitted outcomes before calling.',
215
407
  schema: AddTicketActionArgsSchema,
216
408
  handler: addTicketAction,
217
409
  };
@@ -221,4 +413,16 @@ export const listTicketActionsTool = {
221
413
  schema: ListTicketActionsArgsSchema,
222
414
  handler: listTicketActions,
223
415
  };
416
+ export const holdTicketSlaTool = {
417
+ name: 'hold_halopsa_ticket_sla',
418
+ description: 'Put a HaloPSA ticket SLA on hold (waiting on customer). Sets ticket.onhold=true via direct field update — does NOT require an SLA-Hold outcome to be configured. The reason argument is logged in the response but not posted as a separate action (use add_halopsa_ticket_action for an audit-trail note).',
419
+ schema: HoldTicketSlaArgsSchema,
420
+ handler: holdTicketSla,
421
+ };
422
+ export const releaseTicketSlaTool = {
423
+ name: 'release_halopsa_ticket_sla',
424
+ description: 'Releases the SLA hold on a HaloPSA ticket. Performs read-before-write merge to set onhold=false on the ticket. Direct write — no outcome lookup, no env var. Invalidates ticket and ticket_actions caches.',
425
+ schema: ReleaseTicketSlaArgsSchema,
426
+ handler: releaseTicketSla,
427
+ };
224
428
  //# sourceMappingURL=ticket-actions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ticket-actions.js","sourceRoot":"","sources":["../../src/tools/ticket-actions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ticket-actions.js","sourceRoot":"","sources":["../../src/tools/ticket-actions.ts"],"names":[],"mappings":"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"}