@t4dhg/mcp-factorial 7.0.1 → 8.2.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 (201) hide show
  1. package/README.md +321 -49
  2. package/dist/api/ats.d.ts +78 -0
  3. package/dist/api/ats.d.ts.map +1 -0
  4. package/dist/api/ats.js +173 -0
  5. package/dist/api/ats.js.map +1 -0
  6. package/dist/api/attendance.d.ts +27 -0
  7. package/dist/api/attendance.d.ts.map +1 -0
  8. package/dist/api/attendance.js +62 -0
  9. package/dist/api/attendance.js.map +1 -0
  10. package/dist/api/contracts.d.ts +40 -0
  11. package/dist/api/contracts.d.ts.map +1 -0
  12. package/dist/api/contracts.js +146 -0
  13. package/dist/api/contracts.js.map +1 -0
  14. package/dist/api/documents.d.ts +95 -0
  15. package/dist/api/documents.d.ts.map +1 -0
  16. package/dist/api/documents.js +265 -0
  17. package/dist/api/documents.js.map +1 -0
  18. package/dist/api/employees.d.ts +35 -0
  19. package/dist/api/employees.d.ts.map +1 -0
  20. package/dist/api/employees.js +116 -0
  21. package/dist/api/employees.js.map +1 -0
  22. package/dist/api/index.d.ts +22 -0
  23. package/dist/api/index.d.ts.map +1 -0
  24. package/dist/api/index.js +36 -0
  25. package/dist/api/index.js.map +1 -0
  26. package/dist/api/job-catalog.d.ts +21 -0
  27. package/dist/api/job-catalog.d.ts.map +1 -0
  28. package/dist/api/job-catalog.js +34 -0
  29. package/dist/api/job-catalog.js.map +1 -0
  30. package/dist/api/locations.d.ts +26 -0
  31. package/dist/api/locations.d.ts.map +1 -0
  32. package/dist/api/locations.js +59 -0
  33. package/dist/api/locations.js.map +1 -0
  34. package/dist/api/payroll.d.ts +30 -0
  35. package/dist/api/payroll.d.ts.map +1 -0
  36. package/dist/api/payroll.js +68 -0
  37. package/dist/api/payroll.js.map +1 -0
  38. package/dist/api/projects.d.ts +82 -0
  39. package/dist/api/projects.d.ts.map +1 -0
  40. package/dist/api/projects.js +193 -0
  41. package/dist/api/projects.js.map +1 -0
  42. package/dist/api/shared.d.ts +12 -0
  43. package/dist/api/shared.d.ts.map +1 -0
  44. package/dist/api/shared.js +17 -0
  45. package/dist/api/shared.js.map +1 -0
  46. package/dist/api/teams.d.ts +26 -0
  47. package/dist/api/teams.d.ts.map +1 -0
  48. package/dist/api/teams.js +59 -0
  49. package/dist/api/teams.js.map +1 -0
  50. package/dist/api/time-off.d.ts +47 -0
  51. package/dist/api/time-off.d.ts.map +1 -0
  52. package/dist/api/time-off.js +112 -0
  53. package/dist/api/time-off.js.map +1 -0
  54. package/dist/api/training.d.ts +62 -0
  55. package/dist/api/training.d.ts.map +1 -0
  56. package/dist/api/training.js +147 -0
  57. package/dist/api/training.js.map +1 -0
  58. package/dist/api/work-areas.d.ts +30 -0
  59. package/dist/api/work-areas.d.ts.map +1 -0
  60. package/dist/api/work-areas.js +71 -0
  61. package/dist/api/work-areas.js.map +1 -0
  62. package/dist/api.d.ts +3 -434
  63. package/dist/api.d.ts.map +1 -1
  64. package/dist/api.js +3 -1154
  65. package/dist/api.js.map +1 -1
  66. package/dist/audit.d.ts +8 -3
  67. package/dist/audit.d.ts.map +1 -1
  68. package/dist/audit.js +8 -3
  69. package/dist/audit.js.map +1 -1
  70. package/dist/index.d.ts +6 -13
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +6 -3701
  73. package/dist/index.js.map +1 -1
  74. package/dist/oauth.d.ts +63 -0
  75. package/dist/oauth.d.ts.map +1 -0
  76. package/dist/oauth.js +143 -0
  77. package/dist/oauth.js.map +1 -0
  78. package/dist/schemas/ats.d.ts +326 -0
  79. package/dist/schemas/ats.d.ts.map +1 -0
  80. package/dist/schemas/ats.js +121 -0
  81. package/dist/schemas/ats.js.map +1 -0
  82. package/dist/schemas/documents.d.ts +78 -0
  83. package/dist/schemas/documents.d.ts.map +1 -0
  84. package/dist/schemas/documents.js +34 -0
  85. package/dist/schemas/documents.js.map +1 -0
  86. package/dist/schemas/employees.d.ts +528 -0
  87. package/dist/schemas/employees.d.ts.map +1 -0
  88. package/dist/schemas/employees.js +206 -0
  89. package/dist/schemas/employees.js.map +1 -0
  90. package/dist/schemas/index.d.ts +18 -0
  91. package/dist/schemas/index.d.ts.map +1 -0
  92. package/dist/schemas/index.js +28 -0
  93. package/dist/schemas/index.js.map +1 -0
  94. package/dist/schemas/job-catalog.d.ts +57 -0
  95. package/dist/schemas/job-catalog.d.ts.map +1 -0
  96. package/dist/schemas/job-catalog.js +27 -0
  97. package/dist/schemas/job-catalog.js.map +1 -0
  98. package/dist/schemas/payroll.d.ts +98 -0
  99. package/dist/schemas/payroll.d.ts.map +1 -0
  100. package/dist/schemas/payroll.js +43 -0
  101. package/dist/schemas/payroll.js.map +1 -0
  102. package/dist/schemas/projects.d.ts +277 -0
  103. package/dist/schemas/projects.d.ts.map +1 -0
  104. package/dist/schemas/projects.js +114 -0
  105. package/dist/schemas/projects.js.map +1 -0
  106. package/dist/schemas/shared.d.ts +42 -0
  107. package/dist/schemas/shared.d.ts.map +1 -0
  108. package/dist/schemas/shared.js +65 -0
  109. package/dist/schemas/shared.js.map +1 -0
  110. package/dist/schemas/time-off.d.ts +286 -0
  111. package/dist/schemas/time-off.d.ts.map +1 -0
  112. package/dist/schemas/time-off.js +111 -0
  113. package/dist/schemas/time-off.js.map +1 -0
  114. package/dist/schemas/training.d.ts +223 -0
  115. package/dist/schemas/training.d.ts.map +1 -0
  116. package/dist/schemas/training.js +88 -0
  117. package/dist/schemas/training.js.map +1 -0
  118. package/dist/schemas/work-areas.d.ts +71 -0
  119. package/dist/schemas/work-areas.d.ts.map +1 -0
  120. package/dist/schemas/work-areas.js +30 -0
  121. package/dist/schemas/work-areas.js.map +1 -0
  122. package/dist/schemas.d.ts +4 -1879
  123. package/dist/schemas.d.ts.map +1 -1
  124. package/dist/schemas.js +4 -755
  125. package/dist/schemas.js.map +1 -1
  126. package/dist/tool-utils.d.ts +0 -14
  127. package/dist/tool-utils.d.ts.map +1 -1
  128. package/dist/tool-utils.js +5 -18
  129. package/dist/tool-utils.js.map +1 -1
  130. package/dist/tools/ats.d.ts +6 -0
  131. package/dist/tools/ats.d.ts.map +1 -0
  132. package/dist/tools/ats.js +206 -0
  133. package/dist/tools/ats.js.map +1 -0
  134. package/dist/tools/attendance.d.ts +6 -0
  135. package/dist/tools/attendance.d.ts.map +1 -0
  136. package/dist/tools/attendance.js +86 -0
  137. package/dist/tools/attendance.js.map +1 -0
  138. package/dist/tools/contracts.d.ts +6 -0
  139. package/dist/tools/contracts.d.ts.map +1 -0
  140. package/dist/tools/contracts.js +63 -0
  141. package/dist/tools/contracts.js.map +1 -0
  142. package/dist/tools/documents.d.ts +6 -0
  143. package/dist/tools/documents.d.ts.map +1 -0
  144. package/dist/tools/documents.js +135 -0
  145. package/dist/tools/documents.js.map +1 -0
  146. package/dist/tools/employees.d.ts +6 -0
  147. package/dist/tools/employees.d.ts.map +1 -0
  148. package/dist/tools/employees.js +125 -0
  149. package/dist/tools/employees.js.map +1 -0
  150. package/dist/tools/index.d.ts +17 -0
  151. package/dist/tools/index.d.ts.map +1 -0
  152. package/dist/tools/index.js +221 -0
  153. package/dist/tools/index.js.map +1 -0
  154. package/dist/tools/job-catalog.d.ts +6 -0
  155. package/dist/tools/job-catalog.d.ts.map +1 -0
  156. package/dist/tools/job-catalog.js +39 -0
  157. package/dist/tools/job-catalog.js.map +1 -0
  158. package/dist/tools/locations.d.ts +6 -0
  159. package/dist/tools/locations.d.ts.map +1 -0
  160. package/dist/tools/locations.js +93 -0
  161. package/dist/tools/locations.js.map +1 -0
  162. package/dist/tools/payroll.d.ts +6 -0
  163. package/dist/tools/payroll.d.ts.map +1 -0
  164. package/dist/tools/payroll.js +76 -0
  165. package/dist/tools/payroll.js.map +1 -0
  166. package/dist/tools/projects.d.ts +6 -0
  167. package/dist/tools/projects.d.ts.map +1 -0
  168. package/dist/tools/projects.js +203 -0
  169. package/dist/tools/projects.js.map +1 -0
  170. package/dist/tools/shared.d.ts +84 -0
  171. package/dist/tools/shared.d.ts.map +1 -0
  172. package/dist/tools/shared.js +164 -0
  173. package/dist/tools/shared.js.map +1 -0
  174. package/dist/tools/teams.d.ts +6 -0
  175. package/dist/tools/teams.d.ts.map +1 -0
  176. package/dist/tools/teams.js +81 -0
  177. package/dist/tools/teams.js.map +1 -0
  178. package/dist/tools/time-off.d.ts +6 -0
  179. package/dist/tools/time-off.d.ts.map +1 -0
  180. package/dist/tools/time-off.js +144 -0
  181. package/dist/tools/time-off.js.map +1 -0
  182. package/dist/tools/training.d.ts +6 -0
  183. package/dist/tools/training.d.ts.map +1 -0
  184. package/dist/tools/training.js +160 -0
  185. package/dist/tools/training.js.map +1 -0
  186. package/dist/tools/work-areas.d.ts +6 -0
  187. package/dist/tools/work-areas.d.ts.map +1 -0
  188. package/dist/tools/work-areas.js +85 -0
  189. package/dist/tools/work-areas.js.map +1 -0
  190. package/dist/types.d.ts +1 -1
  191. package/dist/types.d.ts.map +1 -1
  192. package/dist/utils.d.ts +35 -0
  193. package/dist/utils.d.ts.map +1 -1
  194. package/dist/utils.js +97 -0
  195. package/dist/utils.js.map +1 -1
  196. package/dist/write-safety.d.ts +229 -2
  197. package/dist/write-safety.d.ts.map +1 -1
  198. package/dist/write-safety.js +42 -3
  199. package/dist/write-safety.js.map +1 -1
  200. package/llms.txt +2 -2
  201. package/package.json +2 -2
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Work Areas tool registration
3
+ */
4
+ import * as z from 'zod';
5
+ import { textResponse, formatToolError } from '../tool-utils.js';
6
+ import { listWorkAreas, getWorkArea, createWorkArea, updateWorkArea, archiveWorkArea, unarchiveWorkArea, } from '../api/index.js';
7
+ export function registerWorkAreasTool(server) {
8
+ server.registerTool('factorial_work_areas', {
9
+ title: 'FactorialHR Work Areas',
10
+ description: 'Manage work areas within locations',
11
+ inputSchema: {
12
+ action: z
13
+ .enum(['list', 'get', 'create', 'update', 'archive', 'unarchive'])
14
+ .describe('Action'),
15
+ id: z.number().optional().describe('Work area ID'),
16
+ location_id: z.number().optional().describe('Location ID'),
17
+ name: z.string().optional().describe('Work area name'),
18
+ description: z.string().optional().describe('Description'),
19
+ page: z.number().optional().default(1).describe('Page number'),
20
+ limit: z.number().optional().default(100).describe('Items per page'),
21
+ },
22
+ }, async (args) => {
23
+ try {
24
+ switch (args.action) {
25
+ case 'list': {
26
+ const result = await listWorkAreas({ page: args.page, limit: args.limit });
27
+ // Filter by location_id client-side if specified
28
+ let data = result.data;
29
+ if (args.location_id) {
30
+ data = data.filter(w => w.location_id === args.location_id);
31
+ }
32
+ const summary = data.map(w => ({
33
+ id: w.id,
34
+ name: w.name,
35
+ location_id: w.location_id,
36
+ archived: w.archived,
37
+ }));
38
+ return textResponse(`Found ${summary.length} work areas:\n\n${JSON.stringify(summary, null, 2)}`);
39
+ }
40
+ case 'get': {
41
+ if (!args.id)
42
+ return textResponse('Error: id is required');
43
+ const workArea = await getWorkArea(args.id);
44
+ return textResponse(`Work area details:\n\n${JSON.stringify(workArea, null, 2)}`);
45
+ }
46
+ case 'create': {
47
+ if (!args.location_id || !args.name) {
48
+ return textResponse('Error: location_id and name are required');
49
+ }
50
+ const workArea = await createWorkArea({
51
+ location_id: args.location_id,
52
+ name: args.name,
53
+ description: args.description,
54
+ });
55
+ return textResponse(`Work area created:\n\n${JSON.stringify(workArea, null, 2)}`);
56
+ }
57
+ case 'update': {
58
+ if (!args.id)
59
+ return textResponse('Error: id is required');
60
+ const workArea = await updateWorkArea(args.id, {
61
+ name: args.name,
62
+ description: args.description,
63
+ });
64
+ return textResponse(`Work area updated:\n\n${JSON.stringify(workArea, null, 2)}`);
65
+ }
66
+ case 'archive': {
67
+ if (!args.id)
68
+ return textResponse('Error: id is required');
69
+ const workArea = await archiveWorkArea(args.id);
70
+ return textResponse(`Work area archived:\n\n${JSON.stringify(workArea, null, 2)}`);
71
+ }
72
+ case 'unarchive': {
73
+ if (!args.id)
74
+ return textResponse('Error: id is required');
75
+ const workArea = await unarchiveWorkArea(args.id);
76
+ return textResponse(`Work area unarchived:\n\n${JSON.stringify(workArea, null, 2)}`);
77
+ }
78
+ }
79
+ }
80
+ catch (error) {
81
+ return formatToolError(error);
82
+ }
83
+ });
84
+ }
85
+ //# sourceMappingURL=work-areas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-areas.js","sourceRoot":"","sources":["../../src/tools/work-areas.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Re-exports types from schemas for backward compatibility
5
5
  * and adds additional utility types.
6
6
  */
7
- export type { Employee, Team, Location, Contract, Leave, LeaveType, Allowance, Shift, Folder, Document, JobRole, JobLevel, } from './schemas.js';
7
+ export type { Employee, Team, Location, Contract, ContractSummary, Leave, LeaveType, Allowance, Shift, Folder, Document, JobRole, JobLevel, } from './schemas.js';
8
8
  export type { PaginationInput, PaginationParams, PaginationMeta, PaginatedResponse, } from './pagination.js';
9
9
  /**
10
10
  * Leave status options
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,SAAS,EACT,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,QAAQ,GACT,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,KAAK,EACL,SAAS,EACT,SAAS,EACT,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,QAAQ,GACT,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB"}
package/dist/utils.d.ts CHANGED
@@ -30,4 +30,39 @@ export declare function validatePositiveNumber(value: unknown, fieldName: string
30
30
  * @throws Error if the value is invalid
31
31
  */
32
32
  export declare function validateNonEmptyString(value: unknown, fieldName: string): string;
33
+ /**
34
+ * Build a safe output path for a file downloaded from the Factorial API
35
+ *
36
+ * Document names come from Factorial metadata and can be set by anyone with
37
+ * document-upload rights in the tenant, so they are untrusted input. Only the
38
+ * final path segment is kept, and the resolved path is checked to make sure it
39
+ * stays inside the output directory.
40
+ *
41
+ * Both `/` and `\` are treated as separators on every platform. A backslash is
42
+ * a legal character in a POSIX filename, so a document genuinely named
43
+ * `report\final.pdf` is saved as `final.pdf` on Linux and macOS. That is a
44
+ * deliberate trade: downloaded files get carried onto other systems, and losing
45
+ * part of a rare filename is cheaper than honouring a separator somewhere else.
46
+ *
47
+ * @param outputDir - Directory the file must be written into
48
+ * @param filename - Untrusted filename taken from API metadata
49
+ * @param fallbackName - Name to use when the filename sanitizes to nothing usable
50
+ * @returns An absolute path inside outputDir
51
+ * @throws Error if the resolved path would escape outputDir
52
+ */
53
+ export declare function resolveSafeOutputPath(outputDir: string, filename: string, fallbackName: string): string;
54
+ /**
55
+ * Write a file, picking a free name rather than replacing an existing one
56
+ *
57
+ * Downloaded filenames come from tenant-controlled metadata, so a download can
58
+ * otherwise land on an existing file the caller cares about, and two documents
59
+ * sharing a name would silently collapse into one. The `wx` flag fails if the
60
+ * path already exists, so the loop settles on the first free "name (n).ext".
61
+ *
62
+ * @param preferredPath - Where the file should go if nothing is there
63
+ * @param buffer - File contents
64
+ * @returns The path actually written
65
+ * @throws Error if no free name is found, or on any non-EEXIST write failure
66
+ */
67
+ export declare function writeWithoutOverwriting(preferredPath: string, buffer: Buffer): Promise<string>;
33
68
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKhF"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAKpE;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAKhF;AAsBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,MAAM,CAiCR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
package/dist/utils.js CHANGED
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Provides common validation and helper functions used across the codebase.
5
5
  */
6
+ import * as path from 'node:path';
6
7
  /**
7
8
  * Validate that a value is a positive integer ID
8
9
  *
@@ -45,4 +46,100 @@ export function validateNonEmptyString(value, fieldName) {
45
46
  }
46
47
  return value.trim();
47
48
  }
49
+ /**
50
+ * Shorten a filename to a byte budget, keeping its extension
51
+ *
52
+ * Counts bytes rather than characters, since the filesystem limit is in bytes
53
+ * and a name can be entirely multi-byte.
54
+ */
55
+ function truncateFilename(name, maxBytes) {
56
+ if (Buffer.byteLength(name, 'utf8') <= maxBytes)
57
+ return name;
58
+ const extension = path.extname(name).slice(0, maxBytes);
59
+ const budget = maxBytes - Buffer.byteLength(extension, 'utf8');
60
+ let stem = name.slice(0, name.length - extension.length);
61
+ while (Buffer.byteLength(stem, 'utf8') > budget) {
62
+ stem = stem.slice(0, -1);
63
+ }
64
+ return `${stem}${extension}`;
65
+ }
66
+ /**
67
+ * Build a safe output path for a file downloaded from the Factorial API
68
+ *
69
+ * Document names come from Factorial metadata and can be set by anyone with
70
+ * document-upload rights in the tenant, so they are untrusted input. Only the
71
+ * final path segment is kept, and the resolved path is checked to make sure it
72
+ * stays inside the output directory.
73
+ *
74
+ * Both `/` and `\` are treated as separators on every platform. A backslash is
75
+ * a legal character in a POSIX filename, so a document genuinely named
76
+ * `report\final.pdf` is saved as `final.pdf` on Linux and macOS. That is a
77
+ * deliberate trade: downloaded files get carried onto other systems, and losing
78
+ * part of a rare filename is cheaper than honouring a separator somewhere else.
79
+ *
80
+ * @param outputDir - Directory the file must be written into
81
+ * @param filename - Untrusted filename taken from API metadata
82
+ * @param fallbackName - Name to use when the filename sanitizes to nothing usable
83
+ * @returns An absolute path inside outputDir
84
+ * @throws Error if the resolved path would escape outputDir
85
+ */
86
+ export function resolveSafeOutputPath(outputDir, filename, fallbackName) {
87
+ const lastSegment = filename.split(/[/\\]/).pop() ?? '';
88
+ // Drop control characters, which the filesystem rejects outright (a NUL makes
89
+ // fs.writeFile throw), and cap the length, since most filesystems limit a
90
+ // single path component to 255 bytes and reject anything longer.
91
+ const printable = [...lastSegment]
92
+ .filter(character => {
93
+ const code = character.charCodeAt(0);
94
+ return code > 31 && code !== 127;
95
+ })
96
+ .join('');
97
+ const cleaned = truncateFilename(printable.trim(), 200);
98
+ const safeName = cleaned === '' || cleaned === '.' || cleaned === '..' ? fallbackName : cleaned;
99
+ const baseDir = path.resolve(outputDir);
100
+ const outputPath = path.resolve(baseDir, safeName);
101
+ const relative = path.relative(baseDir, outputPath);
102
+ // Compare whole path segments: a file legitimately named "..archive.pdf"
103
+ // starts with ".." without escaping anything.
104
+ const escapesOutputDir = relative === '' ||
105
+ relative === '..' ||
106
+ relative.startsWith(`..${path.sep}`) ||
107
+ path.isAbsolute(relative);
108
+ if (escapesOutputDir) {
109
+ throw new Error(`Refusing to write a document outside the output directory: ${filename}`);
110
+ }
111
+ return outputPath;
112
+ }
113
+ /**
114
+ * Write a file, picking a free name rather than replacing an existing one
115
+ *
116
+ * Downloaded filenames come from tenant-controlled metadata, so a download can
117
+ * otherwise land on an existing file the caller cares about, and two documents
118
+ * sharing a name would silently collapse into one. The `wx` flag fails if the
119
+ * path already exists, so the loop settles on the first free "name (n).ext".
120
+ *
121
+ * @param preferredPath - Where the file should go if nothing is there
122
+ * @param buffer - File contents
123
+ * @returns The path actually written
124
+ * @throws Error if no free name is found, or on any non-EEXIST write failure
125
+ */
126
+ export async function writeWithoutOverwriting(preferredPath, buffer) {
127
+ const fs = await import('fs/promises');
128
+ const directory = path.dirname(preferredPath);
129
+ const extension = path.extname(preferredPath);
130
+ const stem = path.basename(preferredPath, extension);
131
+ for (let attempt = 0; attempt < 100; attempt++) {
132
+ const candidate = attempt === 0 ? preferredPath : path.join(directory, `${stem} (${attempt})${extension}`);
133
+ try {
134
+ await fs.writeFile(candidate, buffer, { flag: 'wx' });
135
+ return candidate;
136
+ }
137
+ catch (error) {
138
+ if (error.code !== 'EEXIST')
139
+ throw error;
140
+ }
141
+ }
142
+ throw new Error(`Could not find a free filename for ${preferredPath} after 100 attempts. ` +
143
+ 'Choose a different output_dir or clear the existing files.');
144
+ }
48
145
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,EAAW,EAAE,YAAoB;IAC1D,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,WAAW,YAAY,yCAAyC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc,EAAE,SAAiB;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,qCAAqC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAc,EAAE,SAAiB;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,WAAW,SAAS,sCAAsC,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,12 @@ export interface OperationPolicy {
25
25
  risk: OperationRisk;
26
26
  /** Whether explicit confirmation is required */
27
27
  requiresConfirmation: boolean;
28
- /** Whether to show a preview before executing */
28
+ /**
29
+ * Whether to show a preview before executing
30
+ *
31
+ * Not currently consumed anywhere: no code path reads this field. It records
32
+ * an intent for a preview step that does not exist yet.
33
+ */
29
34
  requiresPreview: boolean;
30
35
  /** Maximum number of records that can be affected in batch */
31
36
  maxBatchSize?: number;
@@ -37,6 +42,226 @@ export interface OperationPolicy {
37
42
  /**
38
43
  * Default policies for write operations
39
44
  */
45
+ declare const POLICIES: {
46
+ create_employee: {
47
+ risk: OperationRisk.MEDIUM;
48
+ requiresConfirmation: false;
49
+ requiresPreview: true;
50
+ impactDescription: string;
51
+ };
52
+ update_employee: {
53
+ risk: OperationRisk.LOW;
54
+ requiresConfirmation: false;
55
+ requiresPreview: true;
56
+ impactDescription: string;
57
+ };
58
+ terminate_employee: {
59
+ risk: OperationRisk.HIGH;
60
+ requiresConfirmation: true;
61
+ requiresPreview: true;
62
+ impactDescription: string;
63
+ };
64
+ create_team: {
65
+ risk: OperationRisk.MEDIUM;
66
+ requiresConfirmation: false;
67
+ requiresPreview: true;
68
+ impactDescription: string;
69
+ };
70
+ update_team: {
71
+ risk: OperationRisk.LOW;
72
+ requiresConfirmation: false;
73
+ requiresPreview: true;
74
+ impactDescription: string;
75
+ };
76
+ delete_team: {
77
+ risk: OperationRisk.HIGH;
78
+ requiresConfirmation: true;
79
+ requiresPreview: true;
80
+ impactDescription: string;
81
+ };
82
+ add_team_member: {
83
+ risk: OperationRisk.LOW;
84
+ requiresConfirmation: false;
85
+ requiresPreview: false;
86
+ impactDescription: string;
87
+ };
88
+ remove_team_member: {
89
+ risk: OperationRisk.LOW;
90
+ requiresConfirmation: false;
91
+ requiresPreview: false;
92
+ impactDescription: string;
93
+ };
94
+ create_location: {
95
+ risk: OperationRisk.MEDIUM;
96
+ requiresConfirmation: false;
97
+ requiresPreview: true;
98
+ impactDescription: string;
99
+ };
100
+ update_location: {
101
+ risk: OperationRisk.LOW;
102
+ requiresConfirmation: false;
103
+ requiresPreview: true;
104
+ impactDescription: string;
105
+ };
106
+ delete_location: {
107
+ risk: OperationRisk.HIGH;
108
+ requiresConfirmation: true;
109
+ requiresPreview: true;
110
+ impactDescription: string;
111
+ };
112
+ create_leave: {
113
+ risk: OperationRisk.MEDIUM;
114
+ requiresConfirmation: false;
115
+ requiresPreview: true;
116
+ impactDescription: string;
117
+ };
118
+ update_leave: {
119
+ risk: OperationRisk.LOW;
120
+ requiresConfirmation: false;
121
+ requiresPreview: true;
122
+ impactDescription: string;
123
+ };
124
+ cancel_leave: {
125
+ risk: OperationRisk.MEDIUM;
126
+ requiresConfirmation: true;
127
+ requiresPreview: true;
128
+ impactDescription: string;
129
+ };
130
+ approve_leave: {
131
+ risk: OperationRisk.MEDIUM;
132
+ requiresConfirmation: false;
133
+ requiresPreview: true;
134
+ impactDescription: string;
135
+ };
136
+ reject_leave: {
137
+ risk: OperationRisk.MEDIUM;
138
+ requiresConfirmation: true;
139
+ requiresPreview: true;
140
+ impactDescription: string;
141
+ };
142
+ create_shift: {
143
+ risk: OperationRisk.LOW;
144
+ requiresConfirmation: false;
145
+ requiresPreview: false;
146
+ impactDescription: string;
147
+ };
148
+ update_shift: {
149
+ risk: OperationRisk.LOW;
150
+ requiresConfirmation: false;
151
+ requiresPreview: false;
152
+ impactDescription: string;
153
+ };
154
+ delete_shift: {
155
+ risk: OperationRisk.MEDIUM;
156
+ requiresConfirmation: true;
157
+ requiresPreview: true;
158
+ impactDescription: string;
159
+ };
160
+ upload_document: {
161
+ risk: OperationRisk.MEDIUM;
162
+ requiresConfirmation: false;
163
+ requiresPreview: true;
164
+ impactDescription: string;
165
+ };
166
+ update_document: {
167
+ risk: OperationRisk.LOW;
168
+ requiresConfirmation: false;
169
+ requiresPreview: false;
170
+ impactDescription: string;
171
+ };
172
+ delete_document: {
173
+ risk: OperationRisk.HIGH;
174
+ requiresConfirmation: true;
175
+ requiresPreview: true;
176
+ impactDescription: string;
177
+ };
178
+ create_project: {
179
+ risk: OperationRisk.MEDIUM;
180
+ requiresConfirmation: false;
181
+ requiresPreview: true;
182
+ impactDescription: string;
183
+ };
184
+ update_project: {
185
+ risk: OperationRisk.LOW;
186
+ requiresConfirmation: false;
187
+ requiresPreview: true;
188
+ impactDescription: string;
189
+ };
190
+ delete_project: {
191
+ risk: OperationRisk.HIGH;
192
+ requiresConfirmation: true;
193
+ requiresPreview: true;
194
+ impactDescription: string;
195
+ };
196
+ delete_task: {
197
+ risk: OperationRisk.MEDIUM;
198
+ requiresConfirmation: true;
199
+ requiresPreview: true;
200
+ impactDescription: string;
201
+ };
202
+ delete_time: {
203
+ risk: OperationRisk.MEDIUM;
204
+ requiresConfirmation: true;
205
+ requiresPreview: true;
206
+ impactDescription: string;
207
+ };
208
+ remove_project_worker: {
209
+ risk: OperationRisk.MEDIUM;
210
+ requiresConfirmation: true;
211
+ requiresPreview: true;
212
+ impactDescription: string;
213
+ };
214
+ create_job_posting: {
215
+ risk: OperationRisk.MEDIUM;
216
+ requiresConfirmation: false;
217
+ requiresPreview: true;
218
+ impactDescription: string;
219
+ };
220
+ delete_job_posting: {
221
+ risk: OperationRisk.HIGH;
222
+ requiresConfirmation: true;
223
+ requiresPreview: true;
224
+ impactDescription: string;
225
+ };
226
+ delete_candidate: {
227
+ risk: OperationRisk.HIGH;
228
+ requiresConfirmation: true;
229
+ requiresPreview: true;
230
+ impactDescription: string;
231
+ };
232
+ delete_application: {
233
+ risk: OperationRisk.HIGH;
234
+ requiresConfirmation: true;
235
+ requiresPreview: true;
236
+ impactDescription: string;
237
+ };
238
+ delete_training: {
239
+ risk: OperationRisk.HIGH;
240
+ requiresConfirmation: true;
241
+ requiresPreview: true;
242
+ impactDescription: string;
243
+ };
244
+ delete_session: {
245
+ risk: OperationRisk.MEDIUM;
246
+ requiresConfirmation: true;
247
+ requiresPreview: true;
248
+ impactDescription: string;
249
+ };
250
+ remove_enrollment: {
251
+ risk: OperationRisk.MEDIUM;
252
+ requiresConfirmation: true;
253
+ requiresPreview: true;
254
+ impactDescription: string;
255
+ };
256
+ };
257
+ /**
258
+ * Names of operations that have an explicit policy defined above
259
+ *
260
+ * Confirmation gates take this type rather than a bare string, so gating an
261
+ * operation that has no policy entry is a compile error instead of a silent
262
+ * fall-through to the permissive default policy.
263
+ */
264
+ export type OperationName = keyof typeof POLICIES;
40
265
  export declare const OPERATION_POLICIES: Record<string, OperationPolicy>;
41
266
  /**
42
267
  * Get the policy for an operation
@@ -47,7 +272,9 @@ export declare function getOperationPolicy(operationName: string): OperationPoli
47
272
  */
48
273
  export declare function requiresConfirmation(operationName: string): boolean;
49
274
  /**
50
- * Get a warning message for high-risk operations
275
+ * Get a warning message for high-risk operations, and for any operation that
276
+ * requires confirmation regardless of its risk level
51
277
  */
52
278
  export declare function getWarningMessage(operationName: string): string | null;
279
+ export {};
53
280
  //# sourceMappingURL=write-safety.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"write-safety.d.ts","sourceRoot":"","sources":["../src/write-safety.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,oBAAY,aAAa;IACvB,qEAAqE;IACrE,GAAG,QAAQ;IACX,wEAAwE;IACxE,MAAM,WAAW;IACjB,gEAAgE;IAChE,IAAI,SAAS;IACb,kFAAkF;IAClF,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,gDAAgD;IAChD,oBAAoB,EAAE,OAAO,CAAC;IAC9B,iDAAiD;IACjD,eAAe,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAgM9D,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CASzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAatE"}
1
+ {"version":3,"file":"write-safety.d.ts","sourceRoot":"","sources":["../src/write-safety.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,oBAAY,aAAa;IACvB,qEAAqE;IACrE,GAAG,QAAQ;IACX,wEAAwE;IACxE,MAAM,WAAW;IACjB,gEAAgE;IAChE,IAAI,SAAS;IACb,kFAAkF;IAClF,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,gDAAgD;IAChD,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsO6B,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,QAAQ,CAAC;AAElD,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAY,CAAC;AAE5E;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CASzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAetE"}
@@ -21,7 +21,7 @@ export var OperationRisk;
21
21
  /**
22
22
  * Default policies for write operations
23
23
  */
24
- export const OPERATION_POLICIES = {
24
+ const POLICIES = {
25
25
  // Employee operations
26
26
  create_employee: {
27
27
  risk: OperationRisk.MEDIUM,
@@ -179,6 +179,24 @@ export const OPERATION_POLICIES = {
179
179
  requiresPreview: true,
180
180
  impactDescription: 'Deletes the project and all associated tasks/time records',
181
181
  },
182
+ delete_task: {
183
+ risk: OperationRisk.MEDIUM,
184
+ requiresConfirmation: true,
185
+ requiresPreview: true,
186
+ impactDescription: 'Deletes the project task',
187
+ },
188
+ delete_time: {
189
+ risk: OperationRisk.MEDIUM,
190
+ requiresConfirmation: true,
191
+ requiresPreview: true,
192
+ impactDescription: 'Deletes the time record',
193
+ },
194
+ remove_project_worker: {
195
+ risk: OperationRisk.MEDIUM,
196
+ requiresConfirmation: true,
197
+ requiresPreview: true,
198
+ impactDescription: "Deletes the employee's assignment to the project. Time records are recorded against this assignment",
199
+ },
182
200
  // ATS operations
183
201
  create_job_posting: {
184
202
  risk: OperationRisk.MEDIUM,
@@ -198,6 +216,12 @@ export const OPERATION_POLICIES = {
198
216
  requiresPreview: true,
199
217
  impactDescription: 'Permanently deletes the candidate record',
200
218
  },
219
+ delete_application: {
220
+ risk: OperationRisk.HIGH,
221
+ requiresConfirmation: true,
222
+ requiresPreview: true,
223
+ impactDescription: "Permanently deletes the application, removing the candidate from the job posting's pipeline",
224
+ },
201
225
  // Training operations
202
226
  delete_training: {
203
227
  risk: OperationRisk.HIGH,
@@ -205,7 +229,20 @@ export const OPERATION_POLICIES = {
205
229
  requiresPreview: true,
206
230
  impactDescription: 'Deletes the training program and all enrollments',
207
231
  },
232
+ delete_session: {
233
+ risk: OperationRisk.MEDIUM,
234
+ requiresConfirmation: true,
235
+ requiresPreview: true,
236
+ impactDescription: 'Deletes the training session',
237
+ },
238
+ remove_enrollment: {
239
+ risk: OperationRisk.MEDIUM,
240
+ requiresConfirmation: true,
241
+ requiresPreview: true,
242
+ impactDescription: "Deletes the employee's enrollment record for the training",
243
+ },
208
244
  };
245
+ export const OPERATION_POLICIES = POLICIES;
209
246
  /**
210
247
  * Get the policy for an operation
211
248
  */
@@ -224,11 +261,13 @@ export function requiresConfirmation(operationName) {
224
261
  return getOperationPolicy(operationName).requiresConfirmation;
225
262
  }
226
263
  /**
227
- * Get a warning message for high-risk operations
264
+ * Get a warning message for high-risk operations, and for any operation that
265
+ * requires confirmation regardless of its risk level
228
266
  */
229
267
  export function getWarningMessage(operationName) {
230
268
  const policy = getOperationPolicy(operationName);
231
- if (policy.risk === OperationRisk.HIGH || policy.risk === OperationRisk.CRITICAL) {
269
+ const isHighRisk = policy.risk === OperationRisk.HIGH || policy.risk === OperationRisk.CRITICAL;
270
+ if (isHighRisk || policy.requiresConfirmation) {
232
271
  return (`**Warning:** This is a ${policy.risk}-risk operation. ${policy.impactDescription}. ` +
233
272
  (policy.requiresConfirmation
234
273
  ? 'Please confirm by setting `confirm: true`.'
@@ -1 +1 @@
1
- {"version":3,"file":"write-safety.js","sourceRoot":"","sources":["../src/write-safety.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"write-safety.js","sourceRoot":"","sources":["../src/write-safety.ts"],"names":[],"mappings":"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"}
package/llms.txt CHANGED
@@ -9,8 +9,8 @@ MCP FactorialHR provides comprehensive access to FactorialHR data through the Mo
9
9
  ## Key Features
10
10
 
11
11
  - **80+ Tools**: Full CRUD operations for all major HR entities
12
- - **Safety Guardrails**: High-risk operations (terminate, delete) require confirmation
13
- - **Audit Logging**: All write operations are logged
12
+ - **Safety Guardrails**: Every operation that deletes a record, or terminates an employee, requires `confirm: true`. See the README for the full list.
13
+ - **Audit Logging**: All write operations are logged in-process for debugging. The log is in-memory, capped at 1000 entries, and not retrievable through any tool.
14
14
  - **Read-only Payroll**: Payroll data is accessible but read-only for security
15
15
  - **Pagination**: All list operations support pagination
16
16
  - **Caching**: TTL-based caching for performance