@ttctl/cli 0.0.0 → 0.1.0-rc.2

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 (395) hide show
  1. package/README.md +44 -9
  2. package/dist/commands/applications/index.d.ts +21 -0
  3. package/dist/commands/applications/index.d.ts.map +1 -0
  4. package/dist/commands/applications/index.js +87 -0
  5. package/dist/commands/applications/index.js.map +1 -0
  6. package/dist/commands/applications/list.d.ts +55 -0
  7. package/dist/commands/applications/list.d.ts.map +1 -0
  8. package/dist/commands/applications/list.js +106 -0
  9. package/dist/commands/applications/list.js.map +1 -0
  10. package/dist/commands/applications/shared.d.ts +14 -0
  11. package/dist/commands/applications/shared.d.ts.map +1 -0
  12. package/dist/commands/applications/shared.js +19 -0
  13. package/dist/commands/applications/shared.js.map +1 -0
  14. package/dist/commands/applications/show.d.ts +51 -0
  15. package/dist/commands/applications/show.d.ts.map +1 -0
  16. package/dist/commands/applications/show.js +154 -0
  17. package/dist/commands/applications/show.js.map +1 -0
  18. package/dist/commands/applications/stats.d.ts +42 -0
  19. package/dist/commands/applications/stats.d.ts.map +1 -0
  20. package/dist/commands/applications/stats.js +69 -0
  21. package/dist/commands/applications/stats.js.map +1 -0
  22. package/dist/commands/auth/index.d.ts +17 -0
  23. package/dist/commands/auth/index.d.ts.map +1 -0
  24. package/dist/commands/auth/index.js +69 -0
  25. package/dist/commands/auth/index.js.map +1 -0
  26. package/dist/commands/auth/init.d.ts +98 -0
  27. package/dist/commands/auth/init.d.ts.map +1 -0
  28. package/dist/commands/auth/init.js +387 -0
  29. package/dist/commands/auth/init.js.map +1 -0
  30. package/dist/commands/auth/signin.d.ts +81 -0
  31. package/dist/commands/auth/signin.d.ts.map +1 -0
  32. package/dist/commands/auth/signin.js +145 -0
  33. package/dist/commands/auth/signin.js.map +1 -0
  34. package/dist/commands/auth/signout.d.ts +133 -0
  35. package/dist/commands/auth/signout.d.ts.map +1 -0
  36. package/dist/commands/auth/signout.js +172 -0
  37. package/dist/commands/auth/signout.js.map +1 -0
  38. package/dist/commands/auth/status.d.ts +62 -0
  39. package/dist/commands/auth/status.d.ts.map +1 -0
  40. package/dist/commands/auth/status.js +98 -0
  41. package/dist/commands/auth/status.js.map +1 -0
  42. package/dist/commands/availability/allocated-hours.d.ts +27 -0
  43. package/dist/commands/availability/allocated-hours.d.ts.map +1 -0
  44. package/dist/commands/availability/allocated-hours.js +61 -0
  45. package/dist/commands/availability/allocated-hours.js.map +1 -0
  46. package/dist/commands/availability/index.d.ts +30 -0
  47. package/dist/commands/availability/index.d.ts.map +1 -0
  48. package/dist/commands/availability/index.js +124 -0
  49. package/dist/commands/availability/index.js.map +1 -0
  50. package/dist/commands/availability/shared.d.ts +11 -0
  51. package/dist/commands/availability/shared.d.ts.map +1 -0
  52. package/dist/commands/availability/shared.js +30 -0
  53. package/dist/commands/availability/shared.js.map +1 -0
  54. package/dist/commands/availability/show.d.ts +32 -0
  55. package/dist/commands/availability/show.d.ts.map +1 -0
  56. package/dist/commands/availability/show.js +86 -0
  57. package/dist/commands/availability/show.js.map +1 -0
  58. package/dist/commands/availability/working-hours.d.ts +53 -0
  59. package/dist/commands/availability/working-hours.d.ts.map +1 -0
  60. package/dist/commands/availability/working-hours.js +151 -0
  61. package/dist/commands/availability/working-hours.js.map +1 -0
  62. package/dist/commands/contracts/index.d.ts +69 -0
  63. package/dist/commands/contracts/index.d.ts.map +1 -0
  64. package/dist/commands/contracts/index.js +198 -0
  65. package/dist/commands/contracts/index.js.map +1 -0
  66. package/dist/commands/engagements/breaks.d.ts +81 -0
  67. package/dist/commands/engagements/breaks.d.ts.map +1 -0
  68. package/dist/commands/engagements/breaks.js +229 -0
  69. package/dist/commands/engagements/breaks.js.map +1 -0
  70. package/dist/commands/engagements/index.d.ts +29 -0
  71. package/dist/commands/engagements/index.d.ts.map +1 -0
  72. package/dist/commands/engagements/index.js +172 -0
  73. package/dist/commands/engagements/index.js.map +1 -0
  74. package/dist/commands/engagements/list.d.ts +49 -0
  75. package/dist/commands/engagements/list.d.ts.map +1 -0
  76. package/dist/commands/engagements/list.js +95 -0
  77. package/dist/commands/engagements/list.js.map +1 -0
  78. package/dist/commands/engagements/shared.d.ts +10 -0
  79. package/dist/commands/engagements/shared.d.ts.map +1 -0
  80. package/dist/commands/engagements/shared.js +31 -0
  81. package/dist/commands/engagements/shared.js.map +1 -0
  82. package/dist/commands/engagements/show.d.ts +19 -0
  83. package/dist/commands/engagements/show.d.ts.map +1 -0
  84. package/dist/commands/engagements/show.js +150 -0
  85. package/dist/commands/engagements/show.js.map +1 -0
  86. package/dist/commands/engagements/stats.d.ts +24 -0
  87. package/dist/commands/engagements/stats.d.ts.map +1 -0
  88. package/dist/commands/engagements/stats.js +51 -0
  89. package/dist/commands/engagements/stats.js.map +1 -0
  90. package/dist/commands/jobs/index.d.ts +49 -0
  91. package/dist/commands/jobs/index.d.ts.map +1 -0
  92. package/dist/commands/jobs/index.js +304 -0
  93. package/dist/commands/jobs/index.js.map +1 -0
  94. package/dist/commands/jobs/interest.d.ts +65 -0
  95. package/dist/commands/jobs/interest.d.ts.map +1 -0
  96. package/dist/commands/jobs/interest.js +172 -0
  97. package/dist/commands/jobs/interest.js.map +1 -0
  98. package/dist/commands/jobs/list.d.ts +81 -0
  99. package/dist/commands/jobs/list.d.ts.map +1 -0
  100. package/dist/commands/jobs/list.js +157 -0
  101. package/dist/commands/jobs/list.js.map +1 -0
  102. package/dist/commands/jobs/search.d.ts +71 -0
  103. package/dist/commands/jobs/search.d.ts.map +1 -0
  104. package/dist/commands/jobs/search.js +163 -0
  105. package/dist/commands/jobs/search.js.map +1 -0
  106. package/dist/commands/jobs/shared.d.ts +79 -0
  107. package/dist/commands/jobs/shared.d.ts.map +1 -0
  108. package/dist/commands/jobs/shared.js +133 -0
  109. package/dist/commands/jobs/shared.js.map +1 -0
  110. package/dist/commands/jobs/show.d.ts +20 -0
  111. package/dist/commands/jobs/show.d.ts.map +1 -0
  112. package/dist/commands/jobs/show.js +135 -0
  113. package/dist/commands/jobs/show.js.map +1 -0
  114. package/dist/commands/payments/index.d.ts +34 -0
  115. package/dist/commands/payments/index.d.ts.map +1 -0
  116. package/dist/commands/payments/index.js +160 -0
  117. package/dist/commands/payments/index.js.map +1 -0
  118. package/dist/commands/payments/methods.d.ts +17 -0
  119. package/dist/commands/payments/methods.d.ts.map +1 -0
  120. package/dist/commands/payments/methods.js +79 -0
  121. package/dist/commands/payments/methods.js.map +1 -0
  122. package/dist/commands/payments/payouts.d.ts +44 -0
  123. package/dist/commands/payments/payouts.d.ts.map +1 -0
  124. package/dist/commands/payments/payouts.js +147 -0
  125. package/dist/commands/payments/payouts.js.map +1 -0
  126. package/dist/commands/payments/rate.d.ts +48 -0
  127. package/dist/commands/payments/rate.d.ts.map +1 -0
  128. package/dist/commands/payments/rate.js +229 -0
  129. package/dist/commands/payments/rate.js.map +1 -0
  130. package/dist/commands/payments/shared.d.ts +10 -0
  131. package/dist/commands/payments/shared.d.ts.map +1 -0
  132. package/dist/commands/payments/shared.js +27 -0
  133. package/dist/commands/payments/shared.js.map +1 -0
  134. package/dist/commands/profile/basic/index.d.ts +18 -0
  135. package/dist/commands/profile/basic/index.d.ts.map +1 -0
  136. package/dist/commands/profile/basic/index.js +79 -0
  137. package/dist/commands/profile/basic/index.js.map +1 -0
  138. package/dist/commands/profile/basic/photo-show.d.ts +28 -0
  139. package/dist/commands/profile/basic/photo-show.d.ts.map +1 -0
  140. package/dist/commands/profile/basic/photo-show.js +112 -0
  141. package/dist/commands/profile/basic/photo-show.js.map +1 -0
  142. package/dist/commands/profile/basic/photo-upload.d.ts +10 -0
  143. package/dist/commands/profile/basic/photo-upload.d.ts.map +1 -0
  144. package/dist/commands/profile/basic/photo-upload.js +61 -0
  145. package/dist/commands/profile/basic/photo-upload.js.map +1 -0
  146. package/dist/commands/profile/basic/set.d.ts +54 -0
  147. package/dist/commands/profile/basic/set.d.ts.map +1 -0
  148. package/dist/commands/profile/basic/set.js +174 -0
  149. package/dist/commands/profile/basic/set.js.map +1 -0
  150. package/dist/commands/profile/basic/show.d.ts +95 -0
  151. package/dist/commands/profile/basic/show.d.ts.map +1 -0
  152. package/dist/commands/profile/basic/show.js +310 -0
  153. package/dist/commands/profile/basic/show.js.map +1 -0
  154. package/dist/commands/profile/certifications/index.d.ts +40 -0
  155. package/dist/commands/profile/certifications/index.d.ts.map +1 -0
  156. package/dist/commands/profile/certifications/index.js +350 -0
  157. package/dist/commands/profile/certifications/index.js.map +1 -0
  158. package/dist/commands/profile/education/index.d.ts +37 -0
  159. package/dist/commands/profile/education/index.d.ts.map +1 -0
  160. package/dist/commands/profile/education/index.js +331 -0
  161. package/dist/commands/profile/education/index.js.map +1 -0
  162. package/dist/commands/profile/employment/index.d.ts +49 -0
  163. package/dist/commands/profile/employment/index.d.ts.map +1 -0
  164. package/dist/commands/profile/employment/index.js +425 -0
  165. package/dist/commands/profile/employment/index.js.map +1 -0
  166. package/dist/commands/profile/external/_shared.d.ts +35 -0
  167. package/dist/commands/profile/external/_shared.d.ts.map +1 -0
  168. package/dist/commands/profile/external/_shared.js +59 -0
  169. package/dist/commands/profile/external/_shared.js.map +1 -0
  170. package/dist/commands/profile/external/advanced-wizard-show.d.ts +15 -0
  171. package/dist/commands/profile/external/advanced-wizard-show.d.ts.map +1 -0
  172. package/dist/commands/profile/external/advanced-wizard-show.js +82 -0
  173. package/dist/commands/profile/external/advanced-wizard-show.js.map +1 -0
  174. package/dist/commands/profile/external/custom-requirements-set.d.ts +32 -0
  175. package/dist/commands/profile/external/custom-requirements-set.d.ts.map +1 -0
  176. package/dist/commands/profile/external/custom-requirements-set.js +116 -0
  177. package/dist/commands/profile/external/custom-requirements-set.js.map +1 -0
  178. package/dist/commands/profile/external/custom-requirements-show.d.ts +16 -0
  179. package/dist/commands/profile/external/custom-requirements-show.d.ts.map +1 -0
  180. package/dist/commands/profile/external/custom-requirements-show.js +84 -0
  181. package/dist/commands/profile/external/custom-requirements-show.js.map +1 -0
  182. package/dist/commands/profile/external/index.d.ts +21 -0
  183. package/dist/commands/profile/external/index.d.ts.map +1 -0
  184. package/dist/commands/profile/external/index.js +113 -0
  185. package/dist/commands/profile/external/index.js.map +1 -0
  186. package/dist/commands/profile/external/readiness.d.ts +15 -0
  187. package/dist/commands/profile/external/readiness.d.ts.map +1 -0
  188. package/dist/commands/profile/external/readiness.js +104 -0
  189. package/dist/commands/profile/external/readiness.js.map +1 -0
  190. package/dist/commands/profile/external/recommendations.d.ts +17 -0
  191. package/dist/commands/profile/external/recommendations.d.ts.map +1 -0
  192. package/dist/commands/profile/external/recommendations.js +97 -0
  193. package/dist/commands/profile/external/recommendations.js.map +1 -0
  194. package/dist/commands/profile/external/show.d.ts +22 -0
  195. package/dist/commands/profile/external/show.d.ts.map +1 -0
  196. package/dist/commands/profile/external/show.js +83 -0
  197. package/dist/commands/profile/external/show.js.map +1 -0
  198. package/dist/commands/profile/external/update.d.ts +37 -0
  199. package/dist/commands/profile/external/update.d.ts.map +1 -0
  200. package/dist/commands/profile/external/update.js +125 -0
  201. package/dist/commands/profile/external/update.js.map +1 -0
  202. package/dist/commands/profile/index.d.ts +16 -0
  203. package/dist/commands/profile/index.d.ts.map +1 -0
  204. package/dist/commands/profile/index.js +81 -0
  205. package/dist/commands/profile/index.js.map +1 -0
  206. package/dist/commands/profile/industries/index.d.ts +43 -0
  207. package/dist/commands/profile/industries/index.d.ts.map +1 -0
  208. package/dist/commands/profile/industries/index.js +258 -0
  209. package/dist/commands/profile/industries/index.js.map +1 -0
  210. package/dist/commands/profile/portfolio/add.d.ts +43 -0
  211. package/dist/commands/profile/portfolio/add.d.ts.map +1 -0
  212. package/dist/commands/profile/portfolio/add.js +181 -0
  213. package/dist/commands/profile/portfolio/add.js.map +1 -0
  214. package/dist/commands/profile/portfolio/highlight.d.ts +11 -0
  215. package/dist/commands/profile/portfolio/highlight.d.ts.map +1 -0
  216. package/dist/commands/profile/portfolio/highlight.js +31 -0
  217. package/dist/commands/profile/portfolio/highlight.js.map +1 -0
  218. package/dist/commands/profile/portfolio/index.d.ts +16 -0
  219. package/dist/commands/profile/portfolio/index.d.ts.map +1 -0
  220. package/dist/commands/profile/portfolio/index.js +121 -0
  221. package/dist/commands/profile/portfolio/index.js.map +1 -0
  222. package/dist/commands/profile/portfolio/list.d.ts +83 -0
  223. package/dist/commands/profile/portfolio/list.d.ts.map +1 -0
  224. package/dist/commands/profile/portfolio/list.js +189 -0
  225. package/dist/commands/profile/portfolio/list.js.map +1 -0
  226. package/dist/commands/profile/portfolio/remove.d.ts +9 -0
  227. package/dist/commands/profile/portfolio/remove.d.ts.map +1 -0
  228. package/dist/commands/profile/portfolio/remove.js +24 -0
  229. package/dist/commands/profile/portfolio/remove.js.map +1 -0
  230. package/dist/commands/profile/portfolio/reorder.d.ts +17 -0
  231. package/dist/commands/profile/portfolio/reorder.d.ts.map +1 -0
  232. package/dist/commands/profile/portfolio/reorder.js +135 -0
  233. package/dist/commands/profile/portfolio/reorder.js.map +1 -0
  234. package/dist/commands/profile/portfolio/shared.d.ts +8 -0
  235. package/dist/commands/profile/portfolio/shared.d.ts.map +1 -0
  236. package/dist/commands/profile/portfolio/shared.js +10 -0
  237. package/dist/commands/profile/portfolio/shared.js.map +1 -0
  238. package/dist/commands/profile/portfolio/update.d.ts +18 -0
  239. package/dist/commands/profile/portfolio/update.d.ts.map +1 -0
  240. package/dist/commands/profile/portfolio/update.js +77 -0
  241. package/dist/commands/profile/portfolio/update.js.map +1 -0
  242. package/dist/commands/profile/portfolio/upload.d.ts +8 -0
  243. package/dist/commands/profile/portfolio/upload.d.ts.map +1 -0
  244. package/dist/commands/profile/portfolio/upload.js +131 -0
  245. package/dist/commands/profile/portfolio/upload.js.map +1 -0
  246. package/dist/commands/profile/resume/cancel-upload.d.ts +9 -0
  247. package/dist/commands/profile/resume/cancel-upload.d.ts.map +1 -0
  248. package/dist/commands/profile/resume/cancel-upload.js +30 -0
  249. package/dist/commands/profile/resume/cancel-upload.js.map +1 -0
  250. package/dist/commands/profile/resume/index.d.ts +15 -0
  251. package/dist/commands/profile/resume/index.d.ts.map +1 -0
  252. package/dist/commands/profile/resume/index.js +42 -0
  253. package/dist/commands/profile/resume/index.js.map +1 -0
  254. package/dist/commands/profile/resume/upload.d.ts +16 -0
  255. package/dist/commands/profile/resume/upload.d.ts.map +1 -0
  256. package/dist/commands/profile/resume/upload.js +65 -0
  257. package/dist/commands/profile/resume/upload.js.map +1 -0
  258. package/dist/commands/profile/reviews/_shared.d.ts +9 -0
  259. package/dist/commands/profile/reviews/_shared.d.ts.map +1 -0
  260. package/dist/commands/profile/reviews/_shared.js +15 -0
  261. package/dist/commands/profile/reviews/_shared.js.map +1 -0
  262. package/dist/commands/profile/reviews/approve-item.d.ts +30 -0
  263. package/dist/commands/profile/reviews/approve-item.d.ts.map +1 -0
  264. package/dist/commands/profile/reviews/approve-item.js +82 -0
  265. package/dist/commands/profile/reviews/approve-item.js.map +1 -0
  266. package/dist/commands/profile/reviews/approve-section.d.ts +15 -0
  267. package/dist/commands/profile/reviews/approve-section.d.ts.map +1 -0
  268. package/dist/commands/profile/reviews/approve-section.js +67 -0
  269. package/dist/commands/profile/reviews/approve-section.js.map +1 -0
  270. package/dist/commands/profile/reviews/index.d.ts +19 -0
  271. package/dist/commands/profile/reviews/index.d.ts.map +1 -0
  272. package/dist/commands/profile/reviews/index.js +71 -0
  273. package/dist/commands/profile/reviews/index.js.map +1 -0
  274. package/dist/commands/profile/reviews/list.d.ts +17 -0
  275. package/dist/commands/profile/reviews/list.d.ts.map +1 -0
  276. package/dist/commands/profile/reviews/list.js +96 -0
  277. package/dist/commands/profile/reviews/list.js.map +1 -0
  278. package/dist/commands/profile/reviews/submit-for-review.d.ts +16 -0
  279. package/dist/commands/profile/reviews/submit-for-review.d.ts.map +1 -0
  280. package/dist/commands/profile/reviews/submit-for-review.js +65 -0
  281. package/dist/commands/profile/reviews/submit-for-review.js.map +1 -0
  282. package/dist/commands/profile/shared.d.ts +46 -0
  283. package/dist/commands/profile/shared.d.ts.map +1 -0
  284. package/dist/commands/profile/shared.js +111 -0
  285. package/dist/commands/profile/shared.js.map +1 -0
  286. package/dist/commands/profile/skills/index.d.ts +29 -0
  287. package/dist/commands/profile/skills/index.d.ts.map +1 -0
  288. package/dist/commands/profile/skills/index.js +475 -0
  289. package/dist/commands/profile/skills/index.js.map +1 -0
  290. package/dist/commands/profile/visas/add.d.ts +19 -0
  291. package/dist/commands/profile/visas/add.d.ts.map +1 -0
  292. package/dist/commands/profile/visas/add.js +37 -0
  293. package/dist/commands/profile/visas/add.js.map +1 -0
  294. package/dist/commands/profile/visas/index.d.ts +13 -0
  295. package/dist/commands/profile/visas/index.d.ts.map +1 -0
  296. package/dist/commands/profile/visas/index.js +69 -0
  297. package/dist/commands/profile/visas/index.js.map +1 -0
  298. package/dist/commands/profile/visas/list.d.ts +40 -0
  299. package/dist/commands/profile/visas/list.d.ts.map +1 -0
  300. package/dist/commands/profile/visas/list.js +115 -0
  301. package/dist/commands/profile/visas/list.js.map +1 -0
  302. package/dist/commands/profile/visas/remove.d.ts +8 -0
  303. package/dist/commands/profile/visas/remove.d.ts.map +1 -0
  304. package/dist/commands/profile/visas/remove.js +23 -0
  305. package/dist/commands/profile/visas/remove.js.map +1 -0
  306. package/dist/commands/profile/visas/shared.d.ts +11 -0
  307. package/dist/commands/profile/visas/shared.d.ts.map +1 -0
  308. package/dist/commands/profile/visas/shared.js +16 -0
  309. package/dist/commands/profile/visas/shared.js.map +1 -0
  310. package/dist/commands/profile/visas/update.d.ts +13 -0
  311. package/dist/commands/profile/visas/update.d.ts.map +1 -0
  312. package/dist/commands/profile/visas/update.js +44 -0
  313. package/dist/commands/profile/visas/update.js.map +1 -0
  314. package/dist/commands/timesheet/index.d.ts +24 -0
  315. package/dist/commands/timesheet/index.d.ts.map +1 -0
  316. package/dist/commands/timesheet/index.js +98 -0
  317. package/dist/commands/timesheet/index.js.map +1 -0
  318. package/dist/commands/timesheet/list.d.ts +40 -0
  319. package/dist/commands/timesheet/list.d.ts.map +1 -0
  320. package/dist/commands/timesheet/list.js +79 -0
  321. package/dist/commands/timesheet/list.js.map +1 -0
  322. package/dist/commands/timesheet/shared.d.ts +10 -0
  323. package/dist/commands/timesheet/shared.d.ts.map +1 -0
  324. package/dist/commands/timesheet/shared.js +35 -0
  325. package/dist/commands/timesheet/shared.js.map +1 -0
  326. package/dist/commands/timesheet/show.d.ts +19 -0
  327. package/dist/commands/timesheet/show.d.ts.map +1 -0
  328. package/dist/commands/timesheet/show.js +109 -0
  329. package/dist/commands/timesheet/show.js.map +1 -0
  330. package/dist/commands/timesheet/submit.d.ts +50 -0
  331. package/dist/commands/timesheet/submit.d.ts.map +1 -0
  332. package/dist/commands/timesheet/submit.js +151 -0
  333. package/dist/commands/timesheet/submit.js.map +1 -0
  334. package/dist/crash-handlers.d.ts +67 -0
  335. package/dist/crash-handlers.d.ts.map +1 -0
  336. package/dist/crash-handlers.js +78 -0
  337. package/dist/crash-handlers.js.map +1 -0
  338. package/dist/errors.d.ts +45 -0
  339. package/dist/errors.d.ts.map +1 -0
  340. package/dist/errors.js +57 -0
  341. package/dist/errors.js.map +1 -0
  342. package/dist/index.d.ts +8 -0
  343. package/dist/index.d.ts.map +1 -0
  344. package/dist/index.js +15 -0
  345. package/dist/index.js.map +1 -0
  346. package/dist/lib/config-context.d.ts +41 -0
  347. package/dist/lib/config-context.d.ts.map +1 -0
  348. package/dist/lib/config-context.js +74 -0
  349. package/dist/lib/config-context.js.map +1 -0
  350. package/dist/lib/dry-run.d.ts +70 -0
  351. package/dist/lib/dry-run.d.ts.map +1 -0
  352. package/dist/lib/dry-run.js +114 -0
  353. package/dist/lib/dry-run.js.map +1 -0
  354. package/dist/lib/empty-state-cta.d.ts +63 -0
  355. package/dist/lib/empty-state-cta.d.ts.map +1 -0
  356. package/dist/lib/empty-state-cta.js +88 -0
  357. package/dist/lib/empty-state-cta.js.map +1 -0
  358. package/dist/lib/envelopes.d.ts +540 -0
  359. package/dist/lib/envelopes.d.ts.map +1 -0
  360. package/dist/lib/envelopes.js +598 -0
  361. package/dist/lib/envelopes.js.map +1 -0
  362. package/dist/lib/error-routing.d.ts +49 -0
  363. package/dist/lib/error-routing.d.ts.map +1 -0
  364. package/dist/lib/error-routing.js +72 -0
  365. package/dist/lib/error-routing.js.map +1 -0
  366. package/dist/lib/format-helpers.d.ts +65 -0
  367. package/dist/lib/format-helpers.d.ts.map +1 -0
  368. package/dist/lib/format-helpers.js +79 -0
  369. package/dist/lib/format-helpers.js.map +1 -0
  370. package/dist/lib/format-overrides.d.ts +81 -0
  371. package/dist/lib/format-overrides.d.ts.map +1 -0
  372. package/dist/lib/format-overrides.js +55 -0
  373. package/dist/lib/format-overrides.js.map +1 -0
  374. package/dist/lib/freetext.d.ts +83 -0
  375. package/dist/lib/freetext.d.ts.map +1 -0
  376. package/dist/lib/freetext.js +182 -0
  377. package/dist/lib/freetext.js.map +1 -0
  378. package/dist/lib/kill-switch-hook.d.ts +49 -0
  379. package/dist/lib/kill-switch-hook.d.ts.map +1 -0
  380. package/dist/lib/kill-switch-hook.js +34 -0
  381. package/dist/lib/kill-switch-hook.js.map +1 -0
  382. package/dist/lib/output.d.ts +173 -0
  383. package/dist/lib/output.d.ts.map +1 -0
  384. package/dist/lib/output.js +177 -0
  385. package/dist/lib/output.js.map +1 -0
  386. package/dist/lib/pagination.d.ts +49 -0
  387. package/dist/lib/pagination.d.ts.map +1 -0
  388. package/dist/lib/pagination.js +36 -0
  389. package/dist/lib/pagination.js.map +1 -0
  390. package/dist/program.d.ts +80 -0
  391. package/dist/program.d.ts.map +1 -0
  392. package/dist/program.js +273 -0
  393. package/dist/program.js.map +1 -0
  394. package/package.json +35 -13
  395. package/index.js +0 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/timesheet/shared.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAoB,EAAE,GAAY,EAAE,SAAuB,QAAQ;IACtG,iBAAiB,CAAC,YAAY,EAAE,GAAG,EAAE,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAC/F,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,IAAkC;IAC9D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW;YACd,OAAO,2EAA2E,CAAC;QACrF,KAAK,eAAe;YAClB,OAAO,kGAAkG,CAAC;QAC5G,KAAK,kBAAkB;YACrB,OAAO,2GAA2G,CAAC;QACrH,KAAK,yBAAyB;YAC5B,OAAO,2IAA2I,CAAC;QACrJ,KAAK,gBAAgB;YACnB,OAAO,6JAA6J,CAAC;QACvK;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { timesheet } from "@ttctl/core";
2
+ import type { OutputFormat } from "../../lib/output.js";
3
+ /**
4
+ * Action handler for `ttctl timesheet show <id>`. `<id>` is the
5
+ * BillingCycle.id from `ttctl timesheet list`.
6
+ *
7
+ * Pretty rendering is a multi-line key:value layout grouped into
8
+ * sections (Header, Engagement, Submission, Agreement, Records). Empty
9
+ * sections are omitted. `json` / `yaml` always emit the full server
10
+ * payload (including `timesheetUrl`, `actualAgreement`, the full
11
+ * records array, etc.).
12
+ */
13
+ export declare function runTimesheetShow(id: string, output: OutputFormat): Promise<void>;
14
+ /**
15
+ * Render the timesheet detail as a sectioned multi-line block. Pure —
16
+ * directly unit-testable.
17
+ */
18
+ export declare function formatTimesheetDetail(item: timesheet.TimesheetDetail): string;
19
+ //# sourceMappingURL=show.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../../src/commands/timesheet/show.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAatF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC,eAAe,GAAG,MAAM,CAgF7E"}
@@ -0,0 +1,109 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { timesheet } from "@ttctl/core";
4
+ import { emitResult } from "../../lib/output.js";
5
+ import { handleTimesheetError, loadAuthTokenOrExit } from "./shared.js";
6
+ /**
7
+ * Action handler for `ttctl timesheet show <id>`. `<id>` is the
8
+ * BillingCycle.id from `ttctl timesheet list`.
9
+ *
10
+ * Pretty rendering is a multi-line key:value layout grouped into
11
+ * sections (Header, Engagement, Submission, Agreement, Records). Empty
12
+ * sections are omitted. `json` / `yaml` always emit the full server
13
+ * payload (including `timesheetUrl`, `actualAgreement`, the full
14
+ * records array, etc.).
15
+ */
16
+ export async function runTimesheetShow(id, output) {
17
+ const token = await loadAuthTokenOrExit("timesheet show", output);
18
+ let item;
19
+ try {
20
+ item = await timesheet.show(token, id);
21
+ }
22
+ catch (err) {
23
+ handleTimesheetError("timesheet show", err, output);
24
+ }
25
+ emitResult(item, output, {
26
+ pretty: (data) => formatTimesheetDetail(data),
27
+ });
28
+ }
29
+ /**
30
+ * Render the timesheet detail as a sectioned multi-line block. Pure —
31
+ * directly unit-testable.
32
+ */
33
+ export function formatTimesheetDetail(item) {
34
+ const lines = [];
35
+ lines.push(`Timesheet ${item.id}`);
36
+ lines.push(` Week: ${item.startDate} → ${item.endDate}`);
37
+ lines.push(` Hours: ${item.hours}`);
38
+ lines.push(` Submitted: ${String(item.timesheetSubmitted)}`);
39
+ lines.push(` Overdue: ${String(item.timesheetOverdue)}`);
40
+ if (item.timesheetSubmissionOpenDatetime !== null) {
41
+ lines.push(` Submission opens: ${item.timesheetSubmissionOpenDatetime}`);
42
+ }
43
+ if (item.timesheetSubmissionDeadlineDatetime !== null) {
44
+ lines.push(` Submission deadline: ${item.timesheetSubmissionDeadlineDatetime}`);
45
+ }
46
+ if (item.timesheetUrl !== null) {
47
+ lines.push(` URL: ${item.timesheetUrl}`);
48
+ }
49
+ lines.push("");
50
+ lines.push("Engagement");
51
+ if (item.engagement.job.title !== null)
52
+ lines.push(` ${item.engagement.job.title}`);
53
+ if (item.engagement.job.client?.fullName != null) {
54
+ lines.push(` Client: ${item.engagement.job.client.fullName}`);
55
+ }
56
+ // Note: this is `Engagement.id` (TalentEngagement), NOT `JobActivityItem.id`.
57
+ // The `--engagement <id>` flag on `timesheet list/submit` consumes the
58
+ // `JobActivityItem.id` surfaced by `engagements list`, which is a
59
+ // distinct identifier — we name the field verbosely here so users don't
60
+ // copy-paste this id back into `--engagement` and get a NOT_FOUND.
61
+ lines.push(` TalentEngagement id: ${item.engagement.id}`);
62
+ if (item.engagement.expectedHours !== null) {
63
+ lines.push(` Expected hours: ${item.engagement.expectedHours.toString()}`);
64
+ }
65
+ if (item.minimumCommitment !== null && item.minimumCommitment.applicable) {
66
+ lines.push("");
67
+ lines.push("Minimum commitment");
68
+ if (item.minimumCommitment.minimumHours !== null) {
69
+ lines.push(` Minimum hours: ${item.minimumCommitment.minimumHours.toString()}`);
70
+ }
71
+ }
72
+ if (item.actualAgreement !== null) {
73
+ lines.push("");
74
+ lines.push("Agreement");
75
+ if (item.actualAgreement.applicationRate !== null) {
76
+ lines.push(` Application rate: ${item.actualAgreement.applicationRate}`);
77
+ }
78
+ if (item.actualAgreement.talentHourlyRate !== null) {
79
+ lines.push(` Hourly rate: ${item.actualAgreement.talentHourlyRate}`);
80
+ }
81
+ if (item.actualAgreement.marketplaceMargin !== null) {
82
+ lines.push(` Marketplace margin: ${item.actualAgreement.marketplaceMargin}`);
83
+ }
84
+ }
85
+ if (item.timesheetComment !== null && item.timesheetComment !== "") {
86
+ lines.push("");
87
+ lines.push("Comment");
88
+ for (const para of item.timesheetComment.split(/\n+/)) {
89
+ if (para.trim().length > 0)
90
+ lines.push(` ${para}`);
91
+ }
92
+ }
93
+ if (item.timesheetRecords.length > 0) {
94
+ lines.push("");
95
+ lines.push(`Records (${item.timesheetRecords.length.toString()})`);
96
+ for (const rec of item.timesheetRecords) {
97
+ // `duration` is a string-encoded decimal in minutes (e.g., "480.0"
98
+ // for an 8-hour day). `Number()` parses "480.0" → 480; division by
99
+ // 60 yields hours. Pre-#???: this divided by 3600 assuming
100
+ // number-typed seconds, rendering 8h as 0.13h.
101
+ const hours = (Number(rec.duration) / 60).toFixed(2);
102
+ const tag = rec.isDayOff ? " [day off]" : "";
103
+ const note = rec.note != null && rec.note !== "" ? ` — ${rec.note}` : "";
104
+ lines.push(` ${rec.date}: ${hours}h${tag}${note}`);
105
+ }
106
+ }
107
+ return lines.join("\n");
108
+ }
109
+ //# sourceMappingURL=show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.js","sourceRoot":"","sources":["../../../src/commands/timesheet/show.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { OutputFormat } from "../../lib/output.js";
2
+ /**
3
+ * Action handler for `ttctl timesheet submit [id]`.
4
+ *
5
+ * Per #13 spec, submit is destructive (one-way on the wire). The
6
+ * action is gated behind one of:
7
+ *
8
+ * - `--confirm` flag (script-safe, no prompt)
9
+ * - Interactive TTY confirm via `@clack/prompts` (non-TTY without
10
+ * `--confirm` refuses with a clear error envelope)
11
+ *
12
+ * `<id>` is a positional BillingCycle.id. When omitted, the runner
13
+ * calls {@link timesheet.resolveCurrentCycle} to auto-resolve the
14
+ * single cycle whose submission window contains "now". Optional
15
+ * `--engagement <id>` scopes the resolve to one engagement (uses the
16
+ * `JobActivityItem.id` from `engagements list`).
17
+ *
18
+ * Auto-resolve outcomes:
19
+ *
20
+ * - `kind: "found"` → proceed to confirm + submit
21
+ * - `kind: "none"` → error envelope with code `NO_CURRENT_CYCLE`
22
+ * - `kind: "multiple"` → error envelope with code
23
+ * `MULTIPLE_CURRENT_CYCLES` listing candidate
24
+ * ids in `errors[0].hint` so scripts can
25
+ * disambiguate.
26
+ *
27
+ * Success returns the write-success envelope per #128:
28
+ * `{ok: true, version: "1.0", operation: "timesheet.submit", updated: <detail>}`.
29
+ *
30
+ * Dry-run path: when `getCliDryRun()` is true (the CLI-global
31
+ * `--dry-run` flag was passed), the destructive mutation is replaced
32
+ * by a {@link DryRunPreview}. The confirm gate AND the auto-resolve
33
+ * read are BOTH skipped — auto-resolve uses the placeholder string
34
+ * `<auto-resolved-at-apply-time>` for the id, surfaced via the
35
+ * envelope `notice` so machine consumers don't mistake it for a real
36
+ * cycle id. See {@link DRY_RUN_PLACEHOLDER_NOTICE}.
37
+ */
38
+ export interface TimesheetSubmitOptions {
39
+ confirm: boolean;
40
+ engagement?: string;
41
+ output: OutputFormat;
42
+ }
43
+ /**
44
+ * Internal seam: `runTimesheetSubmit` decides whether to prompt based
45
+ * on a deterministic predicate. Exported via `isStdinTty` so tests can
46
+ * stub it cleanly without poking `process.stdin.isTTY`.
47
+ */
48
+ export declare function isStdinTty(): boolean;
49
+ export declare function runTimesheetSubmit(id: string | undefined, opts: TimesheetSubmitOptions): Promise<void>;
50
+ //# sourceMappingURL=submit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../../src/commands/timesheet/submit.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAIxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB;AAYD;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+H5G"}
@@ -0,0 +1,151 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import * as p from "@clack/prompts";
4
+ import { timesheet } from "@ttctl/core";
5
+ import { getCliDryRun } from "../../lib/dry-run.js";
6
+ import { emitDryRunSuccess, emitErrorAndExit, emitUpdateSuccess } from "../../lib/envelopes.js";
7
+ import { handleTimesheetError, loadAuthTokenOrExit } from "./shared.js";
8
+ import { formatTimesheetDetail } from "./show.js";
9
+ /**
10
+ * Notice surfaced on the dry-run envelope when the caller omitted the
11
+ * positional `<id>` AND the apply path would have auto-resolved the
12
+ * current cycle. The preview's `variables.id` carries the placeholder
13
+ * string `<auto-resolved-at-apply-time>`; the real BillingCycle.id is
14
+ * resolved at apply time via `PendingTimesheets` (skipped on dry-run).
15
+ */
16
+ const DRY_RUN_PLACEHOLDER_NOTICE = "id in the preview is the placeholder string `<auto-resolved-at-apply-time>`; the apply path resolves the real BillingCycle.id via a PendingTimesheets query before issuing the mutation — this read is skipped on dry-run.";
17
+ /**
18
+ * Internal seam: `runTimesheetSubmit` decides whether to prompt based
19
+ * on a deterministic predicate. Exported via `isStdinTty` so tests can
20
+ * stub it cleanly without poking `process.stdin.isTTY`.
21
+ */
22
+ export function isStdinTty() {
23
+ return process.stdin.isTTY === true;
24
+ }
25
+ export async function runTimesheetSubmit(id, opts) {
26
+ const token = await loadAuthTokenOrExit("timesheet submit", opts.output);
27
+ const dryRun = getCliDryRun();
28
+ // Step 1: resolve the cycle id (explicit positional OR auto-resolve).
29
+ // Dry-run path: skip the auto-resolve read entirely and stamp the
30
+ // placeholder. The destructive mutation is never sent.
31
+ let cycleId;
32
+ let usedPlaceholder = false;
33
+ if (id !== undefined) {
34
+ cycleId = id;
35
+ }
36
+ else if (dryRun) {
37
+ cycleId = "<auto-resolved-at-apply-time>";
38
+ usedPlaceholder = true;
39
+ }
40
+ else {
41
+ const resolveOpts = {};
42
+ if (opts.engagement !== undefined)
43
+ resolveOpts.engagement = opts.engagement;
44
+ let resolution;
45
+ try {
46
+ resolution = await timesheet.resolveCurrentCycle(token, resolveOpts);
47
+ }
48
+ catch (err) {
49
+ handleTimesheetError("timesheet submit", err, opts.output);
50
+ }
51
+ if (resolution.kind === "none") {
52
+ emitErrorAndExit({
53
+ operation: "timesheet.submit",
54
+ format: opts.output,
55
+ errors: [
56
+ {
57
+ code: "NO_CURRENT_CYCLE",
58
+ message: "No billing cycle is currently in its submission window. Either nothing is due, or every pending cycle is too early / past deadline.",
59
+ hint: "Run `ttctl timesheet list` to see what's pending, or specify a cycle id explicitly.",
60
+ },
61
+ ],
62
+ prettySummary: "timesheet submit failed (NO_CURRENT_CYCLE): no current pending timesheet.",
63
+ });
64
+ }
65
+ if (resolution.kind === "multiple") {
66
+ const candidateLines = resolution.candidates.map((c) => {
67
+ const client = c.engagement.job.client?.fullName ?? "(no client)";
68
+ const title = c.engagement.job.title ?? "(untitled)";
69
+ return ` - ${c.id} (${client} — ${title}, ${c.startDate} → ${c.endDate})`;
70
+ });
71
+ emitErrorAndExit({
72
+ operation: "timesheet.submit",
73
+ format: opts.output,
74
+ errors: [
75
+ {
76
+ code: "MULTIPLE_CURRENT_CYCLES",
77
+ message: `${resolution.candidates.length.toString()} billing cycles match the current submission window — specify one explicitly.`,
78
+ hint: `Candidates:\n${candidateLines.join("\n")}`,
79
+ },
80
+ ],
81
+ prettySummary: `timesheet submit failed (MULTIPLE_CURRENT_CYCLES): ${resolution.candidates.length.toString()} candidates.`,
82
+ });
83
+ }
84
+ cycleId = resolution.cycle.id;
85
+ }
86
+ // Step 2: --confirm OR interactive TTY confirm gate.
87
+ // Dry-run path: skip the confirm gate entirely — there's nothing
88
+ // destructive to confirm. The preview is emitted regardless of
89
+ // --confirm / stdin TTY-ness.
90
+ if (!dryRun && !opts.confirm) {
91
+ if (!isStdinTty()) {
92
+ emitErrorAndExit({
93
+ operation: "timesheet.submit",
94
+ format: opts.output,
95
+ errors: [
96
+ {
97
+ code: "CONFIRMATION_REQUIRED",
98
+ message: "timesheet submit is destructive (one-way) and requires explicit confirmation. Pass --confirm or run in an interactive terminal.",
99
+ hint: "Add `--confirm` to the command, or run `ttctl timesheet submit` from a TTY.",
100
+ },
101
+ ],
102
+ prettySummary: "timesheet submit refused: --confirm flag required (non-TTY stdin).",
103
+ });
104
+ }
105
+ const proceed = await p.confirm({
106
+ message: `Submit timesheet ${cycleId}? This is one-way and cannot be undone.`,
107
+ initialValue: false,
108
+ });
109
+ if (p.isCancel(proceed) || !proceed) {
110
+ emitErrorAndExit({
111
+ operation: "timesheet.submit",
112
+ format: opts.output,
113
+ errors: [
114
+ {
115
+ code: "CONFIRMATION_DECLINED",
116
+ message: "Submission cancelled by user.",
117
+ },
118
+ ],
119
+ prettySummary: "timesheet submit cancelled by user.",
120
+ exitCode: 1,
121
+ });
122
+ }
123
+ }
124
+ // Step 3: perform the submission (or build the dry-run preview).
125
+ let outcome;
126
+ try {
127
+ outcome = await timesheet.submit(token, cycleId, { dryRun });
128
+ }
129
+ catch (err) {
130
+ handleTimesheetError("timesheet submit", err, opts.output);
131
+ }
132
+ // Step 4: branch on outcome — dry-run preview OR apply-path envelope.
133
+ if (outcome.kind === "preview") {
134
+ emitDryRunSuccess({
135
+ operation: "timesheet.submit",
136
+ format: opts.output,
137
+ preview: outcome.preview,
138
+ ...(usedPlaceholder ? { notice: DRY_RUN_PLACEHOLDER_NOTICE } : {}),
139
+ });
140
+ return;
141
+ }
142
+ const { result: updated } = outcome;
143
+ emitUpdateSuccess({
144
+ operation: "timesheet.submit",
145
+ format: opts.output,
146
+ updated,
147
+ prettySummary: `timesheet ${updated.id} submitted (${updated.startDate} → ${updated.endDate}, ${updated.hours}h)`,
148
+ prettyEntity: (entity) => formatTimesheetDetail(entity),
149
+ });
150
+ }
151
+ //# sourceMappingURL=submit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.js","sourceRoot":"","sources":["../../../src/commands/timesheet/submit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Discriminator for the two top-level crash paths Node.js exposes.
3
+ * `uncaughtException` fires for synchronous throws that escape every
4
+ * try/catch frame; `unhandledRejection` fires for rejected promises with
5
+ * no `.catch()` or `await` upstream. Both are terminal — the process
6
+ * is exiting; the only question is whether the crash output leaks an
7
+ * in-memory secret on the way out.
8
+ */
9
+ export type CrashKind = "uncaughtException" | "unhandledRejection";
10
+ /**
11
+ * Build the redacted crash log for an uncaught throw or unhandled
12
+ * promise rejection. Returns a multi-line string suitable for stderr.
13
+ *
14
+ * Wire shape:
15
+ *
16
+ * [<kind>] <ErrorName>: <message>
17
+ * <stack>
18
+ *
19
+ * For non-`Error` rejections (`reject("string")`, `reject(42)`,
20
+ * `reject(undefined)`), the name falls back to `UnknownError` and the
21
+ * message is `String(reason)`; there is no stack.
22
+ *
23
+ * **Redaction**: the assembled string is run through {@link redactString}
24
+ * from `@ttctl/core`, replacing every canonical Toptal session bearer
25
+ * (`user_<24hex>_<20alnum>`) with `***REDACTED***`. The crash log
26
+ * intentionally does NOT include `process.env`, command-line arguments,
27
+ * or any other ambient runtime state — those are the load-bearing
28
+ * defenses against process-environment leakage (env vars carrying
29
+ * 1Password session tokens, shell history hints, etc.). Bearer
30
+ * scrubbing is defense-in-depth for the case where a thrown error's
31
+ * message or stack frame interpolates a captured bearer.
32
+ *
33
+ * Pure — no I/O, no process state mutation.
34
+ *
35
+ * See `SECURITY.md` § Crash-output secret invariant for the
36
+ * cross-cutting contract this function satisfies.
37
+ */
38
+ export declare function formatCrashLog(err: unknown, kind: CrashKind): string;
39
+ /**
40
+ * Install global crash handlers for `uncaughtException` and
41
+ * `unhandledRejection` (issue #207). Each handler:
42
+ *
43
+ * 1. Formats the throw via {@link formatCrashLog} (bearer-pattern
44
+ * scrubbed via `@ttctl/core` `redactString`).
45
+ * 2. Writes the formatted block to `process.stderr` — never `stdout`
46
+ * (the data channel `-o json` / `-o yaml` is owned by command
47
+ * handlers and must remain uncontaminated even on crash).
48
+ * 3. Exits with code `1` (non-zero — generic error).
49
+ *
50
+ * Handlers do NOT log `process.env`, `process.argv`, or any other
51
+ * ambient runtime state; those would risk dumping shell-history hints,
52
+ * 1Password session env vars (`OP_SESSION_*`), and other secrets that
53
+ * tested crash-output assertions cannot catch from the application
54
+ * side.
55
+ *
56
+ * The umbrella bin (`packages/ttctl/src/cli.ts`) calls this once at
57
+ * startup before invoking `main()`. Calling twice would register two
58
+ * listeners for each event — Node.js permits this but it doubles the
59
+ * stderr output, so callers should treat this as a startup-only API.
60
+ *
61
+ * Exit channel: writers use `process.stderr.write` directly rather
62
+ * than `console.error` because the latter can be redirected by
63
+ * downstream test infrastructure in surprising ways. `stderr.write` is
64
+ * the most direct path to the parent process's standard-error stream.
65
+ */
66
+ export declare function installCrashHandlers(): void;
67
+ //# sourceMappingURL=crash-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-handlers.d.ts","sourceRoot":"","sources":["../src/crash-handlers.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAQpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAS3C"}
@@ -0,0 +1,78 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { redactString } from "@ttctl/core";
4
+ /**
5
+ * Build the redacted crash log for an uncaught throw or unhandled
6
+ * promise rejection. Returns a multi-line string suitable for stderr.
7
+ *
8
+ * Wire shape:
9
+ *
10
+ * [<kind>] <ErrorName>: <message>
11
+ * <stack>
12
+ *
13
+ * For non-`Error` rejections (`reject("string")`, `reject(42)`,
14
+ * `reject(undefined)`), the name falls back to `UnknownError` and the
15
+ * message is `String(reason)`; there is no stack.
16
+ *
17
+ * **Redaction**: the assembled string is run through {@link redactString}
18
+ * from `@ttctl/core`, replacing every canonical Toptal session bearer
19
+ * (`user_<24hex>_<20alnum>`) with `***REDACTED***`. The crash log
20
+ * intentionally does NOT include `process.env`, command-line arguments,
21
+ * or any other ambient runtime state — those are the load-bearing
22
+ * defenses against process-environment leakage (env vars carrying
23
+ * 1Password session tokens, shell history hints, etc.). Bearer
24
+ * scrubbing is defense-in-depth for the case where a thrown error's
25
+ * message or stack frame interpolates a captured bearer.
26
+ *
27
+ * Pure — no I/O, no process state mutation.
28
+ *
29
+ * See `SECURITY.md` § Crash-output secret invariant for the
30
+ * cross-cutting contract this function satisfies.
31
+ */
32
+ export function formatCrashLog(err, kind) {
33
+ const isError = err instanceof Error;
34
+ const name = isError ? err.name : "UnknownError";
35
+ const message = isError ? err.message : String(err);
36
+ const stack = isError && err.stack !== undefined && err.stack !== "" ? err.stack : undefined;
37
+ const head = `[${kind}] ${name}: ${message}`;
38
+ const body = stack !== undefined ? `${head}\n${stack}` : head;
39
+ return redactString(body);
40
+ }
41
+ /**
42
+ * Install global crash handlers for `uncaughtException` and
43
+ * `unhandledRejection` (issue #207). Each handler:
44
+ *
45
+ * 1. Formats the throw via {@link formatCrashLog} (bearer-pattern
46
+ * scrubbed via `@ttctl/core` `redactString`).
47
+ * 2. Writes the formatted block to `process.stderr` — never `stdout`
48
+ * (the data channel `-o json` / `-o yaml` is owned by command
49
+ * handlers and must remain uncontaminated even on crash).
50
+ * 3. Exits with code `1` (non-zero — generic error).
51
+ *
52
+ * Handlers do NOT log `process.env`, `process.argv`, or any other
53
+ * ambient runtime state; those would risk dumping shell-history hints,
54
+ * 1Password session env vars (`OP_SESSION_*`), and other secrets that
55
+ * tested crash-output assertions cannot catch from the application
56
+ * side.
57
+ *
58
+ * The umbrella bin (`packages/ttctl/src/cli.ts`) calls this once at
59
+ * startup before invoking `main()`. Calling twice would register two
60
+ * listeners for each event — Node.js permits this but it doubles the
61
+ * stderr output, so callers should treat this as a startup-only API.
62
+ *
63
+ * Exit channel: writers use `process.stderr.write` directly rather
64
+ * than `console.error` because the latter can be redirected by
65
+ * downstream test infrastructure in surprising ways. `stderr.write` is
66
+ * the most direct path to the parent process's standard-error stream.
67
+ */
68
+ export function installCrashHandlers() {
69
+ process.on("uncaughtException", (err) => {
70
+ process.stderr.write(formatCrashLog(err, "uncaughtException") + "\n");
71
+ process.exit(1);
72
+ });
73
+ process.on("unhandledRejection", (reason) => {
74
+ process.stderr.write(formatCrashLog(reason, "unhandledRejection") + "\n");
75
+ process.exit(1);
76
+ });
77
+ }
78
+ //# sourceMappingURL=crash-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crash-handlers.js","sourceRoot":"","sources":["../src/crash-handlers.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAY3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,IAAe;IAC1D,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC;IACrC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC;IACjD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,OAAO,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,MAAM,IAAI,GAAG,IAAI,IAAI,KAAK,IAAI,KAAK,OAAO,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAU,EAAE,EAAE;QAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE,mBAAmB,CAAC,GAAG,IAAI,CAAC,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAe,EAAE,EAAE;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,oBAAoB,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { TtctlError } from "@ttctl/core";
2
+ /**
3
+ * CLI presentation contract for `TtctlError` subclasses (issue #77).
4
+ *
5
+ * The CLI surface renders any `TtctlError` in a uniform multi-block format
6
+ * so users see the same shape whether the failure was an auth revocation,
7
+ * a Cloudflare 403, or a (post-v1) scheduler-bearer expiry:
8
+ *
9
+ * Error: <error.message>
10
+ *
11
+ * Recovery: <error.recovery>
12
+ *
13
+ * (Code: <error.code>)
14
+ *
15
+ * `error.message` may be multi-line (e.g. `Cf403Error.formatMessage`
16
+ * produces a 3-paragraph walkthrough); the renderer passes it through
17
+ * verbatim. `recovery` is one short imperative sentence. `code` is a
18
+ * stable machine-readable token script consumers can branch on without
19
+ * parsing prose.
20
+ *
21
+ * Pure function — no I/O. Callers route the result to `process.stderr` and
22
+ * choose an exit code via `exitCodeForTtctlError`.
23
+ */
24
+ export declare function formatTtctlErrorMessage(err: TtctlError): string;
25
+ /**
26
+ * Map a `TtctlError` to a process exit code.
27
+ *
28
+ * Default is `1` (general error — auth revoked, Cloudflare clearance
29
+ * expired, etc.). The 1 / 2 split mirrors the existing `auth status`
30
+ * convention (1 = auth-related, 2 = transient/retryable). `Cf403*` codes
31
+ * map to `2` because they are transport-level blocks the user cannot fix
32
+ * by re-authenticating.
33
+ */
34
+ export declare function exitCodeForTtctlError(err: TtctlError): number;
35
+ /**
36
+ * Side-effecting renderer: write the formatted block to `process.stderr`
37
+ * and `process.exit` with the corresponding code. Never returns.
38
+ *
39
+ * Command handlers gate this with `instanceof TtctlError` so the uniform
40
+ * presentation only applies to typed-hierarchy errors — other domain
41
+ * errors (`ProfileError`, `SignInError`, …) keep their existing
42
+ * command-specific "(CODE): message" rendering.
43
+ */
44
+ export declare function presentTtctlError(err: TtctlError): never;
45
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAE/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAK7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,GAAG,KAAK,CAGxD"}
package/dist/errors.js ADDED
@@ -0,0 +1,57 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { TtctlError } from "@ttctl/core";
4
+ /**
5
+ * CLI presentation contract for `TtctlError` subclasses (issue #77).
6
+ *
7
+ * The CLI surface renders any `TtctlError` in a uniform multi-block format
8
+ * so users see the same shape whether the failure was an auth revocation,
9
+ * a Cloudflare 403, or a (post-v1) scheduler-bearer expiry:
10
+ *
11
+ * Error: <error.message>
12
+ *
13
+ * Recovery: <error.recovery>
14
+ *
15
+ * (Code: <error.code>)
16
+ *
17
+ * `error.message` may be multi-line (e.g. `Cf403Error.formatMessage`
18
+ * produces a 3-paragraph walkthrough); the renderer passes it through
19
+ * verbatim. `recovery` is one short imperative sentence. `code` is a
20
+ * stable machine-readable token script consumers can branch on without
21
+ * parsing prose.
22
+ *
23
+ * Pure function — no I/O. Callers route the result to `process.stderr` and
24
+ * choose an exit code via `exitCodeForTtctlError`.
25
+ */
26
+ export function formatTtctlErrorMessage(err) {
27
+ return [`Error: ${err.message}`, "", `Recovery: ${err.recovery}`, "", `(Code: ${err.code})`].join("\n");
28
+ }
29
+ /**
30
+ * Map a `TtctlError` to a process exit code.
31
+ *
32
+ * Default is `1` (general error — auth revoked, Cloudflare clearance
33
+ * expired, etc.). The 1 / 2 split mirrors the existing `auth status`
34
+ * convention (1 = auth-related, 2 = transient/retryable). `Cf403*` codes
35
+ * map to `2` because they are transport-level blocks the user cannot fix
36
+ * by re-authenticating.
37
+ */
38
+ export function exitCodeForTtctlError(err) {
39
+ if (err.code === "CF_403_CLEARANCE" || err.code === "CF_403_PERSISTENT") {
40
+ return 2;
41
+ }
42
+ return 1;
43
+ }
44
+ /**
45
+ * Side-effecting renderer: write the formatted block to `process.stderr`
46
+ * and `process.exit` with the corresponding code. Never returns.
47
+ *
48
+ * Command handlers gate this with `instanceof TtctlError` so the uniform
49
+ * presentation only applies to typed-hierarchy errors — other domain
50
+ * errors (`ProfileError`, `SignInError`, …) keep their existing
51
+ * command-specific "(CODE): message" rendering.
52
+ */
53
+ export function presentTtctlError(err) {
54
+ process.stderr.write(formatTtctlErrorMessage(err) + "\n");
55
+ process.exit(exitCodeForTtctlError(err));
56
+ }
57
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAe;IACrD,OAAO,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,aAAa,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1G,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAe;IACnD,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACxE,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAe;IAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { buildProgram } from "./program.js";
2
+ export { exitCodeForTtctlError, formatTtctlErrorMessage, presentTtctlError } from "./errors.js";
3
+ export { formatCrashLog, installCrashHandlers } from "./crash-handlers.js";
4
+ export type { CrashKind } from "./crash-handlers.js";
5
+ export { TtctlError } from "@ttctl/core";
6
+ export { ConfigError } from "@ttctl/core";
7
+ export type { ConfigErrorCode } from "@ttctl/core";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAKrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}