@piecemaker-legal/piecemaker 1.0.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 (1424) hide show
  1. package/LICENSE +718 -0
  2. package/README.md +80 -0
  3. package/dist/Mistral-Icon-Gradient-RGB.svg +12 -0
  4. package/dist/api-docs.html +901 -0
  5. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  6. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  7. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  8. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  9. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  10. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  11. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  12. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  13. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  14. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  15. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  16. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  17. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  18. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  19. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  20. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  21. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  22. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  23. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  24. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  25. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  26. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  27. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  28. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  29. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  30. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  31. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  32. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  33. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  34. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  35. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  36. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  37. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  38. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  39. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  40. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  41. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  42. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  43. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  44. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  45. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  46. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  47. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  48. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  49. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  50. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  51. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  52. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  53. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  54. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  55. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  56. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  57. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  58. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  59. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  60. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  61. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  62. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  63. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  64. package/dist/assets/abnfDiagram-N423BO3Z-DjEx6DRO.js +1 -0
  65. package/dist/assets/arc-DYt0oU_6.js +1 -0
  66. package/dist/assets/architectureDiagram-T3A2C74G-Dn6DhYDe.js +36 -0
  67. package/dist/assets/blockDiagram-VBNYF7ZC-CsvhTLZi.js +132 -0
  68. package/dist/assets/c4Diagram-5PPSVZJV-BuPnjHm6.js +10 -0
  69. package/dist/assets/channel-Czt0N91A.js +1 -0
  70. package/dist/assets/chunk-2GRJ4B5K-BZJJc1-J.js +1 -0
  71. package/dist/assets/chunk-2Q5K7J3B-6stdrDbe.js +1 -0
  72. package/dist/assets/chunk-5RXB4S5H-D5UwN5cg.js +231 -0
  73. package/dist/assets/chunk-5VM5RSS4-BDB8AQ_I.js +15 -0
  74. package/dist/assets/chunk-6Q2QTUOP-RhjQ-NDz.js +88 -0
  75. package/dist/assets/chunk-GF5L2VYU-CJuiA7R4.js +206 -0
  76. package/dist/assets/chunk-JWPE2WC7-DjFkIZqh.js +1 -0
  77. package/dist/assets/chunk-KBJHAD2P-BeSQsoqv.js +1 -0
  78. package/dist/assets/chunk-RYQCIY6F-CPgwsb0o.js +1 -0
  79. package/dist/assets/chunk-XXDRQBXY-CMMVEsX3.js +1 -0
  80. package/dist/assets/classDiagram-JCYQIIEL-BrnQyrwR.js +1 -0
  81. package/dist/assets/classDiagram-v2-OCEON4UE-BrnQyrwR.js +1 -0
  82. package/dist/assets/cose-bilkent-JH36ORCC-XAdYMfi5.js +1 -0
  83. package/dist/assets/cynefin-VYW2F7L2-d2GpDBn-.js +178 -0
  84. package/dist/assets/cynefinDiagram-MW4NZA55-CGtqUrU1.js +62 -0
  85. package/dist/assets/cytoscape.esm-C10L9Icf.js +331 -0
  86. package/dist/assets/dagre-VZM6K2ZE-BxujKIsf.js +4 -0
  87. package/dist/assets/defaultLocale-DX6XiGOO.js +1 -0
  88. package/dist/assets/diagram-7IWD3JNH-CJn9hobL.js +30 -0
  89. package/dist/assets/diagram-B4RE2ZJO-DF0Cnjzz.js +3 -0
  90. package/dist/assets/diagram-LBJQPF4R-Bq4d3NfR.js +24 -0
  91. package/dist/assets/diagram-Q27KOJAE-DDdfoXt-.js +24 -0
  92. package/dist/assets/diagram-UB23O5K3-TSFk7FuJ.js +41 -0
  93. package/dist/assets/ebnfDiagram-BXEA7PRR-DRvm2Wy9.js +1 -0
  94. package/dist/assets/erDiagram-JOGREHBK-BmdN66-A.js +85 -0
  95. package/dist/assets/flowDiagram-UKHOOZJN-Dsp5LwJz.js +156 -0
  96. package/dist/assets/ganttDiagram-PKOTCBZU-CYfCQ4Yi.js +292 -0
  97. package/dist/assets/gitGraphDiagram-DS77QQ5N-DEzmuv8v.js +106 -0
  98. package/dist/assets/graph-Cx-EqisW.js +1 -0
  99. package/dist/assets/index-CqFxV_pT.css +32 -0
  100. package/dist/assets/index-dWwHeqcq.js +4989 -0
  101. package/dist/assets/infoDiagram-6WML65LV-B1EfV5Bm.js +2 -0
  102. package/dist/assets/init-Gi6I4Gst.js +1 -0
  103. package/dist/assets/ishikawaDiagram-WSZJBQD7-OuQJfUii.js +70 -0
  104. package/dist/assets/journeyDiagram-NVQOT4AX-DHIilb_4.js +139 -0
  105. package/dist/assets/kanban-definition-27J2QSJJ-D4CvKWBP.js +89 -0
  106. package/dist/assets/layout-D6BstSzF.js +1 -0
  107. package/dist/assets/linear-i_Nzyzap.js +1 -0
  108. package/dist/assets/map-CV9uif0g.js +1 -0
  109. package/dist/assets/mermaid.core-DbSHejzG.js +312 -0
  110. package/dist/assets/mindmap-definition-FAOFIHXS-DqhC-BPZ.js +96 -0
  111. package/dist/assets/ordinal-Cboi1Yqb.js +1 -0
  112. package/dist/assets/pegDiagram-VL7TDLO6-pBqvOEvm.js +1 -0
  113. package/dist/assets/pieDiagram-7S7Q4E2Y-BH53iuaz.js +39 -0
  114. package/dist/assets/quadrantDiagram-CIZ2JOQS-CvW9ldJo.js +7 -0
  115. package/dist/assets/railroadDiagram-AXF67PYL-CERi66oR.js +1 -0
  116. package/dist/assets/requirementDiagram-LRYGKXZP-DbcP4MGI.js +84 -0
  117. package/dist/assets/sankeyDiagram-W5VNT64P-DO9bPHWO.js +40 -0
  118. package/dist/assets/sequenceDiagram-SI44F4Z6-D3zd2eJS.js +162 -0
  119. package/dist/assets/server.browser-CtX3Hdl5.js +27 -0
  120. package/dist/assets/sizeCapture-X5ZJPWSS-mcEXJiem.js +1 -0
  121. package/dist/assets/stateDiagram-OKZ733FA-DMqQgpiD.js +1 -0
  122. package/dist/assets/stateDiagram-v2-UEYNNEHI-DprF_P9y.js +1 -0
  123. package/dist/assets/swimlanes-SLNWSIFB-Cb8rIhB1.js +2 -0
  124. package/dist/assets/swimlanesDiagram-ULZ7WXOC-C6NVYMho.js +8 -0
  125. package/dist/assets/timeline-definition-Z64GVDOM-BQ4r_QsK.js +120 -0
  126. package/dist/assets/vendor-codemirror-CYrSt7-U.js +41 -0
  127. package/dist/assets/vendor-react-BGZc9oRE.js +59 -0
  128. package/dist/assets/vendor-xterm-CS4rQ5Mr.js +66 -0
  129. package/dist/assets/vennDiagram-T6HMQDX7-BEkKGTum.js +34 -0
  130. package/dist/assets/wardleyDiagram-T6FBY63Y-kJwmgH-h.js +78 -0
  131. package/dist/assets/xychartDiagram-ELKLHX3M-CSJRTKCr.js +7 -0
  132. package/dist/clear-cache.html +85 -0
  133. package/dist/convert-icons.md +53 -0
  134. package/dist/favicon.png +0 -0
  135. package/dist/favicon.svg +9 -0
  136. package/dist/generate-icons.js +49 -0
  137. package/dist/icons/claude-ai-icon.svg +1 -0
  138. package/dist/icons/codex-white.svg +3 -0
  139. package/dist/icons/codex.svg +3 -0
  140. package/dist/icons/cursor-white.svg +12 -0
  141. package/dist/icons/cursor.svg +1 -0
  142. package/dist/icons/icon-128x128.png +0 -0
  143. package/dist/icons/icon-128x128.svg +12 -0
  144. package/dist/icons/icon-144x144.png +0 -0
  145. package/dist/icons/icon-144x144.svg +12 -0
  146. package/dist/icons/icon-152x152.png +0 -0
  147. package/dist/icons/icon-152x152.svg +12 -0
  148. package/dist/icons/icon-192x192.png +0 -0
  149. package/dist/icons/icon-192x192.svg +12 -0
  150. package/dist/icons/icon-384x384.png +0 -0
  151. package/dist/icons/icon-384x384.svg +12 -0
  152. package/dist/icons/icon-512x512.png +0 -0
  153. package/dist/icons/icon-512x512.svg +12 -0
  154. package/dist/icons/icon-72x72.png +0 -0
  155. package/dist/icons/icon-72x72.svg +12 -0
  156. package/dist/icons/icon-96x96.png +0 -0
  157. package/dist/icons/icon-96x96.svg +12 -0
  158. package/dist/icons/icon-template.svg +12 -0
  159. package/dist/index.html +60 -0
  160. package/dist/logo-128.png +0 -0
  161. package/dist/logo-256.png +0 -0
  162. package/dist/logo-32.png +0 -0
  163. package/dist/logo-512.png +0 -0
  164. package/dist/logo-64.png +0 -0
  165. package/dist/logo.svg +17 -0
  166. package/dist/manifest.json +61 -0
  167. package/dist/screenshots/cli-selection.png +0 -0
  168. package/dist/screenshots/desktop-main.png +0 -0
  169. package/dist/screenshots/mobile-chat.png +0 -0
  170. package/dist/screenshots/tools-modal.png +0 -0
  171. package/dist/sw.js +125 -0
  172. package/dist-server/server/index.js +345 -0
  173. package/dist-server/server/index.js.map +1 -0
  174. package/dist-server/server/load-env.js +46 -0
  175. package/dist-server/server/load-env.js.map +1 -0
  176. package/dist-server/server/modules/agent/agent.module.js +38 -0
  177. package/dist-server/server/modules/agent/agent.module.js.map +1 -0
  178. package/dist-server/server/modules/agent/agent.routes.js +1161 -0
  179. package/dist-server/server/modules/agent/agent.routes.js.map +1 -0
  180. package/dist-server/server/modules/agent/index.js +3 -0
  181. package/dist-server/server/modules/agent/index.js.map +1 -0
  182. package/dist-server/server/modules/agent/tests/agent.routes.test.js +176 -0
  183. package/dist-server/server/modules/agent/tests/agent.routes.test.js.map +1 -0
  184. package/dist-server/server/modules/assets/assets.routes.js +130 -0
  185. package/dist-server/server/modules/assets/assets.routes.js.map +1 -0
  186. package/dist-server/server/modules/assets/index.js +4 -0
  187. package/dist-server/server/modules/assets/index.js.map +1 -0
  188. package/dist-server/server/modules/assets/services/image-assets.service.js +95 -0
  189. package/dist-server/server/modules/assets/services/image-assets.service.js.map +1 -0
  190. package/dist-server/server/modules/assets/tests/image-assets.service.test.js +56 -0
  191. package/dist-server/server/modules/assets/tests/image-assets.service.test.js.map +1 -0
  192. package/dist-server/server/modules/auth/auth.middleware.js +133 -0
  193. package/dist-server/server/modules/auth/auth.middleware.js.map +1 -0
  194. package/dist-server/server/modules/auth/auth.module.js +29 -0
  195. package/dist-server/server/modules/auth/auth.module.js.map +1 -0
  196. package/dist-server/server/modules/auth/auth.routes.js +45 -0
  197. package/dist-server/server/modules/auth/auth.routes.js.map +1 -0
  198. package/dist-server/server/modules/auth/auth.service.js +113 -0
  199. package/dist-server/server/modules/auth/auth.service.js.map +1 -0
  200. package/dist-server/server/modules/auth/index.js +9 -0
  201. package/dist-server/server/modules/auth/index.js.map +1 -0
  202. package/dist-server/server/modules/auth/tests/auth.service.test.js +80 -0
  203. package/dist-server/server/modules/auth/tests/auth.service.test.js.map +1 -0
  204. package/dist-server/server/modules/browser-use/browser-use-mcp.js +352 -0
  205. package/dist-server/server/modules/browser-use/browser-use-mcp.js.map +1 -0
  206. package/dist-server/server/modules/browser-use/browser-use-mcp.routes.js +107 -0
  207. package/dist-server/server/modules/browser-use/browser-use-mcp.routes.js.map +1 -0
  208. package/dist-server/server/modules/browser-use/browser-use-runtime.js +10 -0
  209. package/dist-server/server/modules/browser-use/browser-use-runtime.js.map +1 -0
  210. package/dist-server/server/modules/browser-use/browser-use.routes.js +93 -0
  211. package/dist-server/server/modules/browser-use/browser-use.routes.js.map +1 -0
  212. package/dist-server/server/modules/browser-use/browser-use.service.js +686 -0
  213. package/dist-server/server/modules/browser-use/browser-use.service.js.map +1 -0
  214. package/dist-server/server/modules/browser-use/index.js +11 -0
  215. package/dist-server/server/modules/browser-use/index.js.map +1 -0
  216. package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js +8 -0
  217. package/dist-server/server/modules/browser-use/tests/browser-use.service.test.js.map +1 -0
  218. package/dist-server/server/modules/cli/cli.js +17 -0
  219. package/dist-server/server/modules/cli/cli.js.map +1 -0
  220. package/dist-server/server/modules/cli/cli.module.js +93 -0
  221. package/dist-server/server/modules/cli/cli.module.js.map +1 -0
  222. package/dist-server/server/modules/cli/cli.service.js +230 -0
  223. package/dist-server/server/modules/cli/cli.service.js.map +1 -0
  224. package/dist-server/server/modules/cli/index.js +3 -0
  225. package/dist-server/server/modules/cli/index.js.map +1 -0
  226. package/dist-server/server/modules/cli/pwa-launcher.js +116 -0
  227. package/dist-server/server/modules/cli/pwa-launcher.js.map +1 -0
  228. package/dist-server/server/modules/cli/sandbox.service.js +332 -0
  229. package/dist-server/server/modules/cli/sandbox.service.js.map +1 -0
  230. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js +154 -0
  231. package/dist-server/server/modules/cli/tests/cli-environment-bootstrap.test.js.map +1 -0
  232. package/dist-server/server/modules/cli/tests/cli.service.test.js +91 -0
  233. package/dist-server/server/modules/cli/tests/cli.service.test.js.map +1 -0
  234. package/dist-server/server/modules/cli/tests/sandbox.service.test.js +55 -0
  235. package/dist-server/server/modules/cli/tests/sandbox.service.test.js.map +1 -0
  236. package/dist-server/server/modules/commands/commands.module.js +20 -0
  237. package/dist-server/server/modules/commands/commands.module.js.map +1 -0
  238. package/dist-server/server/modules/commands/commands.routes.js +498 -0
  239. package/dist-server/server/modules/commands/commands.routes.js.map +1 -0
  240. package/dist-server/server/modules/commands/index.js +3 -0
  241. package/dist-server/server/modules/commands/index.js.map +1 -0
  242. package/dist-server/server/modules/commands/tests/commands.test.js +91 -0
  243. package/dist-server/server/modules/commands/tests/commands.test.js.map +1 -0
  244. package/dist-server/server/modules/database/connection.js +125 -0
  245. package/dist-server/server/modules/database/connection.js.map +1 -0
  246. package/dist-server/server/modules/database/index.js +23 -0
  247. package/dist-server/server/modules/database/index.js.map +1 -0
  248. package/dist-server/server/modules/database/init-db.js +18 -0
  249. package/dist-server/server/modules/database/init-db.js.map +1 -0
  250. package/dist-server/server/modules/database/migrations.js +465 -0
  251. package/dist-server/server/modules/database/migrations.js.map +1 -0
  252. package/dist-server/server/modules/database/repositories/api-keys.js +72 -0
  253. package/dist-server/server/modules/database/repositories/api-keys.js.map +1 -0
  254. package/dist-server/server/modules/database/repositories/app-config.js +47 -0
  255. package/dist-server/server/modules/database/repositories/app-config.js.map +1 -0
  256. package/dist-server/server/modules/database/repositories/credentials.js +68 -0
  257. package/dist-server/server/modules/database/repositories/credentials.js.map +1 -0
  258. package/dist-server/server/modules/database/repositories/github-tokens.js +54 -0
  259. package/dist-server/server/modules/database/repositories/github-tokens.js.map +1 -0
  260. package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js +100 -0
  261. package/dist-server/server/modules/database/repositories/notification-channel-endpoints.js.map +1 -0
  262. package/dist-server/server/modules/database/repositories/notification-preferences.js +82 -0
  263. package/dist-server/server/modules/database/repositories/notification-preferences.js.map +1 -0
  264. package/dist-server/server/modules/database/repositories/projects.db.js +172 -0
  265. package/dist-server/server/modules/database/repositories/projects.db.js.map +1 -0
  266. package/dist-server/server/modules/database/repositories/provider-models.js +112 -0
  267. package/dist-server/server/modules/database/repositories/provider-models.js.map +1 -0
  268. package/dist-server/server/modules/database/repositories/push-subscriptions.js +49 -0
  269. package/dist-server/server/modules/database/repositories/push-subscriptions.js.map +1 -0
  270. package/dist-server/server/modules/database/repositories/scan-state.db.js +31 -0
  271. package/dist-server/server/modules/database/repositories/scan-state.db.js.map +1 -0
  272. package/dist-server/server/modules/database/repositories/scheduled-messages.db.js +71 -0
  273. package/dist-server/server/modules/database/repositories/scheduled-messages.db.js.map +1 -0
  274. package/dist-server/server/modules/database/repositories/session-drafts.db.js +105 -0
  275. package/dist-server/server/modules/database/repositories/session-drafts.db.js.map +1 -0
  276. package/dist-server/server/modules/database/repositories/sessions.db.js +507 -0
  277. package/dist-server/server/modules/database/repositories/sessions.db.js.map +1 -0
  278. package/dist-server/server/modules/database/repositories/user-preferences.db.js +65 -0
  279. package/dist-server/server/modules/database/repositories/user-preferences.db.js.map +1 -0
  280. package/dist-server/server/modules/database/repositories/users.js +88 -0
  281. package/dist-server/server/modules/database/repositories/users.js.map +1 -0
  282. package/dist-server/server/modules/database/repositories/vapid-keys.js +38 -0
  283. package/dist-server/server/modules/database/repositories/vapid-keys.js.map +1 -0
  284. package/dist-server/server/modules/database/schema.js +291 -0
  285. package/dist-server/server/modules/database/schema.js.map +1 -0
  286. package/dist-server/server/modules/database/tests/projects.db.integration.test.js +64 -0
  287. package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -0
  288. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js +102 -0
  289. package/dist-server/server/modules/database/tests/provider-models.db.integration.test.js.map +1 -0
  290. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js +79 -0
  291. package/dist-server/server/modules/database/tests/sessions-provider-mapping.test.js.map +1 -0
  292. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js +93 -0
  293. package/dist-server/server/modules/database/tests/sessions.db.integration.test.js.map +1 -0
  294. package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js +105 -0
  295. package/dist-server/server/modules/database/tests/user-preferences.db.integration.test.js.map +1 -0
  296. package/dist-server/server/modules/file-tree/file-tree.module.js +95 -0
  297. package/dist-server/server/modules/file-tree/file-tree.module.js.map +1 -0
  298. package/dist-server/server/modules/file-tree/file-tree.routes.js +208 -0
  299. package/dist-server/server/modules/file-tree/file-tree.routes.js.map +1 -0
  300. package/dist-server/server/modules/file-tree/file-tree.service.js +584 -0
  301. package/dist-server/server/modules/file-tree/file-tree.service.js.map +1 -0
  302. package/dist-server/server/modules/file-tree/index.js +3 -0
  303. package/dist-server/server/modules/file-tree/index.js.map +1 -0
  304. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js +123 -0
  305. package/dist-server/server/modules/file-tree/tests/file-tree.routes.test.js.map +1 -0
  306. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js +311 -0
  307. package/dist-server/server/modules/file-tree/tests/file-tree.service.test.js.map +1 -0
  308. package/dist-server/server/modules/git/git-branch.service.js +15 -0
  309. package/dist-server/server/modules/git/git-branch.service.js.map +1 -0
  310. package/dist-server/server/modules/git/git-parsing.service.js +61 -0
  311. package/dist-server/server/modules/git/git-parsing.service.js.map +1 -0
  312. package/dist-server/server/modules/git/git.module.js +14 -0
  313. package/dist-server/server/modules/git/git.module.js.map +1 -0
  314. package/dist-server/server/modules/git/git.routes.js +1347 -0
  315. package/dist-server/server/modules/git/git.routes.js.map +1 -0
  316. package/dist-server/server/modules/git/index.js +3 -0
  317. package/dist-server/server/modules/git/index.js.map +1 -0
  318. package/dist-server/server/modules/git/tests/git-branch.service.test.js +52 -0
  319. package/dist-server/server/modules/git/tests/git-branch.service.test.js.map +1 -0
  320. package/dist-server/server/modules/git/tests/git-init.routes.test.js +132 -0
  321. package/dist-server/server/modules/git/tests/git-init.routes.test.js.map +1 -0
  322. package/dist-server/server/modules/git/tests/git.test.js +80 -0
  323. package/dist-server/server/modules/git/tests/git.test.js.map +1 -0
  324. package/dist-server/server/modules/notifications/index.js +20 -0
  325. package/dist-server/server/modules/notifications/index.js.map +1 -0
  326. package/dist-server/server/modules/notifications/notifications.routes.js +115 -0
  327. package/dist-server/server/modules/notifications/notifications.routes.js.map +1 -0
  328. package/dist-server/server/modules/notifications/services/desktop-notification-clients.service.js +97 -0
  329. package/dist-server/server/modules/notifications/services/desktop-notification-clients.service.js.map +1 -0
  330. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js +249 -0
  331. package/dist-server/server/modules/notifications/services/notification-orchestrator.service.js.map +1 -0
  332. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js +44 -0
  333. package/dist-server/server/modules/notifications/tests/notification-orchestrator.integration.test.js.map +1 -0
  334. package/dist-server/server/modules/notifications/vapid-keys.service.js +28 -0
  335. package/dist-server/server/modules/notifications/vapid-keys.service.js.map +1 -0
  336. package/dist-server/server/modules/notifications/websocket/desktop-notifications-websocket.service.js +79 -0
  337. package/dist-server/server/modules/notifications/websocket/desktop-notifications-websocket.service.js.map +1 -0
  338. package/dist-server/server/modules/plugins/index.js +9 -0
  339. package/dist-server/server/modules/plugins/index.js.map +1 -0
  340. package/dist-server/server/modules/plugins/plugin-process.service.js +191 -0
  341. package/dist-server/server/modules/plugins/plugin-process.service.js.map +1 -0
  342. package/dist-server/server/modules/plugins/plugin-registry.service.js +415 -0
  343. package/dist-server/server/modules/plugins/plugin-registry.service.js.map +1 -0
  344. package/dist-server/server/modules/plugins/plugins.module.js +30 -0
  345. package/dist-server/server/modules/plugins/plugins.module.js.map +1 -0
  346. package/dist-server/server/modules/plugins/plugins.routes.js +70 -0
  347. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -0
  348. package/dist-server/server/modules/plugins/plugins.service.js +123 -0
  349. package/dist-server/server/modules/plugins/plugins.service.js.map +1 -0
  350. package/dist-server/server/modules/plugins/tests/plugins.service.test.js +28 -0
  351. package/dist-server/server/modules/plugins/tests/plugins.service.test.js.map +1 -0
  352. package/dist-server/server/modules/projects/index.js +9 -0
  353. package/dist-server/server/modules/projects/index.js.map +1 -0
  354. package/dist-server/server/modules/projects/projects.routes.js +205 -0
  355. package/dist-server/server/modules/projects/projects.routes.js.map +1 -0
  356. package/dist-server/server/modules/projects/services/project-clone.service.js +220 -0
  357. package/dist-server/server/modules/projects/services/project-clone.service.js.map +1 -0
  358. package/dist-server/server/modules/projects/services/project-delete.service.js +89 -0
  359. package/dist-server/server/modules/projects/services/project-delete.service.js.map +1 -0
  360. package/dist-server/server/modules/projects/services/project-management.service.js +90 -0
  361. package/dist-server/server/modules/projects/services/project-management.service.js.map +1 -0
  362. package/dist-server/server/modules/projects/services/project-star.service.js +60 -0
  363. package/dist-server/server/modules/projects/services/project-star.service.js.map +1 -0
  364. package/dist-server/server/modules/projects/services/projects-has-taskmaster.service.js +167 -0
  365. package/dist-server/server/modules/projects/services/projects-has-taskmaster.service.js.map +1 -0
  366. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js +188 -0
  367. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js.map +1 -0
  368. package/dist-server/server/modules/projects/tests/project-clone.service.test.js +126 -0
  369. package/dist-server/server/modules/projects/tests/project-clone.service.test.js.map +1 -0
  370. package/dist-server/server/modules/projects/tests/project-management.service.test.js +85 -0
  371. package/dist-server/server/modules/projects/tests/project-management.service.test.js.map +1 -0
  372. package/dist-server/server/modules/projects/tests/project-star.service.test.js +95 -0
  373. package/dist-server/server/modules/projects/tests/project-star.service.test.js.map +1 -0
  374. package/dist-server/server/modules/projects/tests/projects-has-taskmaster.service.test.js +87 -0
  375. package/dist-server/server/modules/projects/tests/projects-has-taskmaster.service.test.js.map +1 -0
  376. package/dist-server/server/modules/providers/index.js +12 -0
  377. package/dist-server/server/modules/providers/index.js.map +1 -0
  378. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js +151 -0
  379. package/dist-server/server/modules/providers/list/claude/claude-auth.provider.js.map +1 -0
  380. package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js +46 -0
  381. package/dist-server/server/modules/providers/list/claude/claude-fork.provider.js.map +1 -0
  382. package/dist-server/server/modules/providers/list/claude/claude-mcp.provider.js +103 -0
  383. package/dist-server/server/modules/providers/list/claude/claude-mcp.provider.js.map +1 -0
  384. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +267 -0
  385. package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -0
  386. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js +1058 -0
  387. package/dist-server/server/modules/providers/list/claude/claude-runtime.provider.js.map +1 -0
  388. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js +141 -0
  389. package/dist-server/server/modules/providers/list/claude/claude-session-synchronizer.provider.js.map +1 -0
  390. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js +924 -0
  391. package/dist-server/server/modules/providers/list/claude/claude-sessions.provider.js.map +1 -0
  392. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js +205 -0
  393. package/dist-server/server/modules/providers/list/claude/claude-skills.provider.js.map +1 -0
  394. package/dist-server/server/modules/providers/list/claude/claude.provider.js +23 -0
  395. package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -0
  396. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js +204 -0
  397. package/dist-server/server/modules/providers/list/codex/codex-app-server.client.js.map +1 -0
  398. package/dist-server/server/modules/providers/list/codex/codex-auth.provider.js +84 -0
  399. package/dist-server/server/modules/providers/list/codex/codex-auth.provider.js.map +1 -0
  400. package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js +32 -0
  401. package/dist-server/server/modules/providers/list/codex/codex-fork.provider.js.map +1 -0
  402. package/dist-server/server/modules/providers/list/codex/codex-mcp.provider.js +107 -0
  403. package/dist-server/server/modules/providers/list/codex/codex-mcp.provider.js.map +1 -0
  404. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +109 -0
  405. package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -0
  406. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js +498 -0
  407. package/dist-server/server/modules/providers/list/codex/codex-runtime.provider.js.map +1 -0
  408. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js +153 -0
  409. package/dist-server/server/modules/providers/list/codex/codex-session-synchronizer.provider.js.map +1 -0
  410. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js +1955 -0
  411. package/dist-server/server/modules/providers/list/codex/codex-sessions.provider.js.map +1 -0
  412. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +62 -0
  413. package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -0
  414. package/dist-server/server/modules/providers/list/codex/codex.provider.js +23 -0
  415. package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -0
  416. package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js +118 -0
  417. package/dist-server/server/modules/providers/list/cursor/cursor-auth.provider.js.map +1 -0
  418. package/dist-server/server/modules/providers/list/cursor/cursor-mcp.provider.js +80 -0
  419. package/dist-server/server/modules/providers/list/cursor/cursor-mcp.provider.js.map +1 -0
  420. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +100 -0
  421. package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -0
  422. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js +305 -0
  423. package/dist-server/server/modules/providers/list/cursor/cursor-runtime.provider.js.map +1 -0
  424. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js +111 -0
  425. package/dist-server/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.js.map +1 -0
  426. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +566 -0
  427. package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -0
  428. package/dist-server/server/modules/providers/list/cursor/cursor-skills.provider.js +35 -0
  429. package/dist-server/server/modules/providers/list/cursor/cursor-skills.provider.js.map +1 -0
  430. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +21 -0
  431. package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -0
  432. package/dist-server/server/modules/providers/list/mistral/mistral-auth.provider.js +147 -0
  433. package/dist-server/server/modules/providers/list/mistral/mistral-auth.provider.js.map +1 -0
  434. package/dist-server/server/modules/providers/list/mistral/mistral-mcp.provider.js +15 -0
  435. package/dist-server/server/modules/providers/list/mistral/mistral-mcp.provider.js.map +1 -0
  436. package/dist-server/server/modules/providers/list/mistral/mistral-models.provider.js +69 -0
  437. package/dist-server/server/modules/providers/list/mistral/mistral-models.provider.js.map +1 -0
  438. package/dist-server/server/modules/providers/list/mistral/mistral-runtime.provider.js +326 -0
  439. package/dist-server/server/modules/providers/list/mistral/mistral-runtime.provider.js.map +1 -0
  440. package/dist-server/server/modules/providers/list/mistral/mistral-session-synchronizer.provider.js +12 -0
  441. package/dist-server/server/modules/providers/list/mistral/mistral-session-synchronizer.provider.js.map +1 -0
  442. package/dist-server/server/modules/providers/list/mistral/mistral-sessions.provider.js +180 -0
  443. package/dist-server/server/modules/providers/list/mistral/mistral-sessions.provider.js.map +1 -0
  444. package/dist-server/server/modules/providers/list/mistral/mistral-skills.provider.js +15 -0
  445. package/dist-server/server/modules/providers/list/mistral/mistral-skills.provider.js.map +1 -0
  446. package/dist-server/server/modules/providers/list/mistral/mistral.provider.js +25 -0
  447. package/dist-server/server/modules/providers/list/mistral/mistral.provider.js.map +1 -0
  448. package/dist-server/server/modules/providers/list/opencode/opencode-auth.provider.js +91 -0
  449. package/dist-server/server/modules/providers/list/opencode/opencode-auth.provider.js.map +1 -0
  450. package/dist-server/server/modules/providers/list/opencode/opencode-mcp.provider.js +181 -0
  451. package/dist-server/server/modules/providers/list/opencode/opencode-mcp.provider.js.map +1 -0
  452. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +257 -0
  453. package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -0
  454. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js +368 -0
  455. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.js.map +1 -0
  456. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +225 -0
  457. package/dist-server/server/modules/providers/list/opencode/opencode-runtime.provider.test.js.map +1 -0
  458. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +136 -0
  459. package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -0
  460. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +404 -0
  461. package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -0
  462. package/dist-server/server/modules/providers/list/opencode/opencode-skills.provider.js +62 -0
  463. package/dist-server/server/modules/providers/list/opencode/opencode-skills.provider.js.map +1 -0
  464. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +21 -0
  465. package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -0
  466. package/dist-server/server/modules/providers/provider.registry.js +33 -0
  467. package/dist-server/server/modules/providers/provider.registry.js.map +1 -0
  468. package/dist-server/server/modules/providers/provider.routes.js +676 -0
  469. package/dist-server/server/modules/providers/provider.routes.js.map +1 -0
  470. package/dist-server/server/modules/providers/services/mcp.service.js +84 -0
  471. package/dist-server/server/modules/providers/services/mcp.service.js.map +1 -0
  472. package/dist-server/server/modules/providers/services/provider-auth.service.js +25 -0
  473. package/dist-server/server/modules/providers/services/provider-auth.service.js.map +1 -0
  474. package/dist-server/server/modules/providers/services/provider-capabilities.service.js +94 -0
  475. package/dist-server/server/modules/providers/services/provider-capabilities.service.js.map +1 -0
  476. package/dist-server/server/modules/providers/services/provider-models.service.js +289 -0
  477. package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -0
  478. package/dist-server/server/modules/providers/services/provider-runtime.service.js +66 -0
  479. package/dist-server/server/modules/providers/services/provider-runtime.service.js.map +1 -0
  480. package/dist-server/server/modules/providers/services/provider-token-usage.service.js +372 -0
  481. package/dist-server/server/modules/providers/services/provider-token-usage.service.js.map +1 -0
  482. package/dist-server/server/modules/providers/services/session-conversations-search.service.js +974 -0
  483. package/dist-server/server/modules/providers/services/session-conversations-search.service.js.map +1 -0
  484. package/dist-server/server/modules/providers/services/session-history-cache.service.js +87 -0
  485. package/dist-server/server/modules/providers/services/session-history-cache.service.js.map +1 -0
  486. package/dist-server/server/modules/providers/services/session-synchronizer.service.js +130 -0
  487. package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -0
  488. package/dist-server/server/modules/providers/services/sessions-watcher.service.js +214 -0
  489. package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -0
  490. package/dist-server/server/modules/providers/services/sessions.service.js +519 -0
  491. package/dist-server/server/modules/providers/services/sessions.service.js.map +1 -0
  492. package/dist-server/server/modules/providers/services/skills.service.js +22 -0
  493. package/dist-server/server/modules/providers/services/skills.service.js.map +1 -0
  494. package/dist-server/server/modules/providers/shared/base/abstract.provider.js +13 -0
  495. package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -0
  496. package/dist-server/server/modules/providers/shared/mcp/mcp.provider.js +102 -0
  497. package/dist-server/server/modules/providers/shared/mcp/mcp.provider.js.map +1 -0
  498. package/dist-server/server/modules/providers/shared/skills/skills.provider.js +207 -0
  499. package/dist-server/server/modules/providers/shared/skills/skills.provider.js.map +1 -0
  500. package/dist-server/server/modules/providers/tests/claude-auth.test.js +174 -0
  501. package/dist-server/server/modules/providers/tests/claude-auth.test.js.map +1 -0
  502. package/dist-server/server/modules/providers/tests/claude-sessions.test.js +470 -0
  503. package/dist-server/server/modules/providers/tests/claude-sessions.test.js.map +1 -0
  504. package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js +16 -0
  505. package/dist-server/server/modules/providers/tests/claude-subagent-echo.test.js.map +1 -0
  506. package/dist-server/server/modules/providers/tests/claude-token-budget.test.js +85 -0
  507. package/dist-server/server/modules/providers/tests/claude-token-budget.test.js.map +1 -0
  508. package/dist-server/server/modules/providers/tests/codex-message-editing.test.js +338 -0
  509. package/dist-server/server/modules/providers/tests/codex-message-editing.test.js.map +1 -0
  510. package/dist-server/server/modules/providers/tests/codex-session-fork.test.js +54 -0
  511. package/dist-server/server/modules/providers/tests/codex-session-fork.test.js.map +1 -0
  512. package/dist-server/server/modules/providers/tests/codex-sessions.test.js +491 -0
  513. package/dist-server/server/modules/providers/tests/codex-sessions.test.js.map +1 -0
  514. package/dist-server/server/modules/providers/tests/mcp.test.js +291 -0
  515. package/dist-server/server/modules/providers/tests/mcp.test.js.map +1 -0
  516. package/dist-server/server/modules/providers/tests/opencode-models.test.js +103 -0
  517. package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -0
  518. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +424 -0
  519. package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -0
  520. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js +205 -0
  521. package/dist-server/server/modules/providers/tests/provider-attachment-history.test.js.map +1 -0
  522. package/dist-server/server/modules/providers/tests/provider-models.service.test.js +268 -0
  523. package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -0
  524. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js +126 -0
  525. package/dist-server/server/modules/providers/tests/provider-runtime.service.test.js.map +1 -0
  526. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js +329 -0
  527. package/dist-server/server/modules/providers/tests/provider-token-usage.service.test.js.map +1 -0
  528. package/dist-server/server/modules/providers/tests/provider.routes.test.js +161 -0
  529. package/dist-server/server/modules/providers/tests/provider.routes.test.js.map +1 -0
  530. package/dist-server/server/modules/providers/tests/session-fork.test.js +113 -0
  531. package/dist-server/server/modules/providers/tests/session-fork.test.js.map +1 -0
  532. package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js +120 -0
  533. package/dist-server/server/modules/providers/tests/session-history-cache.service.test.js.map +1 -0
  534. package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js +90 -0
  535. package/dist-server/server/modules/providers/tests/session-orphan-prune.test.js.map +1 -0
  536. package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js +122 -0
  537. package/dist-server/server/modules/providers/tests/session-synchronizer-coalescing.test.js.map +1 -0
  538. package/dist-server/server/modules/providers/tests/sessions-details.test.js +62 -0
  539. package/dist-server/server/modules/providers/tests/sessions-details.test.js.map +1 -0
  540. package/dist-server/server/modules/providers/tests/sessions.service.test.js +131 -0
  541. package/dist-server/server/modules/providers/tests/sessions.service.test.js.map +1 -0
  542. package/dist-server/server/modules/providers/tests/skills.test.js +398 -0
  543. package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -0
  544. package/dist-server/server/modules/scheduled-messages/index.js +5 -0
  545. package/dist-server/server/modules/scheduled-messages/index.js.map +1 -0
  546. package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js +47 -0
  547. package/dist-server/server/modules/scheduled-messages/scheduled-messages.routes.js.map +1 -0
  548. package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js +163 -0
  549. package/dist-server/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.js.map +1 -0
  550. package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js +95 -0
  551. package/dist-server/server/modules/scheduled-messages/services/scheduled-messages.service.js.map +1 -0
  552. package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js +255 -0
  553. package/dist-server/server/modules/scheduled-messages/tests/scheduled-messages.test.js.map +1 -0
  554. package/dist-server/server/modules/settings/index.js +3 -0
  555. package/dist-server/server/modules/settings/index.js.map +1 -0
  556. package/dist-server/server/modules/settings/settings.module.js +35 -0
  557. package/dist-server/server/modules/settings/settings.module.js.map +1 -0
  558. package/dist-server/server/modules/settings/settings.routes.js +34 -0
  559. package/dist-server/server/modules/settings/settings.routes.js.map +1 -0
  560. package/dist-server/server/modules/settings/settings.service.js +116 -0
  561. package/dist-server/server/modules/settings/settings.service.js.map +1 -0
  562. package/dist-server/server/modules/settings/tests/settings.service.test.js +48 -0
  563. package/dist-server/server/modules/settings/tests/settings.service.test.js.map +1 -0
  564. package/dist-server/server/modules/system/index.js +3 -0
  565. package/dist-server/server/modules/system/index.js.map +1 -0
  566. package/dist-server/server/modules/system/system.module.js +44 -0
  567. package/dist-server/server/modules/system/system.module.js.map +1 -0
  568. package/dist-server/server/modules/system/system.routes.js +16 -0
  569. package/dist-server/server/modules/system/system.routes.js.map +1 -0
  570. package/dist-server/server/modules/system/system.service.js +45 -0
  571. package/dist-server/server/modules/system/system.service.js.map +1 -0
  572. package/dist-server/server/modules/system/tests/system.service.test.js +100 -0
  573. package/dist-server/server/modules/system/tests/system.service.test.js.map +1 -0
  574. package/dist-server/server/modules/taskmaster/index.js +3 -0
  575. package/dist-server/server/modules/taskmaster/index.js.map +1 -0
  576. package/dist-server/server/modules/taskmaster/taskmaster.module.js +20 -0
  577. package/dist-server/server/modules/taskmaster/taskmaster.module.js.map +1 -0
  578. package/dist-server/server/modules/taskmaster/taskmaster.routes.js +1372 -0
  579. package/dist-server/server/modules/taskmaster/taskmaster.routes.js.map +1 -0
  580. package/dist-server/server/modules/taskmaster/taskmaster.service.js +107 -0
  581. package/dist-server/server/modules/taskmaster/taskmaster.service.js.map +1 -0
  582. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js +180 -0
  583. package/dist-server/server/modules/taskmaster/tests/taskmaster.routes.test.js.map +1 -0
  584. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js +85 -0
  585. package/dist-server/server/modules/taskmaster/tests/taskmaster.service.test.js.map +1 -0
  586. package/dist-server/server/modules/user/index.js +3 -0
  587. package/dist-server/server/modules/user/index.js.map +1 -0
  588. package/dist-server/server/modules/user/tests/user.service.test.js +123 -0
  589. package/dist-server/server/modules/user/tests/user.service.test.js.map +1 -0
  590. package/dist-server/server/modules/user/user.module.js +56 -0
  591. package/dist-server/server/modules/user/user.module.js.map +1 -0
  592. package/dist-server/server/modules/user/user.routes.js +88 -0
  593. package/dist-server/server/modules/user/user.routes.js.map +1 -0
  594. package/dist-server/server/modules/user/user.service.js +134 -0
  595. package/dist-server/server/modules/user/user.service.js.map +1 -0
  596. package/dist-server/server/modules/voice/index.js +3 -0
  597. package/dist-server/server/modules/voice/index.js.map +1 -0
  598. package/dist-server/server/modules/voice/tests/voice.service.test.js +87 -0
  599. package/dist-server/server/modules/voice/tests/voice.service.test.js.map +1 -0
  600. package/dist-server/server/modules/voice/voice.module.js +44 -0
  601. package/dist-server/server/modules/voice/voice.module.js.map +1 -0
  602. package/dist-server/server/modules/voice/voice.routes.js +87 -0
  603. package/dist-server/server/modules/voice/voice.routes.js.map +1 -0
  604. package/dist-server/server/modules/voice/voice.service.js +148 -0
  605. package/dist-server/server/modules/voice/voice.service.js.map +1 -0
  606. package/dist-server/server/modules/websocket/index.js +11 -0
  607. package/dist-server/server/modules/websocket/index.js.map +1 -0
  608. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js +232 -0
  609. package/dist-server/server/modules/websocket/services/chat-run-registry.service.js.map +1 -0
  610. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js +135 -0
  611. package/dist-server/server/modules/websocket/services/chat-session-writer.service.js.map +1 -0
  612. package/dist-server/server/modules/websocket/services/chat-websocket.service.js +467 -0
  613. package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -0
  614. package/dist-server/server/modules/websocket/services/plugin-websocket-proxy.service.js +52 -0
  615. package/dist-server/server/modules/websocket/services/plugin-websocket-proxy.service.js.map +1 -0
  616. package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js +94 -0
  617. package/dist-server/server/modules/websocket/services/session-upsert-broadcast.service.js.map +1 -0
  618. package/dist-server/server/modules/websocket/services/shell-websocket.service.js +472 -0
  619. package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -0
  620. package/dist-server/server/modules/websocket/services/websocket-auth.service.js +36 -0
  621. package/dist-server/server/modules/websocket/services/websocket-auth.service.js.map +1 -0
  622. package/dist-server/server/modules/websocket/services/websocket-server.service.js +90 -0
  623. package/dist-server/server/modules/websocket/services/websocket-server.service.js.map +1 -0
  624. package/dist-server/server/modules/websocket/services/websocket-state.service.js +14 -0
  625. package/dist-server/server/modules/websocket/services/websocket-state.service.js.map +1 -0
  626. package/dist-server/server/modules/websocket/services/websocket-writer.service.js +32 -0
  627. package/dist-server/server/modules/websocket/services/websocket-writer.service.js.map +1 -0
  628. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js +40 -0
  629. package/dist-server/server/modules/websocket/tests/chat-attachment-filter.test.js.map +1 -0
  630. package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js +263 -0
  631. package/dist-server/server/modules/websocket/tests/chat-edit-send.test.js.map +1 -0
  632. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js +275 -0
  633. package/dist-server/server/modules/websocket/tests/chat-run-registry.test.js.map +1 -0
  634. package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js +106 -0
  635. package/dist-server/server/modules/websocket/tests/session-upsert-broadcast.test.js.map +1 -0
  636. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js +177 -0
  637. package/dist-server/server/modules/websocket/tests/shell-websocket.service.test.js.map +1 -0
  638. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js +61 -0
  639. package/dist-server/server/modules/websocket/tests/websocket-heartbeat.service.test.js.map +1 -0
  640. package/dist-server/server/modules/worktrees/index.js +3 -0
  641. package/dist-server/server/modules/worktrees/index.js.map +1 -0
  642. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js +37 -0
  643. package/dist-server/server/modules/worktrees/services/worktree-create-and-open.service.js.map +1 -0
  644. package/dist-server/server/modules/worktrees/services/worktree-create.service.js +67 -0
  645. package/dist-server/server/modules/worktrees/services/worktree-create.service.js.map +1 -0
  646. package/dist-server/server/modules/worktrees/services/worktree-git.service.js +172 -0
  647. package/dist-server/server/modules/worktrees/services/worktree-git.service.js.map +1 -0
  648. package/dist-server/server/modules/worktrees/services/worktree-list.service.js +91 -0
  649. package/dist-server/server/modules/worktrees/services/worktree-list.service.js.map +1 -0
  650. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js +118 -0
  651. package/dist-server/server/modules/worktrees/services/worktree-merge.service.js.map +1 -0
  652. package/dist-server/server/modules/worktrees/services/worktree-open.service.js +58 -0
  653. package/dist-server/server/modules/worktrees/services/worktree-open.service.js.map +1 -0
  654. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js +65 -0
  655. package/dist-server/server/modules/worktrees/services/worktree-remove.service.js.map +1 -0
  656. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js +58 -0
  657. package/dist-server/server/modules/worktrees/tests/worktree-create-and-open.service.test.js.map +1 -0
  658. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js +85 -0
  659. package/dist-server/server/modules/worktrees/tests/worktree-create.service.test.js.map +1 -0
  660. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js +58 -0
  661. package/dist-server/server/modules/worktrees/tests/worktree-git.service.test.js.map +1 -0
  662. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js +34 -0
  663. package/dist-server/server/modules/worktrees/tests/worktree-list.service.test.js.map +1 -0
  664. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js +137 -0
  665. package/dist-server/server/modules/worktrees/tests/worktree-merge.service.test.js.map +1 -0
  666. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js +99 -0
  667. package/dist-server/server/modules/worktrees/tests/worktree-open.service.test.js.map +1 -0
  668. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js +157 -0
  669. package/dist-server/server/modules/worktrees/tests/worktree-remove.service.test.js.map +1 -0
  670. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js +167 -0
  671. package/dist-server/server/modules/worktrees/tests/worktrees.routes.test.js.map +1 -0
  672. package/dist-server/server/modules/worktrees/worktrees.module.js +97 -0
  673. package/dist-server/server/modules/worktrees/worktrees.module.js.map +1 -0
  674. package/dist-server/server/modules/worktrees/worktrees.routes.js +84 -0
  675. package/dist-server/server/modules/worktrees/worktrees.routes.js.map +1 -0
  676. package/dist-server/server/piecemaker/activation/claude-mcp.cjs +109 -0
  677. package/dist-server/server/piecemaker/activation/claude-mcp.cjs.map +1 -0
  678. package/dist-server/server/piecemaker/activation/claude-plugins.cjs +60 -0
  679. package/dist-server/server/piecemaker/activation/claude-plugins.cjs.map +1 -0
  680. package/dist-server/server/piecemaker/activation/codex-mcp.cjs +93 -0
  681. package/dist-server/server/piecemaker/activation/codex-mcp.cjs.map +1 -0
  682. package/dist-server/server/piecemaker/activation/errors.cjs +14 -0
  683. package/dist-server/server/piecemaker/activation/errors.cjs.map +1 -0
  684. package/dist-server/server/piecemaker/activation/library.cjs +281 -0
  685. package/dist-server/server/piecemaker/activation/library.cjs.map +1 -0
  686. package/dist-server/server/piecemaker/activation/library.test.js +281 -0
  687. package/dist-server/server/piecemaker/activation/library.test.js.map +1 -0
  688. package/dist-server/server/piecemaker/activation/markdown.cjs +103 -0
  689. package/dist-server/server/piecemaker/activation/markdown.cjs.map +1 -0
  690. package/dist-server/server/piecemaker/activation/paths.cjs +103 -0
  691. package/dist-server/server/piecemaker/activation/paths.cjs.map +1 -0
  692. package/dist-server/server/piecemaker/activation/paths.test.js +91 -0
  693. package/dist-server/server/piecemaker/activation/paths.test.js.map +1 -0
  694. package/dist-server/server/piecemaker/activation/routes.cjs +100 -0
  695. package/dist-server/server/piecemaker/activation/routes.cjs.map +1 -0
  696. package/dist-server/server/piecemaker/activation/routes.test.js +307 -0
  697. package/dist-server/server/piecemaker/activation/routes.test.js.map +1 -0
  698. package/dist-server/server/piecemaker/activation/snapshot.cjs +28 -0
  699. package/dist-server/server/piecemaker/activation/snapshot.cjs.map +1 -0
  700. package/dist-server/server/piecemaker/anonymizer/anonymizer.test.js +282 -0
  701. package/dist-server/server/piecemaker/anonymizer/anonymizer.test.js.map +1 -0
  702. package/dist-server/server/piecemaker/anonymizer/client-config.cjs +224 -0
  703. package/dist-server/server/piecemaker/anonymizer/client-config.cjs.map +1 -0
  704. package/dist-server/server/piecemaker/anonymizer/codex-http.test.js +19 -0
  705. package/dist-server/server/piecemaker/anonymizer/codex-http.test.js.map +1 -0
  706. package/dist-server/server/piecemaker/anonymizer/dictionary.cjs +163 -0
  707. package/dist-server/server/piecemaker/anonymizer/dictionary.cjs.map +1 -0
  708. package/dist-server/server/piecemaker/anonymizer/lifecycle.js +20 -0
  709. package/dist-server/server/piecemaker/anonymizer/lifecycle.js.map +1 -0
  710. package/dist-server/server/piecemaker/anonymizer/lifecycle.test.js +35 -0
  711. package/dist-server/server/piecemaker/anonymizer/lifecycle.test.js.map +1 -0
  712. package/dist-server/server/piecemaker/anonymizer/providers.cjs +236 -0
  713. package/dist-server/server/piecemaker/anonymizer/providers.cjs.map +1 -0
  714. package/dist-server/server/piecemaker/anonymizer/proxy.cjs +338 -0
  715. package/dist-server/server/piecemaker/anonymizer/proxy.cjs.map +1 -0
  716. package/dist-server/server/piecemaker/anonymizer/rewrite.cjs +249 -0
  717. package/dist-server/server/piecemaker/anonymizer/rewrite.cjs.map +1 -0
  718. package/dist-server/server/piecemaker/anonymizer/service.cjs +217 -0
  719. package/dist-server/server/piecemaker/anonymizer/service.cjs.map +1 -0
  720. package/dist-server/server/piecemaker/harness/chat-harness.js +157 -0
  721. package/dist-server/server/piecemaker/harness/chat-harness.js.map +1 -0
  722. package/dist-server/server/piecemaker/harness/chat-harness.test.js +120 -0
  723. package/dist-server/server/piecemaker/harness/chat-harness.test.js.map +1 -0
  724. package/dist-server/server/piecemaker/harness/citation-instructions.js +17 -0
  725. package/dist-server/server/piecemaker/harness/citation-instructions.js.map +1 -0
  726. package/dist-server/server/piecemaker/harness/citation-store.js +72 -0
  727. package/dist-server/server/piecemaker/harness/citation-store.js.map +1 -0
  728. package/dist-server/server/piecemaker/harness/citation-turn.js +211 -0
  729. package/dist-server/server/piecemaker/harness/citation-turn.js.map +1 -0
  730. package/dist-server/server/piecemaker/harness/citation-turn.test.js +144 -0
  731. package/dist-server/server/piecemaker/harness/citation-turn.test.js.map +1 -0
  732. package/dist-server/server/piecemaker/harness/citations.routes.js +16 -0
  733. package/dist-server/server/piecemaker/harness/citations.routes.js.map +1 -0
  734. package/dist-server/server/piecemaker/harness/citations.routes.test.js +68 -0
  735. package/dist-server/server/piecemaker/harness/citations.routes.test.js.map +1 -0
  736. package/dist-server/server/piecemaker/harness/decisions.cjs +298 -0
  737. package/dist-server/server/piecemaker/harness/decisions.cjs.map +1 -0
  738. package/dist-server/server/piecemaker/harness/flux-sse.cjs +108 -0
  739. package/dist-server/server/piecemaker/harness/flux-sse.cjs.map +1 -0
  740. package/dist-server/server/piecemaker/harness/harness.test.js +259 -0
  741. package/dist-server/server/piecemaker/harness/harness.test.js.map +1 -0
  742. package/dist-server/server/piecemaker/harness/index.cjs +100 -0
  743. package/dist-server/server/piecemaker/harness/index.cjs.map +1 -0
  744. package/dist-server/server/piecemaker/harness/proxy-harness.test.js +199 -0
  745. package/dist-server/server/piecemaker/harness/proxy-harness.test.js.map +1 -0
  746. package/dist-server/server/piecemaker/harness/source-passages.js +19 -0
  747. package/dist-server/server/piecemaker/harness/source-passages.js.map +1 -0
  748. package/dist-server/server/piecemaker/harness/verification.cjs +152 -0
  749. package/dist-server/server/piecemaker/harness/verification.cjs.map +1 -0
  750. package/dist-server/server/piecemaker/index.js +46 -0
  751. package/dist-server/server/piecemaker/index.js.map +1 -0
  752. package/dist-server/server/piecemaker/library/index.js +66 -0
  753. package/dist-server/server/piecemaker/library/index.js.map +1 -0
  754. package/dist-server/server/piecemaker/library/marketplace.js +204 -0
  755. package/dist-server/server/piecemaker/library/marketplace.js.map +1 -0
  756. package/dist-server/server/piecemaker/library/migrate-cli.js +13 -0
  757. package/dist-server/server/piecemaker/library/migrate-cli.js.map +1 -0
  758. package/dist-server/server/piecemaker/library/migrate.js +53 -0
  759. package/dist-server/server/piecemaker/library/migrate.js.map +1 -0
  760. package/dist-server/server/piecemaker/library/provider-skills.js +40 -0
  761. package/dist-server/server/piecemaker/library/provider-skills.js.map +1 -0
  762. package/dist-server/server/piecemaker/library/provider-skills.test.js +55 -0
  763. package/dist-server/server/piecemaker/library/provider-skills.test.js.map +1 -0
  764. package/dist-server/server/piecemaker/library/routes.js +56 -0
  765. package/dist-server/server/piecemaker/library/routes.js.map +1 -0
  766. package/dist-server/server/piecemaker/library/runtime.js +34 -0
  767. package/dist-server/server/piecemaker/library/runtime.js.map +1 -0
  768. package/dist-server/server/piecemaker/library/store.js +440 -0
  769. package/dist-server/server/piecemaker/library/store.js.map +1 -0
  770. package/dist-server/server/piecemaker/library/store.test.js +265 -0
  771. package/dist-server/server/piecemaker/library/store.test.js.map +1 -0
  772. package/dist-server/server/piecemaker/library/workspace-installation.js +70 -0
  773. package/dist-server/server/piecemaker/library/workspace-installation.js.map +1 -0
  774. package/dist-server/server/piecemaker/originals-cache.cjs +45 -0
  775. package/dist-server/server/piecemaker/originals-cache.cjs.map +1 -0
  776. package/dist-server/server/piecemaker/originals-cache.test.js +68 -0
  777. package/dist-server/server/piecemaker/originals-cache.test.js.map +1 -0
  778. package/dist-server/server/piecemaker/protection/bypass.cjs +66 -0
  779. package/dist-server/server/piecemaker/protection/bypass.cjs.map +1 -0
  780. package/dist-server/server/piecemaker/protection/bypass.test.js +117 -0
  781. package/dist-server/server/piecemaker/protection/bypass.test.js.map +1 -0
  782. package/dist-server/server/piecemaker/protection/routes.cjs +38 -0
  783. package/dist-server/server/piecemaker/protection/routes.cjs.map +1 -0
  784. package/dist-server/server/piecemaker/timesheet/index.js +9 -0
  785. package/dist-server/server/piecemaker/timesheet/index.js.map +1 -0
  786. package/dist-server/server/piecemaker/timesheet/routes.js +42 -0
  787. package/dist-server/server/piecemaker/timesheet/routes.js.map +1 -0
  788. package/dist-server/server/piecemaker/timesheet/service.js +241 -0
  789. package/dist-server/server/piecemaker/timesheet/service.js.map +1 -0
  790. package/dist-server/server/piecemaker/timesheet/service.test.js +124 -0
  791. package/dist-server/server/piecemaker/timesheet/service.test.js.map +1 -0
  792. package/dist-server/server/piecemaker/timesheet/store.js +126 -0
  793. package/dist-server/server/piecemaker/timesheet/store.js.map +1 -0
  794. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/anonymization-state.cjs +147 -0
  795. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/anonymization-state.cjs.map +1 -0
  796. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folder-structure.cjs +285 -0
  797. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folder-structure.cjs.map +1 -0
  798. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folders.cjs +87 -0
  799. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folders.cjs.map +1 -0
  800. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/central-mapping.cjs +0 -0
  801. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/central-mapping.cjs.map +1 -0
  802. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/citation-sources.cjs +526 -0
  803. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/citation-sources.cjs.map +1 -0
  804. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/citations.cjs +304 -0
  805. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/citations.cjs.map +1 -0
  806. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/commits.cjs +1660 -0
  807. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/commits.cjs.map +1 -0
  808. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/institutional-terms.cjs +152 -0
  809. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/institutional-terms.cjs.map +1 -0
  810. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/legifrance-reads.cjs +84 -0
  811. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/legifrance-reads.cjs.map +1 -0
  812. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.cjs +332 -0
  813. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.cjs.map +1 -0
  814. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.test.js +64 -0
  815. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.test.js.map +1 -0
  816. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/protection.cjs +420 -0
  817. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/protection.cjs.map +1 -0
  818. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/session-timing.cjs +91 -0
  819. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/session-timing.cjs.map +1 -0
  820. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/substitution.cjs +304 -0
  821. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/substitution.cjs.map +1 -0
  822. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/verify-citations.cjs +293 -0
  823. package/dist-server/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/verify-citations.cjs.map +1 -0
  824. package/dist-server/server/piecemaker/vendor/websocket-server/case-folder-structure.cjs +5 -0
  825. package/dist-server/server/piecemaker/vendor/websocket-server/case-folder-structure.cjs.map +1 -0
  826. package/dist-server/server/piecemaker/vendor/websocket-server/legal-forms.cjs +91 -0
  827. package/dist-server/server/piecemaker/vendor/websocket-server/legal-forms.cjs.map +1 -0
  828. package/dist-server/server/piecemaker/vendor/websocket-server/legal-forms.test.js +11 -0
  829. package/dist-server/server/piecemaker/vendor/websocket-server/legal-forms.test.js.map +1 -0
  830. package/dist-server/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +955 -0
  831. package/dist-server/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs.map +1 -0
  832. package/dist-server/server/shared/claude-cli-path.js +120 -0
  833. package/dist-server/server/shared/claude-cli-path.js.map +1 -0
  834. package/dist-server/server/shared/frontmatter.js +16 -0
  835. package/dist-server/server/shared/frontmatter.js.map +1 -0
  836. package/dist-server/server/shared/image-attachments.js +344 -0
  837. package/dist-server/server/shared/image-attachments.js.map +1 -0
  838. package/dist-server/server/shared/interfaces.js +2 -0
  839. package/dist-server/server/shared/interfaces.js.map +1 -0
  840. package/dist-server/server/shared/message-unification.js +376 -0
  841. package/dist-server/server/shared/message-unification.js.map +1 -0
  842. package/dist-server/server/shared/tests/application-data-root.test.js +33 -0
  843. package/dist-server/server/shared/tests/application-data-root.test.js.map +1 -0
  844. package/dist-server/server/shared/tests/claude-cli-path.test.js +89 -0
  845. package/dist-server/server/shared/tests/claude-cli-path.test.js.map +1 -0
  846. package/dist-server/server/shared/tests/image-attachments.test.js +262 -0
  847. package/dist-server/server/shared/tests/image-attachments.test.js.map +1 -0
  848. package/dist-server/server/shared/tests/message-unification.test.js +174 -0
  849. package/dist-server/server/shared/tests/message-unification.test.js.map +1 -0
  850. package/dist-server/server/shared/tests/slice-tail-page.test.js +35 -0
  851. package/dist-server/server/shared/tests/slice-tail-page.test.js.map +1 -0
  852. package/dist-server/server/shared/types.js +2 -0
  853. package/dist-server/server/shared/types.js.map +1 -0
  854. package/dist-server/server/shared/utils.js +1010 -0
  855. package/dist-server/server/shared/utils.js.map +1 -0
  856. package/dist-server/shared/networkHosts.js +20 -0
  857. package/dist-server/shared/networkHosts.js.map +1 -0
  858. package/dist-server/shared/product-config.mjs +79 -0
  859. package/dist-server/shared/product-config.mjs.map +1 -0
  860. package/package.json +271 -0
  861. package/product.config.json +17 -0
  862. package/public/api-docs.html +901 -0
  863. package/scripts/fix-node-pty.js +67 -0
  864. package/scripts/piecemaker/cli/install-command.mjs +130 -0
  865. package/scripts/piecemaker/cli/lib/composants.mjs +68 -0
  866. package/scripts/piecemaker/cli/lib/config.mjs +32 -0
  867. package/scripts/piecemaker/cli/lib/exec.mjs +79 -0
  868. package/scripts/piecemaker/cli/lib/node-runtime.mjs +76 -0
  869. package/scripts/piecemaker/cli/lib/ports.mjs +96 -0
  870. package/scripts/piecemaker/cli/lib/pwa.mjs +323 -0
  871. package/scripts/piecemaker/cli/lib/repos.mjs +140 -0
  872. package/scripts/piecemaker/cli/lib/services.mjs +71 -0
  873. package/scripts/piecemaker/cli/lib/ui.mjs +41 -0
  874. package/scripts/piecemaker/cli/piecemaker.mjs +159 -0
  875. package/scripts/piecemaker/cli/piecemaker.ps1 +63 -0
  876. package/scripts/piecemaker/cli/piecemaker.sh +60 -0
  877. package/scripts/piecemaker/generate-i18n-overrides.mjs +219 -0
  878. package/scripts/piecemaker/hooks/proxy-guard.mjs +286 -0
  879. package/scripts/promote-dist-server.mjs +50 -0
  880. package/scripts/release/build-server-bundle.js +178 -0
  881. package/scripts/release/package-piecemaker.sh +73 -0
  882. package/scripts/release/prepare-desktop-app.js +168 -0
  883. package/server/index.ts +410 -0
  884. package/server/load-env.ts +48 -0
  885. package/server/modules/agent/agent.module.ts +52 -0
  886. package/server/modules/agent/agent.routes.ts +1287 -0
  887. package/server/modules/agent/index.ts +2 -0
  888. package/server/modules/agent/tests/agent.routes.test.ts +205 -0
  889. package/server/modules/assets/assets.routes.ts +150 -0
  890. package/server/modules/assets/index.ts +3 -0
  891. package/server/modules/assets/services/image-assets.service.ts +127 -0
  892. package/server/modules/assets/tests/image-assets.service.test.ts +74 -0
  893. package/server/modules/auth/auth.middleware.ts +163 -0
  894. package/server/modules/auth/auth.module.ts +38 -0
  895. package/server/modules/auth/auth.routes.ts +57 -0
  896. package/server/modules/auth/auth.service.ts +155 -0
  897. package/server/modules/auth/index.ts +9 -0
  898. package/server/modules/auth/tests/auth.service.test.ts +95 -0
  899. package/server/modules/browser-use/browser-use-mcp.routes.ts +120 -0
  900. package/server/modules/browser-use/browser-use-mcp.ts +386 -0
  901. package/server/modules/browser-use/browser-use-runtime.ts +10 -0
  902. package/server/modules/browser-use/browser-use.routes.ts +96 -0
  903. package/server/modules/browser-use/browser-use.service.ts +835 -0
  904. package/server/modules/browser-use/index.ts +11 -0
  905. package/server/modules/browser-use/tests/browser-use.service.test.ts +10 -0
  906. package/server/modules/cli/cli.module.ts +110 -0
  907. package/server/modules/cli/cli.service.ts +266 -0
  908. package/server/modules/cli/cli.ts +19 -0
  909. package/server/modules/cli/index.ts +2 -0
  910. package/server/modules/cli/pwa-launcher.ts +131 -0
  911. package/server/modules/cli/sandbox.service.ts +413 -0
  912. package/server/modules/cli/tests/cli-environment-bootstrap.test.ts +186 -0
  913. package/server/modules/cli/tests/cli.service.test.ts +107 -0
  914. package/server/modules/cli/tests/sandbox.service.test.ts +61 -0
  915. package/server/modules/commands/commands.module.ts +22 -0
  916. package/server/modules/commands/commands.routes.ts +605 -0
  917. package/server/modules/commands/index.ts +2 -0
  918. package/server/modules/commands/tests/commands.test.ts +114 -0
  919. package/server/modules/database/connection.ts +144 -0
  920. package/server/modules/database/index.ts +27 -0
  921. package/server/modules/database/init-db.ts +17 -0
  922. package/server/modules/database/migrations.ts +552 -0
  923. package/server/modules/database/repositories/api-keys.ts +119 -0
  924. package/server/modules/database/repositories/app-config.ts +53 -0
  925. package/server/modules/database/repositories/credentials.ts +106 -0
  926. package/server/modules/database/repositories/github-tokens.ts +100 -0
  927. package/server/modules/database/repositories/notification-channel-endpoints.ts +153 -0
  928. package/server/modules/database/repositories/notification-preferences.ts +117 -0
  929. package/server/modules/database/repositories/projects.db.ts +196 -0
  930. package/server/modules/database/repositories/provider-models.ts +168 -0
  931. package/server/modules/database/repositories/push-subscriptions.ts +80 -0
  932. package/server/modules/database/repositories/scan-state.db.ts +42 -0
  933. package/server/modules/database/repositories/scheduled-messages.db.ts +127 -0
  934. package/server/modules/database/repositories/session-drafts.db.ts +171 -0
  935. package/server/modules/database/repositories/sessions.db.ts +714 -0
  936. package/server/modules/database/repositories/user-preferences.db.ts +80 -0
  937. package/server/modules/database/repositories/users.ts +140 -0
  938. package/server/modules/database/repositories/vapid-keys.ts +57 -0
  939. package/server/modules/database/schema.ts +306 -0
  940. package/server/modules/database/tests/projects.db.integration.test.ts +72 -0
  941. package/server/modules/database/tests/provider-models.db.integration.test.ts +125 -0
  942. package/server/modules/database/tests/sessions-provider-mapping.test.ts +109 -0
  943. package/server/modules/database/tests/sessions.db.integration.test.ts +116 -0
  944. package/server/modules/database/tests/user-preferences.db.integration.test.ts +135 -0
  945. package/server/modules/file-tree/file-tree.module.ts +116 -0
  946. package/server/modules/file-tree/file-tree.routes.ts +258 -0
  947. package/server/modules/file-tree/file-tree.service.ts +675 -0
  948. package/server/modules/file-tree/index.ts +2 -0
  949. package/server/modules/file-tree/tests/file-tree.routes.test.ts +157 -0
  950. package/server/modules/file-tree/tests/file-tree.service.test.ts +371 -0
  951. package/server/modules/git/git-branch.service.ts +43 -0
  952. package/server/modules/git/git-parsing.service.ts +66 -0
  953. package/server/modules/git/git.module.ts +22 -0
  954. package/server/modules/git/git.routes.ts +1600 -0
  955. package/server/modules/git/index.ts +2 -0
  956. package/server/modules/git/tests/git-branch.service.test.ts +60 -0
  957. package/server/modules/git/tests/git-init.routes.test.ts +135 -0
  958. package/server/modules/git/tests/git.test.ts +106 -0
  959. package/server/modules/notifications/index.ts +24 -0
  960. package/server/modules/notifications/notifications.routes.ts +127 -0
  961. package/server/modules/notifications/services/desktop-notification-clients.service.ts +124 -0
  962. package/server/modules/notifications/services/notification-orchestrator.service.js +310 -0
  963. package/server/modules/notifications/tests/notification-orchestrator.integration.test.ts +55 -0
  964. package/server/modules/notifications/vapid-keys.service.ts +38 -0
  965. package/server/modules/notifications/websocket/desktop-notifications-websocket.service.ts +109 -0
  966. package/server/modules/plugins/index.ts +9 -0
  967. package/server/modules/plugins/plugin-process.service.ts +217 -0
  968. package/server/modules/plugins/plugin-registry.service.ts +461 -0
  969. package/server/modules/plugins/plugins.module.ts +33 -0
  970. package/server/modules/plugins/plugins.routes.ts +66 -0
  971. package/server/modules/plugins/plugins.service.ts +147 -0
  972. package/server/modules/plugins/tests/plugins.service.test.ts +32 -0
  973. package/server/modules/projects/index.ts +11 -0
  974. package/server/modules/projects/projects.routes.ts +273 -0
  975. package/server/modules/projects/services/project-clone.service.ts +323 -0
  976. package/server/modules/projects/services/project-delete.service.ts +102 -0
  977. package/server/modules/projects/services/project-management.service.ts +144 -0
  978. package/server/modules/projects/services/project-star.service.ts +78 -0
  979. package/server/modules/projects/services/projects-has-taskmaster.service.ts +248 -0
  980. package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +314 -0
  981. package/server/modules/projects/tests/project-clone.service.test.ts +183 -0
  982. package/server/modules/projects/tests/project-management.service.test.ts +117 -0
  983. package/server/modules/projects/tests/project-star.service.test.ts +123 -0
  984. package/server/modules/projects/tests/projects-has-taskmaster.service.test.ts +105 -0
  985. package/server/modules/providers/README.md +380 -0
  986. package/server/modules/providers/index.ts +14 -0
  987. package/server/modules/providers/list/claude/claude-auth.provider.ts +180 -0
  988. package/server/modules/providers/list/claude/claude-fork.provider.ts +57 -0
  989. package/server/modules/providers/list/claude/claude-mcp.provider.ts +135 -0
  990. package/server/modules/providers/list/claude/claude-models.provider.ts +314 -0
  991. package/server/modules/providers/list/claude/claude-runtime.provider.js +1217 -0
  992. package/server/modules/providers/list/claude/claude-session-synchronizer.provider.ts +203 -0
  993. package/server/modules/providers/list/claude/claude-sessions.provider.ts +1108 -0
  994. package/server/modules/providers/list/claude/claude-skills.provider.ts +265 -0
  995. package/server/modules/providers/list/claude/claude.provider.ts +33 -0
  996. package/server/modules/providers/list/codex/codex-app-server.client.ts +243 -0
  997. package/server/modules/providers/list/codex/codex-auth.provider.ts +100 -0
  998. package/server/modules/providers/list/codex/codex-fork.provider.ts +40 -0
  999. package/server/modules/providers/list/codex/codex-mcp.provider.ts +135 -0
  1000. package/server/modules/providers/list/codex/codex-models.provider.ts +123 -0
  1001. package/server/modules/providers/list/codex/codex-runtime.provider.js +572 -0
  1002. package/server/modules/providers/list/codex/codex-session-synchronizer.provider.ts +212 -0
  1003. package/server/modules/providers/list/codex/codex-sessions.provider.ts +2267 -0
  1004. package/server/modules/providers/list/codex/codex-skills.provider.ts +73 -0
  1005. package/server/modules/providers/list/codex/codex.provider.ts +33 -0
  1006. package/server/modules/providers/list/cursor/cursor-auth.provider.ts +143 -0
  1007. package/server/modules/providers/list/cursor/cursor-mcp.provider.ts +108 -0
  1008. package/server/modules/providers/list/cursor/cursor-models.provider.ts +119 -0
  1009. package/server/modules/providers/list/cursor/cursor-runtime.provider.js +387 -0
  1010. package/server/modules/providers/list/cursor/cursor-session-synchronizer.provider.ts +158 -0
  1011. package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +654 -0
  1012. package/server/modules/providers/list/cursor/cursor-skills.provider.ts +39 -0
  1013. package/server/modules/providers/list/cursor/cursor.provider.ts +30 -0
  1014. package/server/modules/providers/list/mistral/mistral-auth.provider.ts +181 -0
  1015. package/server/modules/providers/list/mistral/mistral-mcp.provider.ts +20 -0
  1016. package/server/modules/providers/list/mistral/mistral-models.provider.ts +76 -0
  1017. package/server/modules/providers/list/mistral/mistral-runtime.provider.ts +417 -0
  1018. package/server/modules/providers/list/mistral/mistral-session-synchronizer.provider.ts +15 -0
  1019. package/server/modules/providers/list/mistral/mistral-sessions.provider.ts +210 -0
  1020. package/server/modules/providers/list/mistral/mistral-skills.provider.ts +20 -0
  1021. package/server/modules/providers/list/mistral/mistral.provider.ts +35 -0
  1022. package/server/modules/providers/list/opencode/opencode-auth.provider.ts +110 -0
  1023. package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +228 -0
  1024. package/server/modules/providers/list/opencode/opencode-models.provider.ts +304 -0
  1025. package/server/modules/providers/list/opencode/opencode-runtime.provider.js +434 -0
  1026. package/server/modules/providers/list/opencode/opencode-runtime.provider.test.js +261 -0
  1027. package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +179 -0
  1028. package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +500 -0
  1029. package/server/modules/providers/list/opencode/opencode-skills.provider.ts +78 -0
  1030. package/server/modules/providers/list/opencode/opencode.provider.ts +30 -0
  1031. package/server/modules/providers/provider.registry.ts +38 -0
  1032. package/server/modules/providers/provider.routes.ts +909 -0
  1033. package/server/modules/providers/services/mcp.service.ts +109 -0
  1034. package/server/modules/providers/services/provider-auth.service.ts +26 -0
  1035. package/server/modules/providers/services/provider-capabilities.service.ts +133 -0
  1036. package/server/modules/providers/services/provider-models.service.ts +401 -0
  1037. package/server/modules/providers/services/provider-runtime.service.ts +108 -0
  1038. package/server/modules/providers/services/provider-token-usage.service.ts +484 -0
  1039. package/server/modules/providers/services/session-conversations-search.service.ts +1321 -0
  1040. package/server/modules/providers/services/session-history-cache.service.ts +139 -0
  1041. package/server/modules/providers/services/session-synchronizer.service.ts +162 -0
  1042. package/server/modules/providers/services/sessions-watcher.service.ts +266 -0
  1043. package/server/modules/providers/services/sessions.service.ts +663 -0
  1044. package/server/modules/providers/services/skills.service.ts +39 -0
  1045. package/server/modules/providers/shared/base/abstract.provider.ts +32 -0
  1046. package/server/modules/providers/shared/mcp/mcp.provider.ts +151 -0
  1047. package/server/modules/providers/shared/skills/skills.provider.ts +287 -0
  1048. package/server/modules/providers/tests/claude-auth.test.ts +208 -0
  1049. package/server/modules/providers/tests/claude-sessions.test.ts +573 -0
  1050. package/server/modules/providers/tests/claude-subagent-echo.test.ts +25 -0
  1051. package/server/modules/providers/tests/claude-token-budget.test.ts +104 -0
  1052. package/server/modules/providers/tests/codex-message-editing.test.ts +419 -0
  1053. package/server/modules/providers/tests/codex-session-fork.test.ts +59 -0
  1054. package/server/modules/providers/tests/codex-sessions.test.ts +553 -0
  1055. package/server/modules/providers/tests/mcp.test.ts +349 -0
  1056. package/server/modules/providers/tests/opencode-models.test.ts +154 -0
  1057. package/server/modules/providers/tests/opencode-sessions.test.ts +522 -0
  1058. package/server/modules/providers/tests/provider-attachment-history.test.ts +247 -0
  1059. package/server/modules/providers/tests/provider-models.service.test.ts +353 -0
  1060. package/server/modules/providers/tests/provider-runtime.service.test.ts +138 -0
  1061. package/server/modules/providers/tests/provider-token-usage.service.test.ts +373 -0
  1062. package/server/modules/providers/tests/provider.routes.test.ts +244 -0
  1063. package/server/modules/providers/tests/session-fork.test.ts +173 -0
  1064. package/server/modules/providers/tests/session-history-cache.service.test.ts +143 -0
  1065. package/server/modules/providers/tests/session-orphan-prune.test.ts +107 -0
  1066. package/server/modules/providers/tests/session-synchronizer-coalescing.test.ts +136 -0
  1067. package/server/modules/providers/tests/sessions-details.test.ts +73 -0
  1068. package/server/modules/providers/tests/sessions.service.test.ts +193 -0
  1069. package/server/modules/providers/tests/skills.test.ts +692 -0
  1070. package/server/modules/scheduled-messages/index.ts +8 -0
  1071. package/server/modules/scheduled-messages/scheduled-messages.routes.ts +68 -0
  1072. package/server/modules/scheduled-messages/services/scheduled-message-dispatcher.service.ts +203 -0
  1073. package/server/modules/scheduled-messages/services/scheduled-messages.service.ts +121 -0
  1074. package/server/modules/scheduled-messages/tests/scheduled-messages.test.ts +310 -0
  1075. package/server/modules/settings/index.ts +2 -0
  1076. package/server/modules/settings/settings.module.ts +50 -0
  1077. package/server/modules/settings/settings.routes.ts +51 -0
  1078. package/server/modules/settings/settings.service.ts +186 -0
  1079. package/server/modules/settings/tests/settings.service.test.ts +54 -0
  1080. package/server/modules/system/index.ts +2 -0
  1081. package/server/modules/system/system.module.ts +62 -0
  1082. package/server/modules/system/system.routes.ts +21 -0
  1083. package/server/modules/system/system.service.ts +76 -0
  1084. package/server/modules/system/tests/system.service.test.ts +118 -0
  1085. package/server/modules/taskmaster/index.ts +2 -0
  1086. package/server/modules/taskmaster/taskmaster.module.ts +24 -0
  1087. package/server/modules/taskmaster/taskmaster.routes.ts +1472 -0
  1088. package/server/modules/taskmaster/taskmaster.service.ts +132 -0
  1089. package/server/modules/taskmaster/tests/taskmaster.routes.test.ts +201 -0
  1090. package/server/modules/taskmaster/tests/taskmaster.service.test.ts +97 -0
  1091. package/server/modules/user/index.ts +2 -0
  1092. package/server/modules/user/tests/user.service.test.ts +151 -0
  1093. package/server/modules/user/user.module.ts +67 -0
  1094. package/server/modules/user/user.routes.ts +94 -0
  1095. package/server/modules/user/user.service.ts +190 -0
  1096. package/server/modules/voice/index.ts +2 -0
  1097. package/server/modules/voice/tests/voice.service.test.ts +99 -0
  1098. package/server/modules/voice/voice.module.ts +47 -0
  1099. package/server/modules/voice/voice.routes.ts +113 -0
  1100. package/server/modules/voice/voice.service.ts +192 -0
  1101. package/server/modules/websocket/README.md +273 -0
  1102. package/server/modules/websocket/index.ts +11 -0
  1103. package/server/modules/websocket/services/chat-run-registry.service.ts +310 -0
  1104. package/server/modules/websocket/services/chat-session-writer.service.ts +175 -0
  1105. package/server/modules/websocket/services/chat-websocket.service.ts +654 -0
  1106. package/server/modules/websocket/services/plugin-websocket-proxy.service.ts +65 -0
  1107. package/server/modules/websocket/services/session-upsert-broadcast.service.ts +108 -0
  1108. package/server/modules/websocket/services/shell-websocket.service.ts +628 -0
  1109. package/server/modules/websocket/services/websocket-auth.service.ts +59 -0
  1110. package/server/modules/websocket/services/websocket-server.service.ts +126 -0
  1111. package/server/modules/websocket/services/websocket-state.service.ts +16 -0
  1112. package/server/modules/websocket/services/websocket-writer.service.ts +38 -0
  1113. package/server/modules/websocket/tests/chat-attachment-filter.test.ts +59 -0
  1114. package/server/modules/websocket/tests/chat-edit-send.test.ts +309 -0
  1115. package/server/modules/websocket/tests/chat-run-registry.test.ts +313 -0
  1116. package/server/modules/websocket/tests/session-upsert-broadcast.test.ts +138 -0
  1117. package/server/modules/websocket/tests/shell-websocket.service.test.ts +227 -0
  1118. package/server/modules/websocket/tests/websocket-heartbeat.service.test.ts +78 -0
  1119. package/server/modules/worktrees/index.ts +2 -0
  1120. package/server/modules/worktrees/services/worktree-create-and-open.service.ts +53 -0
  1121. package/server/modules/worktrees/services/worktree-create.service.ts +104 -0
  1122. package/server/modules/worktrees/services/worktree-git.service.ts +207 -0
  1123. package/server/modules/worktrees/services/worktree-list.service.ts +143 -0
  1124. package/server/modules/worktrees/services/worktree-merge.service.ts +157 -0
  1125. package/server/modules/worktrees/services/worktree-open.service.ts +85 -0
  1126. package/server/modules/worktrees/services/worktree-remove.service.ts +88 -0
  1127. package/server/modules/worktrees/tests/worktree-create-and-open.service.test.ts +68 -0
  1128. package/server/modules/worktrees/tests/worktree-create.service.test.ts +142 -0
  1129. package/server/modules/worktrees/tests/worktree-git.service.test.ts +84 -0
  1130. package/server/modules/worktrees/tests/worktree-list.service.test.ts +45 -0
  1131. package/server/modules/worktrees/tests/worktree-merge.service.test.ts +213 -0
  1132. package/server/modules/worktrees/tests/worktree-open.service.test.ts +122 -0
  1133. package/server/modules/worktrees/tests/worktree-remove.service.test.ts +227 -0
  1134. package/server/modules/worktrees/tests/worktrees.routes.test.ts +199 -0
  1135. package/server/modules/worktrees/worktrees.module.ts +113 -0
  1136. package/server/modules/worktrees/worktrees.routes.ts +116 -0
  1137. package/server/piecemaker/activation/claude-mcp.cjs +115 -0
  1138. package/server/piecemaker/activation/claude-plugins.cjs +65 -0
  1139. package/server/piecemaker/activation/codex-mcp.cjs +102 -0
  1140. package/server/piecemaker/activation/errors.cjs +15 -0
  1141. package/server/piecemaker/activation/index.cjs +5 -0
  1142. package/server/piecemaker/activation/library.cjs +284 -0
  1143. package/server/piecemaker/activation/library.cjs.bak +223 -0
  1144. package/server/piecemaker/activation/library.test.js +365 -0
  1145. package/server/piecemaker/activation/markdown.cjs +108 -0
  1146. package/server/piecemaker/activation/markdown.cjs.bak +78 -0
  1147. package/server/piecemaker/activation/paths.cjs +104 -0
  1148. package/server/piecemaker/activation/paths.test.js +158 -0
  1149. package/server/piecemaker/activation/routes.cjs +101 -0
  1150. package/server/piecemaker/activation/routes.test.js +344 -0
  1151. package/server/piecemaker/activation/snapshot.cjs +30 -0
  1152. package/server/piecemaker/anonymizer/anonymizer.test.js +320 -0
  1153. package/server/piecemaker/anonymizer/client-config.cjs +228 -0
  1154. package/server/piecemaker/anonymizer/codex-http.test.js +20 -0
  1155. package/server/piecemaker/anonymizer/dictionary.cjs +174 -0
  1156. package/server/piecemaker/anonymizer/lifecycle.test.ts +37 -0
  1157. package/server/piecemaker/anonymizer/lifecycle.ts +22 -0
  1158. package/server/piecemaker/anonymizer/providers.cjs +241 -0
  1159. package/server/piecemaker/anonymizer/proxy.cjs +365 -0
  1160. package/server/piecemaker/anonymizer/rewrite.cjs +251 -0
  1161. package/server/piecemaker/anonymizer/routes.cjs +43 -0
  1162. package/server/piecemaker/anonymizer/service.cjs +218 -0
  1163. package/server/piecemaker/harness/chat-harness.test.ts +131 -0
  1164. package/server/piecemaker/harness/chat-harness.ts +151 -0
  1165. package/server/piecemaker/harness/citation-instructions.ts +18 -0
  1166. package/server/piecemaker/harness/citation-store.ts +80 -0
  1167. package/server/piecemaker/harness/citation-turn.test.ts +155 -0
  1168. package/server/piecemaker/harness/citation-turn.ts +197 -0
  1169. package/server/piecemaker/harness/citations.routes.test.ts +68 -0
  1170. package/server/piecemaker/harness/citations.routes.ts +18 -0
  1171. package/server/piecemaker/harness/decisions.cjs +302 -0
  1172. package/server/piecemaker/harness/flux-sse.cjs +111 -0
  1173. package/server/piecemaker/harness/harness.test.js +296 -0
  1174. package/server/piecemaker/harness/index.cjs +103 -0
  1175. package/server/piecemaker/harness/proxy-harness.test.js +226 -0
  1176. package/server/piecemaker/harness/source-passages.ts +21 -0
  1177. package/server/piecemaker/harness/verification.cjs +159 -0
  1178. package/server/piecemaker/index.ts +59 -0
  1179. package/server/piecemaker/library/index.ts +54 -0
  1180. package/server/piecemaker/library/marketplace.ts +152 -0
  1181. package/server/piecemaker/library/migrate-cli.ts +11 -0
  1182. package/server/piecemaker/library/migrate.ts +49 -0
  1183. package/server/piecemaker/library/policy.cjs +9 -0
  1184. package/server/piecemaker/library/provider-skills.test.ts +61 -0
  1185. package/server/piecemaker/library/provider-skills.ts +48 -0
  1186. package/server/piecemaker/library/routes.ts +38 -0
  1187. package/server/piecemaker/library/runtime.ts +39 -0
  1188. package/server/piecemaker/library/store.test.ts +280 -0
  1189. package/server/piecemaker/library/store.ts +429 -0
  1190. package/server/piecemaker/library/workspace-installation.ts +61 -0
  1191. package/server/piecemaker/originals-cache.cjs +54 -0
  1192. package/server/piecemaker/originals-cache.test.js +77 -0
  1193. package/server/piecemaker/protection/bypass.cjs +73 -0
  1194. package/server/piecemaker/protection/bypass.test.js +140 -0
  1195. package/server/piecemaker/protection/routes.cjs +39 -0
  1196. package/server/piecemaker/router.cjs +109 -0
  1197. package/server/piecemaker/timesheet/index.ts +9 -0
  1198. package/server/piecemaker/timesheet/routes.ts +48 -0
  1199. package/server/piecemaker/timesheet/service.test.ts +142 -0
  1200. package/server/piecemaker/timesheet/service.ts +298 -0
  1201. package/server/piecemaker/timesheet/store.ts +167 -0
  1202. package/server/piecemaker/vendor/.env +2 -0
  1203. package/server/piecemaker/vendor/installer/assets/PieceMakerApp.swift +189 -0
  1204. package/server/piecemaker/vendor/installer/assets/claude-hooks/piecemaker-guard-secrets.mjs +230 -0
  1205. package/server/piecemaker/vendor/installer/assets/claude-hooks/piecemaker-secret-paths.default.json +1 -0
  1206. package/server/piecemaker/vendor/installer/assets/piecemaker.icns +0 -0
  1207. package/server/piecemaker/vendor/installer/assets/piecemaker.ico +0 -0
  1208. package/server/piecemaker/vendor/installer/bin/piecemaker.mjs +1018 -0
  1209. package/server/piecemaker/vendor/installer/lib/banner.mjs +35 -0
  1210. package/server/piecemaker/vendor/installer/lib/codex-skills.mjs +343 -0
  1211. package/server/piecemaker/vendor/installer/lib/commandes.mjs +13 -0
  1212. package/server/piecemaker/vendor/installer/lib/desktop-launcher.mjs +305 -0
  1213. package/server/piecemaker/vendor/installer/lib/legacy-legifrance.mjs +72 -0
  1214. package/server/piecemaker/vendor/installer/lib/platform.mjs +163 -0
  1215. package/server/piecemaker/vendor/installer/lib/prompt.mjs +138 -0
  1216. package/server/piecemaker/vendor/installer/lib/resume-steps.mjs +174 -0
  1217. package/server/piecemaker/vendor/installer/lib/secrets-guard.mjs +193 -0
  1218. package/server/piecemaker/vendor/installer/lib/service.mjs +467 -0
  1219. package/server/piecemaker/vendor/installer/lib/state.mjs +114 -0
  1220. package/server/piecemaker/vendor/installer/lib/ui.mjs +159 -0
  1221. package/server/piecemaker/vendor/installer/steps/00-identite.mjs +71 -0
  1222. package/server/piecemaker/vendor/installer/steps/01-prerequis.mjs +119 -0
  1223. package/server/piecemaker/vendor/installer/steps/02-dependances-node.mjs +127 -0
  1224. package/server/piecemaker/vendor/installer/steps/03-python-gliner.mjs +249 -0
  1225. package/server/piecemaker/vendor/installer/steps/03b-python-graphify.mjs +161 -0
  1226. package/server/piecemaker/vendor/installer/steps/04-conversion-md.mjs +147 -0
  1227. package/server/piecemaker/vendor/installer/steps/05-certificats.mjs +171 -0
  1228. package/server/piecemaker/vendor/installer/steps/06-hooks.mjs +266 -0
  1229. package/server/piecemaker/vendor/installer/steps/07-legifrance.mjs +279 -0
  1230. package/server/piecemaker/vendor/installer/steps/08-telegram.mjs +482 -0
  1231. package/server/piecemaker/vendor/installer/steps/09-claude-assets.mjs +151 -0
  1232. package/server/piecemaker/vendor/installer/steps/09-codex-plugin.mjs +142 -0
  1233. package/server/piecemaker/vendor/installer/steps/10-libreoffice.mjs +130 -0
  1234. package/server/piecemaker/vendor/installer/steps/10-pandoc.mjs +212 -0
  1235. package/server/piecemaker/vendor/installer/steps/11-docx-cli.mjs +144 -0
  1236. package/server/piecemaker/vendor/installer/steps/12-mcp-piecemaker.mjs +124 -0
  1237. package/server/piecemaker/vendor/installer/steps/13-garde-secrets.mjs +136 -0
  1238. package/server/piecemaker/vendor/installer/steps/14-mxc-sandbox.mjs +271 -0
  1239. package/server/piecemaker/vendor/installer/steps/15-pwa-desktop.mjs +64 -0
  1240. package/server/piecemaker/vendor/installer/templates/root-CLAUDE.md +79 -0
  1241. package/server/piecemaker/vendor/installer/templates/workspace-CLAUDE.md +111 -0
  1242. package/server/piecemaker/vendor/mcp/README.md +13 -0
  1243. package/server/piecemaker/vendor/mcp/piecemaker/server.mjs +222 -0
  1244. package/server/piecemaker/vendor/mike-defaults-fr/PROVENANCE.md +10 -0
  1245. package/server/piecemaker/vendor/mike-defaults-fr/assistant-workflows/compare-documents/SKILL.md +51 -0
  1246. package/server/piecemaker/vendor/mike-defaults-fr/assistant-workflows/draft-from-template/SKILL.md +27 -0
  1247. package/server/piecemaker/vendor/mike-defaults-fr/assistant-workflows/extract-key-terms/SKILL.md +43 -0
  1248. package/server/piecemaker/vendor/mike-defaults-fr/assistant-workflows/proofread/SKILL.md +98 -0
  1249. package/server/piecemaker/vendor/mike-defaults-fr/catalog.json +22 -0
  1250. package/server/piecemaker/vendor/mike-defaults-fr/tabular-review-workflows/commercial-agreement-tabular-review/SKILL.md +31 -0
  1251. package/server/piecemaker/vendor/mike-defaults-fr/tabular-review-workflows/commercial-agreement-tabular-review/table-columns.yaml +92 -0
  1252. package/server/piecemaker/vendor/package.json +7 -0
  1253. package/server/piecemaker/vendor/piecemaker-plugin/README.md +115 -0
  1254. package/server/piecemaker/vendor/piecemaker-plugin/agents/analyste-piece.md +38 -0
  1255. package/server/piecemaker/vendor/piecemaker-plugin/agents/jurisprudence-scanner.md +50 -0
  1256. package/server/piecemaker/vendor/piecemaker-plugin/hooks/hooks.json +84 -0
  1257. package/server/piecemaker/vendor/piecemaker-plugin/scripts/billing-track.mjs +194 -0
  1258. package/server/piecemaker/vendor/piecemaker-plugin/scripts/build-recherche-pdf.mjs +91 -0
  1259. package/server/piecemaker/vendor/piecemaker-plugin/scripts/classify-ai-documents.mjs +123 -0
  1260. package/server/piecemaker/vendor/piecemaker-plugin/scripts/commit-track.mjs +71 -0
  1261. package/server/piecemaker/vendor/piecemaker-plugin/scripts/compile-recherche.mjs +107 -0
  1262. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/anonymization-state.cjs +146 -0
  1263. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folder-structure.cjs +303 -0
  1264. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folders.cjs +86 -0
  1265. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/central-mapping.cjs +0 -0
  1266. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/citation-sources.cjs +519 -0
  1267. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/citations.cjs +292 -0
  1268. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/commits.cjs +1683 -0
  1269. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/docx-text-worker.cjs +43 -0
  1270. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/hook-io.mjs +249 -0
  1271. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/institutional-terms.cjs +160 -0
  1272. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/legifrance-reads.cjs +85 -0
  1273. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.cjs +346 -0
  1274. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.test.js +68 -0
  1275. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/protection.cjs +419 -0
  1276. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/recherche-report.cjs +177 -0
  1277. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/session-timing.cjs +80 -0
  1278. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/substitution.cjs +318 -0
  1279. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/verify-citations.cjs +318 -0
  1280. package/server/piecemaker/vendor/piecemaker-plugin/scripts/protect-originals.mjs +256 -0
  1281. package/server/piecemaker/vendor/piecemaker-plugin/scripts/session-commit-worker.mjs +260 -0
  1282. package/server/piecemaker/vendor/piecemaker-plugin/scripts/session-commit.mjs +83 -0
  1283. package/server/piecemaker/vendor/piecemaker-plugin/scripts/statusline.mjs +179 -0
  1284. package/server/piecemaker/vendor/piecemaker-plugin/scripts/track-legifrance-reads.mjs +46 -0
  1285. package/server/piecemaker/vendor/piecemaker-plugin/skills/ajout-de-fonctionnalites/SKILL.md +66 -0
  1286. package/server/piecemaker/vendor/piecemaker-plugin/skills/conversion-md/SKILL.md +60 -0
  1287. package/server/piecemaker/vendor/piecemaker-plugin/skills/graphe-juridique/SKILL.md +105 -0
  1288. package/server/piecemaker/vendor/piecemaker-plugin/skills/recherche-juridique/SKILL.md +234 -0
  1289. package/server/piecemaker/vendor/piecemaker-plugin/skills/redaction-juridique/SKILL.md +96 -0
  1290. package/server/piecemaker/vendor/piecemaker-plugin/skills/tamponnage/SKILL.md +148 -0
  1291. package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +3195 -0
  1292. package/server/piecemaker/vendor/websocket-server/case-folder-structure.cjs +3 -0
  1293. package/server/piecemaker/vendor/websocket-server/case-instructions.cjs +114 -0
  1294. package/server/piecemaker/vendor/websocket-server/case-registry.cjs +93 -0
  1295. package/server/piecemaker/vendor/websocket-server/claude-assets.cjs +338 -0
  1296. package/server/piecemaker/vendor/websocket-server/claude-hooks.cjs +380 -0
  1297. package/server/piecemaker/vendor/websocket-server/document-index.cjs +682 -0
  1298. package/server/piecemaker/vendor/websocket-server/graphify-document-graph.cjs +456 -0
  1299. package/server/piecemaker/vendor/websocket-server/legal-chronology.cjs +502 -0
  1300. package/server/piecemaker/vendor/websocket-server/legal-forms.cjs +89 -0
  1301. package/server/piecemaker/vendor/websocket-server/legal-forms.test.js +10 -0
  1302. package/server/piecemaker/vendor/websocket-server/legal-graph-materializer.cjs +234 -0
  1303. package/server/piecemaker/vendor/websocket-server/legal-graph-prompt.txt +155 -0
  1304. package/server/piecemaker/vendor/websocket-server/legal-graph.cjs +2021 -0
  1305. package/server/piecemaker/vendor/websocket-server/legal-identity-boundary.cjs +247 -0
  1306. package/server/piecemaker/vendor/websocket-server/legal-party-registry.cjs +261 -0
  1307. package/server/piecemaker/vendor/websocket-server/lib/doc-generate.cjs +229 -0
  1308. package/server/piecemaker/vendor/websocket-server/lib/export-render.cjs +442 -0
  1309. package/server/piecemaker/vendor/websocket-server/lib/office-to-pdf.cjs +306 -0
  1310. package/server/piecemaker/vendor/websocket-server/lib/stamping.cjs +39 -0
  1311. package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +965 -0
  1312. package/server/piecemaker/vendor/websocket-server/scripts/ADDRESS_ANONYMIZATION.md +216 -0
  1313. package/server/piecemaker/vendor/websocket-server/scripts/DEDUPLICATION_CHANGES.md +134 -0
  1314. package/server/piecemaker/vendor/websocket-server/scripts/GLINER2_README.md +138 -0
  1315. package/server/piecemaker/vendor/websocket-server/scripts/__pycache__/scan_utils.cpython-312.pyc +0 -0
  1316. package/server/piecemaker/vendor/websocket-server/scripts/convert_and_scan_pipeline.py +1984 -0
  1317. package/server/piecemaker/vendor/websocket-server/scripts/graphify-legal-sitecustomize.py +50 -0
  1318. package/server/piecemaker/vendor/websocket-server/scripts/mineru_improved_1.py +208 -0
  1319. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/AUDIT_PERF_QUALITE.md +246 -0
  1320. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/MODELE_COREML.md +62 -0
  1321. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/coreml_runtime.cpython-312.pyc +0 -0
  1322. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/model_config.cpython-312.pyc +0 -0
  1323. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/build_coreml.py +118 -0
  1324. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/coreml_runtime.py +164 -0
  1325. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/BACKENDS_MESURES.md +384 -0
  1326. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/CRITERES_QUALITE.md +81 -0
  1327. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/__pycache__/coreml_encoder.cpython-312.pyc +0 -0
  1328. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/bench_backend.py +151 -0
  1329. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/bench_batchsize.py +47 -0
  1330. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/bench_coreml_pipeline.py +138 -0
  1331. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/bench_gensight.py +124 -0
  1332. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/check_gold.py +66 -0
  1333. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/coreml_encoder.py +182 -0
  1334. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/encoder_backends.py +179 -0
  1335. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/evaluate.py +130 -0
  1336. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/gold.py +59 -0
  1337. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/profile_split.py +65 -0
  1338. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/slice_A.md +67 -0
  1339. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/slice_B.md +57 -0
  1340. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/slice_C.md +907 -0
  1341. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/sweep.py +115 -0
  1342. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/verify_substitution.cjs +116 -0
  1343. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/verify_whitespace.py +67 -0
  1344. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/eval/verify_worker.py +106 -0
  1345. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/model_config.py +28 -0
  1346. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/presidio-gliner.py +471 -0
  1347. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/scanner_worker.py +668 -0
  1348. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__init__.py +10 -0
  1349. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/__init__.cpython-312.pyc +0 -0
  1350. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/analysis_explanation.cpython-312.pyc +0 -0
  1351. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/entity_recognizer.cpython-312.pyc +0 -0
  1352. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/local_recognizer.cpython-312.pyc +0 -0
  1353. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/pattern.cpython-312.pyc +0 -0
  1354. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/pattern_recognizer.cpython-312.pyc +0 -0
  1355. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/__pycache__/recognizer_result.cpython-312.pyc +0 -0
  1356. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/analysis_explanation.py +65 -0
  1357. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/entity_recognizer.py +213 -0
  1358. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/input_validation/__init__.py +21 -0
  1359. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/input_validation/language_validation.py +18 -0
  1360. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/input_validation/schemas.py +132 -0
  1361. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/input_validation/yaml_recognizer_models.py +422 -0
  1362. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/local_recognizer.py +7 -0
  1363. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__init__.py +15 -0
  1364. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__pycache__/__init__.cpython-312.pyc +0 -0
  1365. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__pycache__/device_detector.cpython-312.pyc +0 -0
  1366. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__pycache__/ner_model_configuration.cpython-312.pyc +0 -0
  1367. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__pycache__/nlp_artifacts.cpython-312.pyc +0 -0
  1368. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__pycache__/nlp_engine.cpython-312.pyc +0 -0
  1369. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/__pycache__/spacy_nlp_engine.cpython-312.pyc +0 -0
  1370. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/device_detector.py +65 -0
  1371. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/ner_model_configuration.py +128 -0
  1372. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/nlp_artifacts.py +88 -0
  1373. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/nlp_engine.py +65 -0
  1374. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/nlp_engine_provider.py +114 -0
  1375. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/nlp_engine/spacy_nlp_engine.py +290 -0
  1376. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/pattern.py +66 -0
  1377. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/pattern_recognizer.py +297 -0
  1378. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/__init__.py +4 -0
  1379. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/__pycache__/__init__.cpython-312.pyc +0 -0
  1380. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/__pycache__/gliner_recognizer.cpython-312.pyc +0 -0
  1381. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__init__.py +0 -0
  1382. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/__init__.cpython-312.pyc +0 -0
  1383. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/credit_card_recognizer.cpython-312.pyc +0 -0
  1384. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/crypto_recognizer.cpython-312.pyc +0 -0
  1385. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/email_recognizer.cpython-312.pyc +0 -0
  1386. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/iban_patterns.cpython-312.pyc +0 -0
  1387. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/iban_recognizer.cpython-312.pyc +0 -0
  1388. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/ip_recognizer.cpython-312.pyc +0 -0
  1389. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/mac_recognizer.cpython-312.pyc +0 -0
  1390. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/__pycache__/url_recognizer.cpython-312.pyc +0 -0
  1391. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/credit_card_recognizer.py +82 -0
  1392. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/crypto_recognizer.py +141 -0
  1393. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/date_recognizer.py +102 -0
  1394. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/email_recognizer.py +48 -0
  1395. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/iban_patterns.py +173 -0
  1396. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/iban_recognizer.py +221 -0
  1397. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/ip_recognizer.py +65 -0
  1398. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/mac_recognizer.py +73 -0
  1399. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/generic/url_recognizer.py +50 -0
  1400. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/gliner_recognizer.py +218 -0
  1401. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/predefined_recognizers/spacy_recognizer.py +139 -0
  1402. package/server/piecemaker/vendor/websocket-server/scripts/presidio_analyzer/recognizer_result.py +188 -0
  1403. package/server/piecemaker/vendor/websocket-server/scripts/requirements.txt +29 -0
  1404. package/server/piecemaker/vendor/websocket-server/scripts/scan_utils.py +469 -0
  1405. package/server/piecemaker/vendor/websocket-server/scripts/smart_converter.py +356 -0
  1406. package/server/piecemaker/vendor/websocket-server/scripts/warmup.py +454 -0
  1407. package/server/piecemaker/vendor/websocket-server/stamping-routes.cjs +334 -0
  1408. package/server/piecemaker/vendor/websocket-server/telegram-admin.cjs +602 -0
  1409. package/server/piecemaker/vendor/websocket-server/workspace-paths.cjs +22 -0
  1410. package/server/shared/claude-cli-path.ts +157 -0
  1411. package/server/shared/frontmatter.ts +18 -0
  1412. package/server/shared/image-attachments.ts +437 -0
  1413. package/server/shared/interfaces.ts +241 -0
  1414. package/server/shared/message-unification.ts +449 -0
  1415. package/server/shared/tests/application-data-root.test.ts +29 -0
  1416. package/server/shared/tests/claude-cli-path.test.ts +118 -0
  1417. package/server/shared/tests/image-attachments.test.ts +353 -0
  1418. package/server/shared/tests/message-unification.test.ts +218 -0
  1419. package/server/shared/tests/slice-tail-page.test.ts +42 -0
  1420. package/server/shared/types.ts +1354 -0
  1421. package/server/shared/utils.ts +1212 -0
  1422. package/server/tsconfig.json +40 -0
  1423. package/shared/networkHosts.js +22 -0
  1424. package/shared/product-config.mjs +86 -0
@@ -0,0 +1,1660 @@
1
+ "use strict";
2
+ /** Git commit history for independent PieceMaker legal matters. */
3
+ const crypto = require('node:crypto');
4
+ const fs = require('node:fs');
5
+ const os = require('node:os');
6
+ const path = require('node:path');
7
+ const zlib = require('node:zlib');
8
+ const { spawn } = require('node:child_process');
9
+ const { performance } = require('node:perf_hooks');
10
+ const { promisify } = require('node:util');
11
+ const { Worker } = require('node:worker_threads');
12
+ const { documentKey, isProtectedFile, isResourceFile, readProtection, WORKSPACE_SUBDIR, } = require('./protection.cjs');
13
+ const { isAnonymizedEntry, isConvertedEntry, readAnonymizationState, stateKey, } = require('./anonymization-state.cjs');
14
+ const { formatDurationFr } = require('./session-timing.cjs');
15
+ const fsp = fs.promises;
16
+ // Root commits (first commit of a case, diffed against the empty tree) can
17
+ // produce patches well into the tens of MB even though only MAX_PATCH_BYTES
18
+ // of it is ever kept (see revisionDetails/worktreeDetails). This ceiling only
19
+ // exists to bound memory on a runaway/corrupt diff, so it must stay well
20
+ // above realistic patch sizes — a 16MB cap was killing legitimate large
21
+ // root-commit diffs (e.g. ~33MB) and turning them into a 400 error.
22
+ const MAX_GIT_BUFFER = 128 * 1024 * 1024;
23
+ const MAX_PATCH_BYTES = 768 * 1024;
24
+ const MAX_SAFE_FILES = 10_000;
25
+ const MAX_SAFE_BYTES = 250 * 1024 * 1024;
26
+ const HISTORY_REF = 'refs/heads/main';
27
+ const LEGACY_HISTORY_REF = 'refs/heads/checkpoints';
28
+ // Le hook PostToolUse commite à chaque Write/Edit : un mois d'activité peut
29
+ // donc contenir des milliers de commits. `listHistory` plafonne à 250 pour un
30
+ // affichage récent ; l'export mensuel a besoin de tout, mais reste borné pour
31
+ // ne jamais renvoyer un volume qui exploserait MAX_GIT_BUFFER.
32
+ const MAX_HISTORY_PERIOD_COMMITS = 5000;
33
+ const SAFE_EXTENSIONS = new Set(['.md', '.json']);
34
+ const DOCX_MANIFEST_PATH = '.piecemaker/history-docx-ooxml.json';
35
+ const DOCX_MANIFEST_VERSION = 1;
36
+ const DOCX_FINGERPRINT_ALGORITHM = 'ooxml-central-directory-crc32-v1';
37
+ const MAX_DOCX_CENTRAL_BYTES = 16 * 1024 * 1024;
38
+ const MAX_DOCX_PARTS = 20_000;
39
+ const MAX_DOCX_TEXT_XML_BYTES = 32 * 1024 * 1024;
40
+ const TECHNICAL_CASE_NAMES = new Set(['piecemaker_output']);
41
+ /**
42
+ * Arborescences techniques jamais parcourues. Un dossier juridique finit par
43
+ * héberger autre chose que des pièces : le dossier de test embarque une copie
44
+ * complète d'un projet Node, dont les 53 000 fichiers noyaient la liste de
45
+ * l'administration (47 000 entrées) et faisaient entrer les `package.json` de
46
+ * `node_modules` dans l'historique du dossier.
47
+ */
48
+ const IGNORED_DIRECTORY_NAMES = new Set([
49
+ 'node_modules', 'dist', 'build', 'out', 'coverage', 'vendor', 'target', '__pycache__', 'venv',
50
+ ]);
51
+ /** Plafond de la liste de l'administration ; au-delà, `truncated` le signale. */
52
+ const MAX_ORIGINALS = 2000;
53
+ const PERF_SLOW_MS = 250;
54
+ const PERF_LOG_ALL = process.env.PIECEMAKER_PERF_LOG === '1';
55
+ const COMMIT_USER_NAME_KEY = 'PIECEMAKER_USER_NAME';
56
+ const TECHNICAL_COMMIT_EMAIL = 'commits@piecemaker.local';
57
+ // Repli d'auteur Git quand aucune identité n'a été renseignée : un commit
58
+ // automatique (ex. enregistrement du mapping) ne doit jamais être bloqué par
59
+ // une identité manquante.
60
+ const DEFAULT_COMMIT_USER_NAME = 'PieceMaker';
61
+ const GLOBAL_ENV_FILE = path.resolve(__dirname, '..', '..', '..', '.env');
62
+ // Identité de commit partagée par tous les clones. `GLOBAL_ENV_FILE` est résolu
63
+ // relativement à ce module : lancé depuis le cache du plugin (hook d'édition),
64
+ // il pointe à côté du clone runtime et n'existe pas — le `.env` de l'identité
65
+ // vit dans le clone runtime, hors de portée. `config.json` sous ~/.piecemaker
66
+ // est le seul emplacement stable que le hook lit à coup sûr, quel que soit le
67
+ // clone d'où il tourne.
68
+ const IDENTITY_CONFIG_FILE = path.join(os.homedir(), '.piecemaker', 'config.json');
69
+ const inflateRaw = promisify(zlib.inflateRaw);
70
+ const deflateRaw = promisify(zlib.deflateRaw);
71
+ function validateCommitUserName(value) {
72
+ const cleaned = String(value || '').trim();
73
+ if (!cleaned) {
74
+ throw new Error('Identité utilisateur absente : renseignez votre nom dans les paramètres administrateur.');
75
+ }
76
+ if (cleaned.length > 160 || /[\x00-\x1f\x7f<>]/.test(cleaned)) {
77
+ throw new Error('Nom utilisateur invalide pour la signature des commits.');
78
+ }
79
+ return cleaned;
80
+ }
81
+ function unquoteEnvValue(value) {
82
+ const raw = String(value || '').trim();
83
+ if (raw.length >= 2 && ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'")))) {
84
+ return raw.slice(1, -1);
85
+ }
86
+ return raw;
87
+ }
88
+ function readCommitIdentityEnv(file = GLOBAL_ENV_FILE) {
89
+ let value = '';
90
+ try {
91
+ if (file && fs.existsSync(file)) {
92
+ for (const line of fs.readFileSync(file, 'utf8').split(/\r?\n/)) {
93
+ const match = line.match(/^\s*PIECEMAKER_USER_NAME\s*=(.*)$/);
94
+ if (match)
95
+ value = unquoteEnvValue(match[1]);
96
+ }
97
+ }
98
+ }
99
+ catch {
100
+ // Le processus peut encore avoir reçu l'identité depuis son environnement.
101
+ }
102
+ return value || process.env[COMMIT_USER_NAME_KEY] || '';
103
+ }
104
+ /** Nom de l'utilisateur mémorisé dans ~/.piecemaker/config.json (tous clones). */
105
+ function readCommitIdentityConfig(file = IDENTITY_CONFIG_FILE) {
106
+ try {
107
+ if (file && fs.existsSync(file)) {
108
+ const config = JSON.parse(fs.readFileSync(file, 'utf8'));
109
+ const name = config?.commits?.userName ?? config?.userName;
110
+ if (typeof name === 'string' && name.trim())
111
+ return name.trim();
112
+ }
113
+ }
114
+ catch {
115
+ // Config illisible : on retombe sur les autres sources d'identité.
116
+ }
117
+ return '';
118
+ }
119
+ /** Identité personnelle appliquée à l'auteur et au validateur Git. */
120
+ function resolveCommitIdentity({ identity = null, envFile = GLOBAL_ENV_FILE, configFile = IDENTITY_CONFIG_FILE } = {}) {
121
+ const requestedName = typeof identity === 'string' ? identity : identity?.name;
122
+ // Sans identité explicite (hook d'édition), on tente le `.env` du clone
123
+ // courant puis, à défaut, config.json — le hook tourne depuis le cache du
124
+ // plugin où `envFile` par défaut n'existe pas. À défaut de tout ça, un nom
125
+ // technique par défaut : l'absence d'identité ne doit jamais empêcher un
126
+ // commit automatique.
127
+ const name = validateCommitUserName((identity ? requestedName : readCommitIdentityEnv(envFile) || readCommitIdentityConfig(configFile)) || DEFAULT_COMMIT_USER_NAME);
128
+ return {
129
+ name,
130
+ // Git exige une adresse dans son format d'identité, mais PieceMaker ne
131
+ // collecte aucune adresse personnelle pour signer les tâches.
132
+ email: TECHNICAL_COMMIT_EMAIL,
133
+ };
134
+ }
135
+ /**
136
+ * Journal de performance volontairement compact : aucun contenu de dossier ni
137
+ * argument Git n'est journalisé. Les opérations lentes sont visibles par
138
+ * défaut ; PIECEMAKER_PERF_LOG=1 affiche aussi les étapes rapides pendant un
139
+ * diagnostic ponctuel.
140
+ */
141
+ function logPerformance(operation, startedAt, details = {}, slowMs = PERF_SLOW_MS) {
142
+ const durationMs = Number((performance.now() - startedAt).toFixed(1));
143
+ if (PERF_LOG_ALL || durationMs >= slowMs) {
144
+ const write = durationMs >= slowMs ? console.warn : console.log;
145
+ write(`[PM-PERF] ${operation}`, { durationMs, ...details });
146
+ }
147
+ return durationMs;
148
+ }
149
+ async function runGit(cwd, args, { gitDir, workTree, env = {}, input, allowFailure = false, encoding = 'utf8', maxOutputBytes = MAX_GIT_BUFFER, truncateOutput = false, } = {}) {
150
+ const startedAt = performance.now();
151
+ const command = [
152
+ ...(gitDir ? [`--git-dir=${gitDir}`] : []),
153
+ ...(workTree ? [`--work-tree=${workTree}`] : []),
154
+ '-c',
155
+ 'core.quotePath=false',
156
+ ...args,
157
+ ];
158
+ // `spawn` plutôt que `spawnSync` : le serveur d'administration sert aussi le
159
+ // task pane et le WebSocket depuis la même boucle d'événements, qu'un git
160
+ // synchrone bloquerait le temps du parcours complet du dossier.
161
+ return new Promise((resolve, reject) => {
162
+ const child = spawn('git', command, {
163
+ cwd,
164
+ windowsHide: true,
165
+ env: { ...process.env, ...env },
166
+ });
167
+ const outChunks = [];
168
+ const errChunks = [];
169
+ let outBytes = 0;
170
+ let failure = null;
171
+ let truncated = false;
172
+ child.stdout.on('data', (chunk) => {
173
+ if (truncated)
174
+ return;
175
+ const nextBytes = outBytes + chunk.length;
176
+ if (nextBytes > maxOutputBytes) {
177
+ if (truncateOutput) {
178
+ const remaining = Math.max(maxOutputBytes - outBytes, 0);
179
+ if (remaining)
180
+ outChunks.push(chunk.subarray(0, remaining));
181
+ outBytes += remaining;
182
+ truncated = true;
183
+ child.kill();
184
+ return;
185
+ }
186
+ if (!failure) {
187
+ failure = new Error(`git ${args[0]} a produit une sortie trop volumineuse`);
188
+ child.kill();
189
+ }
190
+ return;
191
+ }
192
+ outBytes = nextBytes;
193
+ outChunks.push(chunk);
194
+ });
195
+ child.stderr.on('data', (chunk) => errChunks.push(chunk));
196
+ child.on('error', (error) => { failure = failure || error; });
197
+ child.on('close', (code) => {
198
+ const rawStdout = Buffer.concat(outChunks);
199
+ const rawStderr = Buffer.concat(errChunks).toString('utf8');
200
+ const stdout = encoding === null ? rawStdout : rawStdout.toString('utf8').trimEnd();
201
+ const stderr = encoding === null ? rawStderr : rawStderr.trim();
202
+ const status = failure ? null : truncated && truncateOutput ? 0 : code;
203
+ logPerformance('git', startedAt, {
204
+ command: args[0] || 'unknown',
205
+ status: status ?? 1,
206
+ stdoutBytes: rawStdout.length,
207
+ truncated,
208
+ });
209
+ if (!allowFailure && ((status ?? 1) !== 0 || failure)) {
210
+ reject(new Error(stderr.trim() || rawStdout.toString('utf8') || failure?.message || `git ${args[0]} a échoué`));
211
+ return;
212
+ }
213
+ resolve({ code: status ?? 1, stdout, stderr, error: failure, truncated });
214
+ });
215
+ child.stdin.on('error', () => { });
216
+ child.stdin.end(input === undefined ? undefined : input);
217
+ });
218
+ }
219
+ /** `PieceMaker_Output` et consorts ne sont pas des dossiers juridiques. */
220
+ function isTechnicalCaseDirectoryName(value) {
221
+ return TECHNICAL_CASE_NAMES.has(String(value || '').trim().toLowerCase());
222
+ }
223
+ function isIgnoredDirectoryName(value) {
224
+ const name = String(value || '').trim().toLowerCase();
225
+ return IGNORED_DIRECTORY_NAMES.has(name) || TECHNICAL_CASE_NAMES.has(name);
226
+ }
227
+ function isDocxPath(value) {
228
+ return path.extname(String(value || '')).toLowerCase() === '.docx';
229
+ }
230
+ function emptyDocxManifest() {
231
+ return { version: DOCX_MANIFEST_VERSION, algorithm: DOCX_FINGERPRINT_ALGORITHM, files: {} };
232
+ }
233
+ function findZipEnd(buffer) {
234
+ const first = Math.max(0, buffer.length - 65_557);
235
+ for (let offset = buffer.length - 22; offset >= first; offset -= 1) {
236
+ if (buffer.readUInt32LE(offset) === 0x06054b50)
237
+ return offset;
238
+ }
239
+ return -1;
240
+ }
241
+ async function parseCentralDirectory(buffer, entries) {
242
+ if (entries > MAX_DOCX_PARTS)
243
+ return null;
244
+ const parts = [];
245
+ let offset = 0;
246
+ for (let index = 0; index < entries; index += 1) {
247
+ if (offset + 46 > buffer.length || buffer.readUInt32LE(offset) !== 0x02014b50)
248
+ return null;
249
+ const flags = buffer.readUInt16LE(offset + 8);
250
+ const compression = buffer.readUInt16LE(offset + 10);
251
+ const crc32 = buffer.readUInt32LE(offset + 16).toString(16).padStart(8, '0');
252
+ const compressedSize = buffer.readUInt32LE(offset + 20);
253
+ const size = buffer.readUInt32LE(offset + 24);
254
+ const nameLength = buffer.readUInt16LE(offset + 28);
255
+ const next = offset + 46 + nameLength + buffer.readUInt16LE(offset + 30) + buffer.readUInt16LE(offset + 32);
256
+ if (next > buffer.length)
257
+ return null;
258
+ const name = buffer.subarray(offset + 46, offset + 46 + nameLength)
259
+ .toString((flags & 0x0800) !== 0 ? 'utf8' : 'latin1')
260
+ .replaceAll('\\', '/');
261
+ if (name && !name.endsWith('/')) {
262
+ parts.push({
263
+ name,
264
+ crc32,
265
+ size,
266
+ compressedSize,
267
+ compression,
268
+ localOffset: buffer.readUInt32LE(offset + 42),
269
+ });
270
+ }
271
+ offset = next;
272
+ if (index > 0 && index % 1000 === 0)
273
+ await new Promise((resolve) => setImmediate(resolve));
274
+ }
275
+ parts.sort((left, right) => left.name.localeCompare(right.name));
276
+ return parts;
277
+ }
278
+ /** Empreinte canonique des entrées OOXML, indépendante du conteneur ZIP. */
279
+ async function fingerprintCentralDirectory(buffer, entries) {
280
+ const parts = await parseCentralDirectory(buffer, entries);
281
+ if (!parts)
282
+ return null;
283
+ const hash = crypto.createHash('sha256');
284
+ for (let index = 0; index < parts.length; index += 1) {
285
+ const part = parts[index];
286
+ hash.update(`${part.name}\0${part.crc32}\0${part.size}\n`);
287
+ if (index > 0 && index % 1000 === 0)
288
+ await new Promise((resolve) => setImmediate(resolve));
289
+ }
290
+ return { fingerprint: hash.digest('hex'), format: 'ooxml', partCount: parts.length };
291
+ }
292
+ const docxFingerprintCache = new Map();
293
+ const docxTreeCache = new Map();
294
+ const docxTextCache = new Map();
295
+ function boundedCacheSet(cache, key, value, max) {
296
+ if (cache.has(key))
297
+ cache.delete(key);
298
+ cache.set(key, value);
299
+ if (cache.size > max)
300
+ cache.delete(cache.keys().next().value);
301
+ }
302
+ function docxStat(stat) {
303
+ return {
304
+ size: stat.size,
305
+ mtimeMs: Number(stat.mtimeMs.toFixed(3)),
306
+ ctimeMs: Number(stat.ctimeMs.toFixed(3)),
307
+ };
308
+ }
309
+ function sameDocxStat(entry, stat) {
310
+ return entry?.size === stat.size && entry?.mtimeMs === stat.mtimeMs && entry?.ctimeMs === stat.ctimeMs;
311
+ }
312
+ async function readRange(handle, length, position) {
313
+ const buffer = Buffer.allocUnsafe(length);
314
+ const { bytesRead } = await handle.read(buffer, 0, length, position);
315
+ return bytesRead === length ? buffer : buffer.subarray(0, bytesRead);
316
+ }
317
+ function normalizeWordSections(sections) {
318
+ return new Promise((resolve, reject) => {
319
+ const worker = new Worker(path.join(__dirname, 'docx-text-worker.cjs'), { workerData: sections });
320
+ worker.once('message', resolve);
321
+ worker.once('error', reject);
322
+ worker.once('exit', (code) => {
323
+ if (code !== 0)
324
+ reject(new Error(`Extraction DOCX interrompue (${code}).`));
325
+ });
326
+ });
327
+ }
328
+ async function readZipPart(handle, part) {
329
+ if (![0, 8].includes(part.compression)
330
+ || part.compressedSize > MAX_DOCX_TEXT_XML_BYTES
331
+ || part.size > MAX_DOCX_TEXT_XML_BYTES)
332
+ return null;
333
+ const header = await readRange(handle, 30, part.localOffset);
334
+ if (header.length !== 30 || header.readUInt32LE(0) !== 0x04034b50)
335
+ return null;
336
+ const dataOffset = part.localOffset + 30 + header.readUInt16LE(26) + header.readUInt16LE(28);
337
+ const compressed = await readRange(handle, part.compressedSize, dataOffset);
338
+ if (compressed.length !== part.compressedSize)
339
+ return null;
340
+ if (part.compression === 0)
341
+ return compressed;
342
+ try {
343
+ return await inflateRaw(compressed, { maxOutputLength: MAX_DOCX_TEXT_XML_BYTES });
344
+ }
345
+ catch {
346
+ return null;
347
+ }
348
+ }
349
+ function docxPartTitle(name) {
350
+ if (name === 'word/document.xml')
351
+ return 'Corps du document';
352
+ if (/^word\/header\d*\.xml$/i.test(name))
353
+ return 'En-tête';
354
+ if (/^word\/footer\d*\.xml$/i.test(name))
355
+ return 'Pied de page';
356
+ if (name === 'word/footnotes.xml')
357
+ return 'Notes de bas de page';
358
+ if (name === 'word/endnotes.xml')
359
+ return 'Notes de fin';
360
+ if (name === 'word/comments.xml')
361
+ return 'Commentaires';
362
+ return name;
363
+ }
364
+ async function extractDocxText(file, stat) {
365
+ const key = `${file}\0${stat.size}\0${stat.mtimeMs}\0${stat.ctimeMs}`;
366
+ if (docxTextCache.has(key))
367
+ return docxTextCache.get(key);
368
+ let handle;
369
+ let text = '';
370
+ try {
371
+ handle = await fsp.open(file, 'r');
372
+ const tailLength = Math.min(stat.size, 65_557);
373
+ const tail = await readRange(handle, tailLength, stat.size - tailLength);
374
+ const end = findZipEnd(tail);
375
+ if (end < 0)
376
+ return '';
377
+ const entries = tail.readUInt16LE(end + 10);
378
+ const centralSize = tail.readUInt32LE(end + 12);
379
+ const centralOffset = tail.readUInt32LE(end + 16);
380
+ if (entries === 0xffff || centralSize > MAX_DOCX_CENTRAL_BYTES || centralOffset + centralSize > stat.size)
381
+ return '';
382
+ const parts = await parseCentralDirectory(await readRange(handle, centralSize, centralOffset), entries);
383
+ if (!parts)
384
+ return '';
385
+ const readable = parts.filter((part) => part.name === 'word/document.xml'
386
+ || /^word\/(?:header\d*|footer\d*|footnotes|endnotes|comments)\.xml$/i.test(part.name));
387
+ const sections = [];
388
+ let totalBytes = 0;
389
+ for (const part of readable) {
390
+ totalBytes += part.size;
391
+ if (totalBytes > MAX_DOCX_TEXT_XML_BYTES)
392
+ break;
393
+ const xml = await readZipPart(handle, part);
394
+ if (!xml)
395
+ continue;
396
+ sections.push({ title: docxPartTitle(part.name), xml: xml.toString('utf8') });
397
+ }
398
+ text = await normalizeWordSections(sections);
399
+ }
400
+ finally {
401
+ await handle?.close().catch(() => { });
402
+ }
403
+ boundedCacheSet(docxTextCache, key, text, 2_000);
404
+ return text;
405
+ }
406
+ async function encodeTextSnapshot(text) {
407
+ const compressed = await deflateRaw(Buffer.from(String(text || ''), 'utf8'), { level: 6 });
408
+ return compressed.toString('base64');
409
+ }
410
+ async function decodeTextSnapshot(entry) {
411
+ if (!entry?.textDeflate)
412
+ return null;
413
+ try {
414
+ return (await inflateRaw(Buffer.from(entry.textDeflate, 'base64'), { maxOutputLength: MAX_DOCX_TEXT_XML_BYTES })).toString('utf8');
415
+ }
416
+ catch {
417
+ return null;
418
+ }
419
+ }
420
+ async function addDocxTextSnapshot(caseRoot, relative, entry) {
421
+ const absolute = path.join(caseRoot, ...relative.split('/'));
422
+ const stat = docxStat(await fsp.stat(absolute));
423
+ const text = await extractDocxText(absolute, stat);
424
+ return {
425
+ ...entry,
426
+ textDeflate: await encodeTextSnapshot(text),
427
+ textHash: crypto.createHash('sha256').update(text).digest('hex'),
428
+ };
429
+ }
430
+ async function fingerprintDocx(file, stat) {
431
+ const key = `${file}\0${stat.size}\0${stat.mtimeMs}\0${stat.ctimeMs}`;
432
+ if (docxFingerprintCache.has(key))
433
+ return docxFingerprintCache.get(key);
434
+ let fingerprint = null;
435
+ let handle;
436
+ try {
437
+ handle = await fsp.open(file, 'r');
438
+ const tailLength = Math.min(stat.size, 65_557);
439
+ const tail = await readRange(handle, tailLength, stat.size - tailLength);
440
+ const end = findZipEnd(tail);
441
+ if (end >= 0) {
442
+ const entries = tail.readUInt16LE(end + 10);
443
+ const centralSize = tail.readUInt32LE(end + 12);
444
+ const centralOffset = tail.readUInt32LE(end + 16);
445
+ if (entries !== 0xffff && centralSize <= MAX_DOCX_CENTRAL_BYTES && centralOffset + centralSize <= stat.size) {
446
+ fingerprint = await fingerprintCentralDirectory(await readRange(handle, centralSize, centralOffset), entries);
447
+ }
448
+ }
449
+ }
450
+ catch {
451
+ fingerprint = null;
452
+ }
453
+ finally {
454
+ await handle?.close().catch(() => { });
455
+ }
456
+ // Repli pour un faux/ZIP64 DOCX : métadonnées seulement, jamais le binaire.
457
+ fingerprint ||= {
458
+ fingerprint: crypto.createHash('sha256').update(`metadata\0${stat.size}\0${stat.mtimeMs}\0${stat.ctimeMs}`).digest('hex'),
459
+ format: 'metadata-fallback',
460
+ partCount: 0,
461
+ };
462
+ boundedCacheSet(docxFingerprintCache, key, fingerprint, 20_000);
463
+ return fingerprint;
464
+ }
465
+ async function currentDocxManifest(caseRoot, baseline = emptyDocxManifest(), { includeText = false } = {}) {
466
+ const root = await fsp.realpath(caseRoot);
467
+ const protection = includeText ? readProtection(root) : null;
468
+ const files = {};
469
+ let count = 0;
470
+ async function visit(directory, prefix = '') {
471
+ for (const entry of await fsp.readdir(directory, { withFileTypes: true })) {
472
+ if (entry.name.startsWith('.') || entry.name.startsWith('~$') || entry.isSymbolicLink())
473
+ continue;
474
+ const absolute = path.join(directory, entry.name);
475
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
476
+ if (entry.isDirectory()) {
477
+ if (!isIgnoredDirectoryName(entry.name))
478
+ await visit(absolute, relative);
479
+ continue;
480
+ }
481
+ if (!entry.isFile() || !isDocxPath(entry.name))
482
+ continue;
483
+ if (count >= MAX_SAFE_FILES)
484
+ throw new Error('Ce dossier contient trop de documents Word pour calculer leur historique.');
485
+ const stat = docxStat(await fsp.stat(absolute));
486
+ const previous = baseline.files[relative];
487
+ let current;
488
+ if (sameDocxStat(previous, stat)) {
489
+ current = previous;
490
+ }
491
+ else {
492
+ const fingerprint = await fingerprintDocx(absolute, stat);
493
+ current = previous?.fingerprint === fingerprint.fingerprint ? previous : { ...stat, ...fingerprint };
494
+ }
495
+ if (includeText) {
496
+ if (isProtectedFile(absolute, root, protection)) {
497
+ const { textDeflate: _textDeflate, textHash: _textHash, ...withoutText } = current;
498
+ current = withoutText;
499
+ }
500
+ else if (!current.textDeflate) {
501
+ current = await addDocxTextSnapshot(root, relative, current);
502
+ }
503
+ }
504
+ files[relative] = current;
505
+ count += 1;
506
+ if (count % 100 === 0)
507
+ await new Promise((resolve) => setImmediate(resolve));
508
+ }
509
+ }
510
+ await visit(root);
511
+ return {
512
+ version: DOCX_MANIFEST_VERSION,
513
+ algorithm: DOCX_FINGERPRINT_ALGORITHM,
514
+ files: Object.fromEntries(Object.entries(files).sort(([left], [right]) => left.localeCompare(right, 'fr'))),
515
+ };
516
+ }
517
+ function serializeDocxManifest(manifest) {
518
+ return `${JSON.stringify(manifest)}\n`;
519
+ }
520
+ function parseDocxManifest(value) {
521
+ try {
522
+ const manifest = JSON.parse(String(value || ''));
523
+ return manifest?.version === DOCX_MANIFEST_VERSION && manifest.files && typeof manifest.files === 'object'
524
+ ? manifest
525
+ : emptyDocxManifest();
526
+ }
527
+ catch {
528
+ return emptyDocxManifest();
529
+ }
530
+ }
531
+ function resolveCasesRoot(casesRoot) {
532
+ if (!casesRoot)
533
+ throw new Error('Le dossier racine PieceMaker n’est pas configuré.');
534
+ const root = path.resolve(String(casesRoot));
535
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {
536
+ throw new Error(`Le dossier racine PieceMaker est introuvable : ${root}`);
537
+ }
538
+ return fs.realpathSync(root);
539
+ }
540
+ function resolveCase(casesRoot, caseName) {
541
+ const root = resolveCasesRoot(casesRoot);
542
+ const name = String(caseName || '').trim();
543
+ if (!name || name === '.' || name === '..' || path.basename(name) !== name || name.startsWith('.')) {
544
+ throw new Error('Dossier juridique invalide.');
545
+ }
546
+ const candidate = path.join(root, name);
547
+ if (!fs.existsSync(candidate) || !fs.statSync(candidate).isDirectory()) {
548
+ throw new Error(`Le dossier juridique « ${name} » est introuvable.`);
549
+ }
550
+ const caseRoot = fs.realpathSync(candidate);
551
+ if (path.dirname(caseRoot) !== root) {
552
+ throw new Error('Le dossier juridique résout hors de la racine PieceMaker.');
553
+ }
554
+ return { casesRoot: root, name, root: caseRoot };
555
+ }
556
+ function locateCaseFile(casesRoot, filePath) {
557
+ const root = resolveCasesRoot(casesRoot);
558
+ const requested = path.resolve(String(filePath || ''));
559
+ let absolute = requested;
560
+ try {
561
+ absolute = fs.realpathSync(requested);
562
+ }
563
+ catch {
564
+ try {
565
+ absolute = path.join(fs.realpathSync(path.dirname(requested)), path.basename(requested));
566
+ }
567
+ catch { }
568
+ }
569
+ if (absolute === root || !absolute.startsWith(`${root}${path.sep}`))
570
+ return null;
571
+ const relativeToRoot = path.relative(root, absolute);
572
+ const [caseName, ...parts] = relativeToRoot.split(path.sep);
573
+ if (!caseName || parts.length === 0)
574
+ return null;
575
+ const legalCase = resolveCase(root, caseName);
576
+ if (isProtectedFile(absolute, legalCase.root)) {
577
+ return { ...legalCase, absolute, protected: true, relative: parts.join('/') };
578
+ }
579
+ if (path.extname(absolute).toLowerCase() && !SAFE_EXTENSIONS.has(path.extname(absolute).toLowerCase())) {
580
+ return { ...legalCase, absolute, protected: false, safe: false, relative: parts.join('/') };
581
+ }
582
+ const relative = path.relative(legalCase.root, absolute).split(path.sep).join('/');
583
+ if (!relative || relative.startsWith('../'))
584
+ return null;
585
+ return { ...legalCase, absolute, protected: false, safe: SAFE_EXTENSIONS.has(path.extname(relative).toLowerCase()), relative };
586
+ }
587
+ async function safeCaseFiles(caseRoot) {
588
+ const startedAt = performance.now();
589
+ const root = await fsp.realpath(caseRoot);
590
+ const files = [];
591
+ let bytes = 0;
592
+ async function visit(directory, prefix = '') {
593
+ for (const entry of await fsp.readdir(directory, { withFileTypes: true })) {
594
+ if (entry.name.startsWith('.') || entry.isSymbolicLink())
595
+ continue;
596
+ const absolute = path.join(directory, entry.name);
597
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
598
+ if (entry.isDirectory()) {
599
+ if (!isIgnoredDirectoryName(entry.name))
600
+ await visit(absolute, relative);
601
+ continue;
602
+ }
603
+ if (!entry.isFile() || !SAFE_EXTENSIONS.has(path.extname(entry.name).toLowerCase()))
604
+ continue;
605
+ const size = (await fsp.stat(absolute)).size;
606
+ bytes += size;
607
+ files.push(relative);
608
+ if (files.length > MAX_SAFE_FILES)
609
+ throw new Error('Ce dossier contient trop de fichiers Markdown/JSON pour un commit sûr.');
610
+ if (bytes > MAX_SAFE_BYTES)
611
+ throw new Error('Les fichiers accessibles à l’IA dépassent 250 Mo ; commit annulé.');
612
+ }
613
+ }
614
+ await visit(root);
615
+ const sorted = files.sort((a, b) => a.localeCompare(b, 'fr'));
616
+ logPerformance('safeCaseFiles', startedAt, { files: sorted.length, bytes });
617
+ return sorted;
618
+ }
619
+ /**
620
+ * Les pièces d'un dossier juridique, sous-dossiers compris.
621
+ *
622
+ * Le recensement ne dépend plus d'un sous-dossier « Pièces originales » : un
623
+ * cabinet range ses pièces à plat, à côté du Markdown qu'il en tire, et cette
624
+ * organisation-là ne protégeait donc rien. Est une pièce tout fichier qui n'est
625
+ * ni Markdown ni JSON — le reste, ce sont les dérivés que l'IA a le droit de
626
+ * lire (sous mapping) et le mapping lui-même.
627
+ *
628
+ * `converted` / `scanned` restent l'état du pipeline ; `protected` est la
629
+ * décision prise dans l'administration et appliquée par les hooks. Le scan
630
+ * n'est plus déduit de la présence d'un mapping sensible par pièce : le
631
+ * manifeste technique `.piecemaker/anonymization-state.json`, dépourvu de PII,
632
+ * mémorise les empreintes de conversion et de scan. Les anciens sensitive maps
633
+ * ne servent que de compatibilité pendant leur migration.
634
+ */
635
+ async function originalFilesOverview(caseRoot, { safeFiles: knownSafeFiles = null } = {}) {
636
+ const startedAt = performance.now();
637
+ const root = await fsp.realpath(caseRoot);
638
+ const safeFiles = knownSafeFiles || await safeCaseFiles(root);
639
+ const markdownKeys = new Set(safeFiles.filter((file) => path.extname(file).toLowerCase() === '.md').map(documentKey));
640
+ const scanKeys = new Set(safeFiles
641
+ .filter((file) => file.toLowerCase().endsWith('_sensitive_map.json'))
642
+ .map((file) => documentKey(file).replace(/-sensitive-map$/, '')));
643
+ const anonymizationState = readAnonymizationState(root);
644
+ const protection = readProtection(root);
645
+ const originals = [];
646
+ let truncated = false;
647
+ async function visit(directory, prefix = '') {
648
+ const entries = await fsp.readdir(directory, { withFileTypes: true });
649
+ // MinerU écrit sa sortie dans `<nom de la pièce>/auto/` à côté de la pièce.
650
+ // Ces dérivés portent le même contenu que l'original — ils restent donc
651
+ // protégés par défaut — mais les lister doublerait chaque pièce dans
652
+ // l'administration.
653
+ const conversionOutputs = new Set(entries.filter((entry) => entry.isFile()).map((entry) => documentKey(entry.name)));
654
+ for (const entry of entries) {
655
+ if (entry.name.startsWith('.') || entry.name.startsWith('~$') || entry.isSymbolicLink())
656
+ continue;
657
+ const absolute = path.join(directory, entry.name);
658
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
659
+ if (entry.isDirectory()) {
660
+ // Le sous-dossier des fichiers produits (Markdown, mapping) n'est jamais
661
+ // une source de pièces : ses `.md`/`.json` sont déjà écartés par
662
+ // `SAFE_EXTENSIONS`, mais d'éventuels dérivés non-Markdown (images
663
+ // MinerU) qui y vivent ne doivent pas non plus être listés comme pièces.
664
+ // `safeCaseFiles`, lui, continue de le parcourir pour repérer les `.md`.
665
+ if (entry.name === WORKSPACE_SUBDIR)
666
+ continue;
667
+ if (isIgnoredDirectoryName(entry.name) || conversionOutputs.has(documentKey(entry.name)))
668
+ continue;
669
+ await visit(absolute, relative);
670
+ continue;
671
+ }
672
+ if (originals.length >= MAX_ORIGINALS) {
673
+ truncated = true;
674
+ return;
675
+ }
676
+ if (!entry.isFile())
677
+ continue;
678
+ if (SAFE_EXTENSIONS.has(path.extname(entry.name).toLowerCase()))
679
+ continue;
680
+ const stat = await fsp.stat(absolute);
681
+ const key = documentKey(entry.name);
682
+ const stateEntry = anonymizationState.files[stateKey(relative)];
683
+ // Un dossier ancien sans manifeste conserve le comportement historique
684
+ // (Markdown présent = converti). Dès qu'une empreinte existe, elle rend un
685
+ // Markdown périmé visible au lieu de le réutiliser silencieusement.
686
+ const converted = markdownKeys.has(key) && (!stateEntry || isConvertedEntry(stateEntry, stat));
687
+ const scanned = converted && (isAnonymizedEntry(stateEntry, stat)
688
+ || scanKeys.has(key));
689
+ originals.push({
690
+ name: entry.name,
691
+ path: relative,
692
+ extension: path.extname(entry.name).toLowerCase(),
693
+ size: stat.size,
694
+ modifiedAt: stat.mtime.toISOString(),
695
+ converted,
696
+ scanned,
697
+ protected: isProtectedFile(absolute, root, protection),
698
+ resource: isResourceFile(absolute, root, protection),
699
+ status: converted ? (scanned ? 'ready' : 'awaiting-scan') : 'not-converted',
700
+ });
701
+ }
702
+ }
703
+ await visit(root);
704
+ const sorted = originals.sort((a, b) => a.path.localeCompare(b.path, 'fr'));
705
+ if (truncated)
706
+ sorted.truncated = true;
707
+ logPerformance('originalFilesOverview', startedAt, {
708
+ safeFiles: safeFiles.length,
709
+ originals: sorted.length,
710
+ truncated,
711
+ });
712
+ return sorted;
713
+ }
714
+ function historyId(legalCase) {
715
+ const slug = legalCase.name
716
+ .normalize('NFKD')
717
+ .replace(/[\u0300-\u036f]/g, '')
718
+ .replace(/[^A-Za-z0-9._-]+/g, '-')
719
+ .replace(/^[.-]+|[.-]+$/g, '')
720
+ .slice(0, 60) || 'dossier';
721
+ const digest = crypto.createHash('sha256').update(legalCase.root).digest('hex').slice(0, 12);
722
+ return `${slug}-${digest}`;
723
+ }
724
+ const caseStateCache = new Map();
725
+ function caseStateCacheKey(homeDir, legalCase) {
726
+ return `${path.resolve(homeDir)}:${historyId(legalCase)}`;
727
+ }
728
+ function historyDirectory(homeDir = path.join(os.homedir(), '.piecemaker')) {
729
+ return path.join(homeDir, 'case-history');
730
+ }
731
+ function historyRepo(homeDir, legalCase) {
732
+ return path.join(historyDirectory(homeDir), `${historyId(legalCase)}.git`);
733
+ }
734
+ async function ensureHistoryRepo(homeDir, legalCase) {
735
+ const gitDir = historyRepo(homeDir, legalCase);
736
+ if (!fs.existsSync(gitDir)) {
737
+ fs.mkdirSync(path.dirname(gitDir), { recursive: true });
738
+ await runGit(legalCase.root, ['init', '--bare', gitDir]);
739
+ await runGit(legalCase.root, ['symbolic-ref', 'HEAD', HISTORY_REF], { gitDir });
740
+ }
741
+ const main = await runGit(legalCase.root, ['rev-parse', '--verify', HISTORY_REF], { gitDir, allowFailure: true });
742
+ if (main.code !== 0) {
743
+ const legacy = await runGit(legalCase.root, ['rev-parse', '--verify', LEGACY_HISTORY_REF], { gitDir, allowFailure: true });
744
+ if (legacy.code === 0)
745
+ await runGit(legalCase.root, ['update-ref', HISTORY_REF, legacy.stdout], { gitDir });
746
+ }
747
+ const head = await runGit(legalCase.root, ['symbolic-ref', '-q', 'HEAD'], { gitDir, allowFailure: true });
748
+ const headCommit = head.code === 0
749
+ ? await runGit(legalCase.root, ['rev-parse', '--verify', head.stdout], { gitDir, allowFailure: true })
750
+ : { code: 1 };
751
+ const migratedMain = await runGit(legalCase.root, ['rev-parse', '--verify', HISTORY_REF], { gitDir, allowFailure: true });
752
+ if (head.code !== 0 || !head.stdout.startsWith('refs/heads/') || (headCommit.code !== 0 && migratedMain.code === 0)) {
753
+ await runGit(legalCase.root, ['symbolic-ref', 'HEAD', HISTORY_REF], { gitDir });
754
+ }
755
+ return gitDir;
756
+ }
757
+ async function activeHistoryRef(legalCase, gitDir) {
758
+ const result = await runGit(legalCase.root, ['symbolic-ref', '-q', 'HEAD'], { gitDir, allowFailure: true });
759
+ return result.code === 0 && result.stdout.startsWith('refs/heads/') ? result.stdout : HISTORY_REF;
760
+ }
761
+ async function latestCommit(legalCase, gitDir) {
762
+ const result = await runGit(legalCase.root, ['rev-parse', '--verify', await activeHistoryRef(legalCase, gitDir)], { gitDir, allowFailure: true });
763
+ return result.code === 0 ? result.stdout : '';
764
+ }
765
+ async function historyBranches(casesRoot, homeDir, caseName) {
766
+ const legalCase = resolveCase(casesRoot, caseName);
767
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
768
+ const activeRef = await activeHistoryRef(legalCase, gitDir);
769
+ const active = activeRef.slice('refs/heads/'.length);
770
+ const result = await runGit(legalCase.root, ['for-each-ref', '--format=%(refname:short)', 'refs/heads'], { gitDir });
771
+ const branches = [...new Set([active, ...result.stdout.split('\n').map((name) => name.trim()).filter(Boolean)])]
772
+ .sort((a, b) => a.localeCompare(b, 'fr'));
773
+ return { active, branches };
774
+ }
775
+ async function validatedBranchName(legalCase, gitDir, value) {
776
+ const name = String(value || '').trim();
777
+ if (!name || name.length > 120)
778
+ throw new Error('Le nom de branche est requis.');
779
+ const valid = await runGit(legalCase.root, ['check-ref-format', '--branch', name], { gitDir, allowFailure: true });
780
+ if (valid.code !== 0)
781
+ throw new Error('Nom de branche Git invalide.');
782
+ return name;
783
+ }
784
+ async function createHistoryBranch({ casesRoot, caseName, homeDir = path.join(os.homedir(), '.piecemaker'), name } = {}) {
785
+ const legalCase = resolveCase(casesRoot, caseName);
786
+ return withCaseLock(homeDir, legalCase, async () => {
787
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
788
+ const branch = await validatedBranchName(legalCase, gitDir, name);
789
+ const ref = `refs/heads/${branch}`;
790
+ const exists = await runGit(legalCase.root, ['show-ref', '--verify', '--quiet', ref], { gitDir, allowFailure: true });
791
+ if (exists.code === 0)
792
+ throw new Error(`La branche « ${branch} » existe déjà.`);
793
+ const parent = await latestCommit(legalCase, gitDir);
794
+ if (parent)
795
+ await runGit(legalCase.root, ['update-ref', ref, parent], { gitDir });
796
+ await runGit(legalCase.root, ['symbolic-ref', 'HEAD', ref], { gitDir });
797
+ caseStateCache.delete(caseStateCacheKey(homeDir, legalCase));
798
+ return historyBranches(casesRoot, homeDir, legalCase.name);
799
+ }, { waitMs: 10_000 });
800
+ }
801
+ async function checkoutHistoryBranch({ casesRoot, caseName, homeDir = path.join(os.homedir(), '.piecemaker'), name } = {}) {
802
+ const legalCase = resolveCase(casesRoot, caseName);
803
+ return withCaseLock(homeDir, legalCase, async () => {
804
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
805
+ const branch = await validatedBranchName(legalCase, gitDir, name);
806
+ const ref = `refs/heads/${branch}`;
807
+ const exists = await runGit(legalCase.root, ['show-ref', '--verify', '--quiet', ref], { gitDir, allowFailure: true });
808
+ const current = await activeHistoryRef(legalCase, gitDir);
809
+ if (exists.code !== 0 && current !== ref)
810
+ throw new Error(`La branche « ${branch} » n’existe pas.`);
811
+ await runGit(legalCase.root, ['symbolic-ref', 'HEAD', ref], { gitDir });
812
+ caseStateCache.delete(caseStateCacheKey(homeDir, legalCase));
813
+ return historyBranches(casesRoot, homeDir, legalCase.name);
814
+ }, { waitMs: 10_000 });
815
+ }
816
+ async function withCaseLock(homeDir, legalCase, callback, { waitMs = 0 } = {}) {
817
+ const directory = historyDirectory(homeDir);
818
+ fs.mkdirSync(directory, { recursive: true });
819
+ const lock = path.join(directory, `${historyId(legalCase)}.lock`);
820
+ const deadline = Date.now() + Math.max(Number(waitMs) || 0, 0);
821
+ let fd;
822
+ try {
823
+ while (fd === undefined) {
824
+ try {
825
+ fd = fs.openSync(lock, 'wx');
826
+ }
827
+ catch (error) {
828
+ if (error.code !== 'EEXIST')
829
+ throw error;
830
+ let age = 0;
831
+ try {
832
+ age = Date.now() - fs.statSync(lock).mtimeMs;
833
+ }
834
+ catch {
835
+ continue;
836
+ }
837
+ if (age >= 60_000) {
838
+ try {
839
+ fs.unlinkSync(lock);
840
+ }
841
+ catch { }
842
+ continue;
843
+ }
844
+ if (Date.now() >= deadline)
845
+ return { created: false, skipped: 'busy' };
846
+ await new Promise((resolve) => setTimeout(resolve, Math.min(50, Math.max(deadline - Date.now(), 1))));
847
+ }
848
+ }
849
+ fs.writeFileSync(fd, `${process.pid}\n`, 'utf8');
850
+ return await callback();
851
+ }
852
+ finally {
853
+ if (fd !== undefined) {
854
+ try {
855
+ fs.closeSync(fd);
856
+ }
857
+ catch { }
858
+ try {
859
+ fs.unlinkSync(lock);
860
+ }
861
+ catch { }
862
+ }
863
+ }
864
+ }
865
+ async function putDocxManifestInIndex(legalCase, gitDir, env, manifest) {
866
+ if (!Object.keys(manifest.files).length)
867
+ return;
868
+ const blob = (await runGit(legalCase.root, ['hash-object', '-w', '--stdin'], {
869
+ gitDir,
870
+ input: serializeDocxManifest(manifest),
871
+ })).stdout;
872
+ await runGit(legalCase.root, ['update-index', '--add', '--cacheinfo', `100644,${blob},${DOCX_MANIFEST_PATH}`], {
873
+ gitDir,
874
+ workTree: legalCase.root,
875
+ env,
876
+ });
877
+ }
878
+ async function treeDocxManifest(legalCase, gitDir, treeish) {
879
+ if (!treeish)
880
+ return emptyDocxManifest();
881
+ const key = `${gitDir}\0${treeish}`;
882
+ if (docxTreeCache.has(key))
883
+ return docxTreeCache.get(key);
884
+ const result = await runGit(legalCase.root, ['show', `${treeish}:${DOCX_MANIFEST_PATH}`], { gitDir, allowFailure: true });
885
+ const manifest = result.code === 0 ? parseDocxManifest(result.stdout) : emptyDocxManifest();
886
+ boundedCacheSet(docxTreeCache, key, manifest, 2_000);
887
+ return manifest;
888
+ }
889
+ function docxChanges(beforeManifest, afterManifest) {
890
+ const before = beforeManifest.files;
891
+ const after = afterManifest.files;
892
+ return [...new Set([...Object.keys(before), ...Object.keys(after)])]
893
+ .sort((left, right) => left.localeCompare(right, 'fr'))
894
+ .flatMap((filePath) => {
895
+ if (!before[filePath])
896
+ return [{ status: 'A', path: filePath, previousPath: null, kind: 'added' }];
897
+ if (!after[filePath])
898
+ return [{ status: 'D', path: filePath, previousPath: null, kind: 'deleted' }];
899
+ return before[filePath].fingerprint === after[filePath].fingerprint
900
+ ? []
901
+ : [{ status: 'M', path: filePath, previousPath: null, kind: 'modified' }];
902
+ });
903
+ }
904
+ async function liveDocxText(legalCase, filePath, entry) {
905
+ if (!entry)
906
+ return '';
907
+ const absolute = path.join(legalCase.root, ...filePath.split('/'));
908
+ try {
909
+ const stat = docxStat(await fsp.stat(absolute));
910
+ const fingerprint = await fingerprintDocx(absolute, stat);
911
+ if (fingerprint.fingerprint !== entry.fingerprint)
912
+ return null;
913
+ return extractDocxText(absolute, stat);
914
+ }
915
+ catch {
916
+ return null;
917
+ }
918
+ }
919
+ async function entryDocxText(legalCase, filePath, entry) {
920
+ if (!entry)
921
+ return '';
922
+ return await decodeTextSnapshot(entry) ?? liveDocxText(legalCase, filePath, entry);
923
+ }
924
+ function limitPatch(value) {
925
+ const buffer = Buffer.from(String(value || ''), 'utf8');
926
+ if (buffer.length <= MAX_PATCH_BYTES)
927
+ return { stdout: buffer.toString('utf8'), truncated: false };
928
+ return { stdout: `${buffer.subarray(0, MAX_PATCH_BYTES).toString('utf8')}…`, truncated: true };
929
+ }
930
+ async function docxTextDiff(legalCase, beforeManifest, afterManifest, filePath) {
931
+ const before = beforeManifest.files[filePath];
932
+ const after = afterManifest.files[filePath];
933
+ const absolute = path.join(legalCase.root, ...filePath.split('/'));
934
+ if (isProtectedFile(absolute, legalCase.root)) {
935
+ return {
936
+ stdout: `diff --text a/${filePath} b/${filePath}\n@@ Document protégé @@\n Le texte n’est pas extrait des pièces protégées.\n`,
937
+ truncated: false,
938
+ stats: { files: 1, added: 0, deleted: 0 },
939
+ };
940
+ }
941
+ const [beforeText, afterText] = await Promise.all([
942
+ entryDocxText(legalCase, filePath, before),
943
+ entryDocxText(legalCase, filePath, after),
944
+ ]);
945
+ if (beforeText === null || afterText === null) {
946
+ const available = afterText ?? beforeText ?? '';
947
+ const prefix = afterText !== null ? '+' : '-';
948
+ const lines = available.split('\n').map((line) => `${prefix}${line}`);
949
+ const patch = limitPatch([
950
+ `diff --text a/${filePath} b/${filePath}`,
951
+ `--- ${before ? `a/${filePath}` : '/dev/null'}`,
952
+ `+++ ${after ? `b/${filePath}` : '/dev/null'}`,
953
+ '@@ Texte partiellement disponible @@',
954
+ ' Le prochain commit servira de référence textuelle complète.',
955
+ ...lines,
956
+ '',
957
+ ].join('\n'));
958
+ return {
959
+ ...patch,
960
+ stats: {
961
+ files: 1,
962
+ added: prefix === '+' ? lines.length : 0,
963
+ deleted: prefix === '-' ? lines.length : 0,
964
+ },
965
+ };
966
+ }
967
+ const temporary = await fsp.mkdtemp(path.join(os.tmpdir(), 'piecemaker-docx-diff-'));
968
+ const beforeFile = path.join(temporary, 'avant.txt');
969
+ const afterFile = path.join(temporary, 'apres.txt');
970
+ try {
971
+ await Promise.all([
972
+ fsp.writeFile(beforeFile, `${beforeText}\n`, { encoding: 'utf8', mode: 0o600 }),
973
+ fsp.writeFile(afterFile, `${afterText}\n`, { encoding: 'utf8', mode: 0o600 }),
974
+ ]);
975
+ const result = await runGit(legalCase.root, [
976
+ 'diff', '--no-index', '--text', '--unified=3', '--', beforeFile, afterFile,
977
+ ], { allowFailure: true, maxOutputBytes: MAX_PATCH_BYTES, truncateOutput: true });
978
+ const hunk = String(result.stdout || '').match(/^@@[\s\S]*$/m)?.[0] || '';
979
+ const patch = [
980
+ `diff --text a/${filePath} b/${filePath}`,
981
+ `--- ${before ? `a/${filePath}` : '/dev/null'}`,
982
+ `+++ ${after ? `b/${filePath}` : '/dev/null'}`,
983
+ hunk,
984
+ ].filter(Boolean).join('\n');
985
+ const body = hunk.split('\n');
986
+ return {
987
+ stdout: patch,
988
+ truncated: result.truncated,
989
+ stats: {
990
+ files: 1,
991
+ added: body.filter((line) => line.startsWith('+') && !line.startsWith('+++')).length,
992
+ deleted: body.filter((line) => line.startsWith('-') && !line.startsWith('---')).length,
993
+ },
994
+ };
995
+ }
996
+ finally {
997
+ await fsp.rm(temporary, { recursive: true, force: true });
998
+ }
999
+ }
1000
+ async function buildCurrentTree(legalCase, gitDir, homeDir, baselineDocx = emptyDocxManifest(), { includeDocx = true } = {}) {
1001
+ const startedAt = performance.now();
1002
+ const temporaryIndex = path.join(historyDirectory(homeDir), `index-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
1003
+ const env = { GIT_INDEX_FILE: temporaryIndex };
1004
+ const [files, docxManifest] = await Promise.all([
1005
+ safeCaseFiles(legalCase.root),
1006
+ currentDocxManifest(legalCase.root, baselineDocx, { includeText: includeDocx }),
1007
+ ]);
1008
+ try {
1009
+ await runGit(legalCase.root, ['read-tree', '--empty'], { gitDir, workTree: legalCase.root, env });
1010
+ if (files.length) {
1011
+ // Un seul processus Git reçoit les chemins en NUL sur stdin. L'ancien
1012
+ // découpage par groupes de 100 relançait Git 38 fois sur un gros dossier.
1013
+ await runGit(legalCase.root, [
1014
+ 'add', '-f', '--pathspec-from-file=-', '--pathspec-file-nul',
1015
+ ], {
1016
+ gitDir,
1017
+ workTree: legalCase.root,
1018
+ env,
1019
+ // Apple Git stocke les chemins précomposés dans l'index alors qu'APFS
1020
+ // les renvoie souvent décomposés. Les arguments argv étaient convertis
1021
+ // implicitement ; les pathspec lus sur stdin doivent l'être ici.
1022
+ input: Buffer.from(`${files.map((file) => process.platform === 'darwin' ? file.normalize('NFC') : file).join('\0')}\0`, 'utf8'),
1023
+ });
1024
+ }
1025
+ if (includeDocx)
1026
+ await putDocxManifestInIndex(legalCase, gitDir, env, docxManifest);
1027
+ const tree = (await runGit(legalCase.root, ['write-tree'], { gitDir, workTree: legalCase.root, env })).stdout;
1028
+ if (includeDocx)
1029
+ boundedCacheSet(docxTreeCache, `${gitDir}\0${tree}`, docxManifest, 2_000);
1030
+ const snapshot = includeDocx
1031
+ ? tree
1032
+ : crypto.createHash('sha1').update(`${tree}\0${serializeDocxManifest(docxManifest)}`).digest('hex');
1033
+ logPerformance('buildCurrentTree', startedAt, {
1034
+ files: files.length,
1035
+ gitAddBatches: files.length ? 1 : 0,
1036
+ });
1037
+ return { tree, snapshot, files, docxManifest };
1038
+ }
1039
+ finally {
1040
+ try {
1041
+ fs.unlinkSync(temporaryIndex);
1042
+ }
1043
+ catch { }
1044
+ }
1045
+ }
1046
+ /**
1047
+ * Construit un arbre à partir du parent en n'y appliquant que les chemins de
1048
+ * l'opération courante. Les autres modifications présentes dans le work-tree
1049
+ * restent donc locales et ne peuvent pas fuiter dans un commit automatique.
1050
+ */
1051
+ async function buildSelectedTree(legalCase, gitDir, homeDir, parent, selectedPaths) {
1052
+ const startedAt = performance.now();
1053
+ const temporaryIndex = path.join(historyDirectory(homeDir), `index-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
1054
+ const env = { GIT_INDEX_FILE: temporaryIndex };
1055
+ try {
1056
+ await runGit(legalCase.root, ['read-tree', ...(parent ? [parent] : ['--empty'])], {
1057
+ gitDir,
1058
+ workTree: legalCase.root,
1059
+ env,
1060
+ });
1061
+ if (selectedPaths.length) {
1062
+ await runGit(legalCase.root, [
1063
+ 'add', '-f', '-A', '--pathspec-from-file=-', '--pathspec-file-nul',
1064
+ ], {
1065
+ gitDir,
1066
+ workTree: legalCase.root,
1067
+ env,
1068
+ input: Buffer.from(`${selectedPaths.map((file) => process.platform === 'darwin' ? file.normalize('NFC') : file).join('\0')}\0`, 'utf8'),
1069
+ });
1070
+ }
1071
+ const tree = (await runGit(legalCase.root, ['write-tree'], { gitDir, workTree: legalCase.root, env })).stdout;
1072
+ logPerformance('buildSelectedTree', startedAt, { files: selectedPaths.length });
1073
+ return { tree, files: selectedPaths };
1074
+ }
1075
+ finally {
1076
+ try {
1077
+ fs.unlinkSync(temporaryIndex);
1078
+ }
1079
+ catch { }
1080
+ }
1081
+ }
1082
+ async function emptyTree(legalCase, gitDir) {
1083
+ return (await runGit(legalCase.root, ['mktree'], { gitDir, input: '' })).stdout;
1084
+ }
1085
+ function parseNameStatus(raw) {
1086
+ return String(raw || '').split(/\r?\n/).filter(Boolean).map((line) => {
1087
+ const columns = line.split('\t');
1088
+ return { status: columns[0] || 'M', path: columns.at(-1) || '', previousPath: columns.length > 2 ? columns[1] : null };
1089
+ });
1090
+ }
1091
+ function statusKind(code) {
1092
+ const value = String(code || '').trim();
1093
+ if (value.includes('A') || value === '??')
1094
+ return 'added';
1095
+ if (value.includes('D'))
1096
+ return 'deleted';
1097
+ if (value.includes('R'))
1098
+ return 'renamed';
1099
+ return 'modified';
1100
+ }
1101
+ async function diffTrees(legalCase, gitDir, from, to, manifests = null) {
1102
+ const raw = (await runGit(legalCase.root, ['diff-tree', '--no-commit-id', '--name-status', '-r', from, to], { gitDir })).stdout;
1103
+ const parsed = parseNameStatus(raw);
1104
+ const regular = parsed
1105
+ .filter((file) => file.path !== DOCX_MANIFEST_PATH)
1106
+ .map((file) => ({ ...file, kind: statusKind(file.status) }));
1107
+ let wordChanges = [];
1108
+ if (manifests) {
1109
+ wordChanges = docxChanges(manifests.before, manifests.after);
1110
+ }
1111
+ else if (parsed.some((file) => file.path === DOCX_MANIFEST_PATH)) {
1112
+ wordChanges = docxChanges(await treeDocxManifest(legalCase, gitDir, from), await treeDocxManifest(legalCase, gitDir, to));
1113
+ }
1114
+ return [...regular, ...wordChanges].sort((left, right) => left.path.localeCompare(right.path, 'fr'));
1115
+ }
1116
+ async function workingState(casesRoot, homeDir, caseName) {
1117
+ const startedAt = performance.now();
1118
+ const legalCase = resolveCase(casesRoot, caseName);
1119
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1120
+ const latest = await latestCommit(legalCase, gitDir);
1121
+ const base = latest || await emptyTree(legalCase, gitDir);
1122
+ const baselineDocx = latest ? await treeDocxManifest(legalCase, gitDir, base) : emptyDocxManifest();
1123
+ // L'admin compare le manifeste en mémoire. Il n'est écrit dans l'index Git
1124
+ // qu'au commit : aucun processus Git supplémentaire sur le chemin chaud.
1125
+ const current = await buildCurrentTree(legalCase, gitDir, homeDir, baselineDocx, { includeDocx: false });
1126
+ const changes = await diffTrees(legalCase, gitDir, base, current.tree, { before: baselineDocx, after: current.docxManifest });
1127
+ logPerformance('workingState', startedAt, { files: current.files.length, changes: changes.length });
1128
+ const state = { legalCase, gitDir, latest, current, base, baselineDocx, changes };
1129
+ caseStateCache.set(caseStateCacheKey(homeDir, legalCase), state);
1130
+ return state;
1131
+ }
1132
+ /**
1133
+ * Structured git trailers appended at the end of a commit message.
1134
+ *
1135
+ * `PieceMaker-Session` is the durable join key between a case's commits and the
1136
+ * billing ledger (which records the authoritative final duration at session
1137
+ * Stop). `PieceMaker-Temps-Session` is the session time elapsed at the instant
1138
+ * of the commit — so the last commit of a session carries ~its full duration,
1139
+ * and every commit is self-documenting without needing the ledger. Both stay
1140
+ * parseable (`Clé: valeur`) and are read back by `listHistory` via `%b`.
1141
+ */
1142
+ function buildCommitTrailers({ sessionId, durationMs }) {
1143
+ const trailers = [];
1144
+ const session = String(sessionId || '').replace(/[\x00-\x1f\x7f]/g, '').trim().slice(0, 120);
1145
+ if (session)
1146
+ trailers.push(`PieceMaker-Session: ${session}`);
1147
+ if (Number.isFinite(durationMs) && durationMs >= 0) {
1148
+ const human = formatDurationFr(durationMs);
1149
+ if (human)
1150
+ trailers.push(`PieceMaker-Temps-Session: ${human} (${Math.round(durationMs)} ms)`);
1151
+ }
1152
+ return trailers;
1153
+ }
1154
+ async function createCommit({ casesRoot, caseName, homeDir = path.join(os.homedir(), '.piecemaker'), label = 'Commit PieceMaker', description = '', sessionId = null, durationMs = null, event = 'manual', paths = null, waitForLockMs = 0, identity = null, envFile = GLOBAL_ENV_FILE, } = {}) {
1155
+ const legalCase = resolveCase(casesRoot, caseName);
1156
+ caseStateCache.delete(caseStateCacheKey(homeDir, legalCase));
1157
+ const safeLabel = String(label || 'Commit PieceMaker').replace(/[\r\n]+/g, ' ').trim().slice(0, 140);
1158
+ const safeDescription = String(description || '').replaceAll('\0', '').replaceAll('\r\n', '\n').trim().slice(0, 4000);
1159
+ const selectedPaths = paths == null
1160
+ ? null
1161
+ : [...new Set((Array.isArray(paths) ? paths : [paths]).map((file) => validateRelativeSafePath(legalCase, file)))];
1162
+ return withCaseLock(homeDir, legalCase, async () => {
1163
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1164
+ const parent = await latestCommit(legalCase, gitDir);
1165
+ const parentTree = parent
1166
+ ? (await runGit(legalCase.root, ['rev-parse', `${parent}^{tree}`], { gitDir })).stdout
1167
+ : await emptyTree(legalCase, gitDir);
1168
+ const baselineDocx = selectedPaths === null && parent
1169
+ ? await treeDocxManifest(legalCase, gitDir, parentTree)
1170
+ : emptyDocxManifest();
1171
+ const current = selectedPaths === null
1172
+ ? await buildCurrentTree(legalCase, gitDir, homeDir, baselineDocx)
1173
+ : await buildSelectedTree(legalCase, gitDir, homeDir, parent, selectedPaths);
1174
+ if (current.tree === parentTree) {
1175
+ return { created: false, commit: parent || null, caseName: legalCase.name, files: [] };
1176
+ }
1177
+ const timestamp = new Date().toISOString();
1178
+ const trailers = buildCommitTrailers({ sessionId, durationMs });
1179
+ const message = `${safeLabel || 'Commit PieceMaker'}\n${safeDescription ? `\n${safeDescription}\n` : ''}${trailers.length ? `\n${trailers.join('\n')}\n` : ''}`;
1180
+ const commitIdentity = resolveCommitIdentity({ identity, envFile });
1181
+ const gitIdentity = {
1182
+ GIT_AUTHOR_NAME: commitIdentity.name,
1183
+ GIT_AUTHOR_EMAIL: commitIdentity.email,
1184
+ GIT_COMMITTER_NAME: commitIdentity.name,
1185
+ GIT_COMMITTER_EMAIL: commitIdentity.email,
1186
+ GIT_AUTHOR_DATE: timestamp,
1187
+ GIT_COMMITTER_DATE: timestamp,
1188
+ };
1189
+ const args = ['commit-tree', current.tree, ...(parent ? ['-p', parent] : [])];
1190
+ const commit = (await runGit(legalCase.root, args, { gitDir, env: gitIdentity, input: message })).stdout;
1191
+ await runGit(legalCase.root, ['update-ref', await activeHistoryRef(legalCase, gitDir), commit, ...(parent ? [parent] : [])], { gitDir });
1192
+ const files = await diffTrees(legalCase, gitDir, parentTree, current.tree, selectedPaths === null ? { before: baselineDocx, after: current.docxManifest } : null);
1193
+ return {
1194
+ created: true,
1195
+ commit,
1196
+ parent: parent || null,
1197
+ timestamp,
1198
+ label: safeLabel || 'Commit PieceMaker',
1199
+ sessionId,
1200
+ durationMs: Number.isFinite(durationMs) && durationMs >= 0 ? durationMs : null,
1201
+ event,
1202
+ author: commitIdentity.name,
1203
+ caseName: legalCase.name,
1204
+ files,
1205
+ };
1206
+ }, { waitMs: waitForLockMs });
1207
+ }
1208
+ function parseLog(raw) {
1209
+ return String(raw || '').split('\x1e').map((record) => record.trim()).filter(Boolean).map((record) => {
1210
+ const [hash, shortHash, author, timestamp, subject, ...body] = record.split('\x1f');
1211
+ return {
1212
+ hash,
1213
+ shortHash,
1214
+ author,
1215
+ timestamp,
1216
+ subject,
1217
+ body: body.join('\x1f').trim(),
1218
+ kind: 'commit',
1219
+ };
1220
+ }).filter((entry) => entry.hash);
1221
+ }
1222
+ async function listHistory(casesRoot, homeDir, { caseName, limit = 120 } = {}) {
1223
+ const startedAt = performance.now();
1224
+ const legalCase = resolveCase(casesRoot, caseName);
1225
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1226
+ if (!await latestCommit(legalCase, gitDir)) {
1227
+ logPerformance('listHistory', startedAt, { commits: 0 });
1228
+ return [];
1229
+ }
1230
+ const safeLimit = Math.min(Math.max(Number(limit) || 120, 1), 250);
1231
+ const historyRef = await activeHistoryRef(legalCase, gitDir);
1232
+ const raw = (await runGit(legalCase.root, [
1233
+ 'log', `--max-count=${safeLimit}`, '--date=iso-strict',
1234
+ '--pretty=format:%x1e%H%x1f%h%x1f%an%x1f%aI%x1f%s%x1f%b', historyRef,
1235
+ ], { gitDir })).stdout;
1236
+ const history = parseLog(raw);
1237
+ logPerformance('listHistory', startedAt, { commits: history.length, limit: safeLimit });
1238
+ return history;
1239
+ }
1240
+ /**
1241
+ * Les mois `YYYY-MM` où le dossier a des commits, du plus récent au plus
1242
+ * ancien — alimente le menu déroulant de l'export mensuel. Une seule colonne
1243
+ * (`%aI`) suffit : dériver le mois ne demande que les 7 premiers caractères
1244
+ * d'une date ISO stricte, pas un `git log` structuré comme `listHistory`.
1245
+ */
1246
+ async function historyMonths(casesRoot, homeDir, { caseName } = {}) {
1247
+ const startedAt = performance.now();
1248
+ const legalCase = resolveCase(casesRoot, caseName);
1249
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1250
+ if (!await latestCommit(legalCase, gitDir)) {
1251
+ logPerformance('historyMonths', startedAt, { months: 0 });
1252
+ return [];
1253
+ }
1254
+ const historyRef = await activeHistoryRef(legalCase, gitDir);
1255
+ const raw = (await runGit(legalCase.root, ['log', '--date=iso-strict', '--pretty=format:%aI', historyRef], { gitDir })).stdout;
1256
+ const months = [...new Set(raw.split('\n').map((line) => line.trim().slice(0, 7)).filter(Boolean))].sort((left, right) => right.localeCompare(left));
1257
+ logPerformance('historyMonths', startedAt, { months: months.length });
1258
+ return months;
1259
+ }
1260
+ /**
1261
+ * Variante de `parseLog` avec la liste des fichiers touchés par chaque
1262
+ * commit. Le format ajoute un `%x1f` terminal après le corps (`%b`) : ce
1263
+ * séparateur referme le champ « corps », multi-ligne, sans ambiguïté avec la
1264
+ * liste de fichiers de `--name-only` qui le suit jusqu'au `\x1e` du commit
1265
+ * suivant. `parseLog` reste inchangé pour `listHistory` (son format n'a pas
1266
+ * ce dernier séparateur).
1267
+ */
1268
+ function parseLogWithFiles(raw) {
1269
+ return String(raw || '').split('\x1e').map((record) => record.trim()).filter(Boolean).map((record) => {
1270
+ const fields = record.split('\x1f');
1271
+ const [hash, shortHash, author, timestamp, subject] = fields;
1272
+ // Entre le 5e séparateur et le dernier se trouve le corps (`%b`), qui ne
1273
+ // devrait jamais contenir de \x1f mais est rejoint par défense, comme le
1274
+ // fait déjà `parseLog` ; le tout dernier segment est la liste des
1275
+ // fichiers, un par ligne.
1276
+ const body = fields.slice(5, -1).join('\x1f').trim();
1277
+ const files = String(fields.at(-1) || '').split('\n').map((line) => line.trim()).filter(Boolean);
1278
+ return {
1279
+ hash,
1280
+ shortHash,
1281
+ author,
1282
+ timestamp,
1283
+ subject,
1284
+ body,
1285
+ kind: 'commit',
1286
+ files,
1287
+ filesCount: files.length,
1288
+ };
1289
+ }).filter((entry) => entry.hash);
1290
+ }
1291
+ /**
1292
+ * Sépare les trailers techniques `PieceMaker-*` du corps d'un commit (voir
1293
+ * `buildCommitTrailers`). Miroir du parsing côté client
1294
+ * (`admin/app.js` → `parsePieceMakerTrailers`), avec en plus la durée brute
1295
+ * en millisecondes que l'affichage seul n'a pas besoin de connaître mais
1296
+ * qu'un export chiffré (temps facturable par mois) exploite directement.
1297
+ */
1298
+ function parseCommitTrailers(body) {
1299
+ const lines = String(body || '').split('\n');
1300
+ const kept = [];
1301
+ let sessionId = null;
1302
+ let durationMs = null;
1303
+ for (const line of lines) {
1304
+ const session = line.match(/^PieceMaker-Session:\s*(.+)$/);
1305
+ if (session) {
1306
+ sessionId = session[1].trim();
1307
+ continue;
1308
+ }
1309
+ const time = line.match(/^PieceMaker-Temps-Session:\s*.+?\((\d+)\s*ms\)\s*$/);
1310
+ if (time) {
1311
+ durationMs = Number(time[1]);
1312
+ continue;
1313
+ }
1314
+ kept.push(line);
1315
+ }
1316
+ return { comment: kept.join('\n').trim(), sessionId, durationMs };
1317
+ }
1318
+ /**
1319
+ * Commits d'une période `[since, until)`, fichiers touchés compris. `until`
1320
+ * est exclusif côté appelant (premier jour du mois suivant, typiquement) :
1321
+ * cette fonction ne fait aucune arithmétique de date, elle transmet telles
1322
+ * quelles à `--since`/`--until`. Pas de plafond façon `listHistory` — le hook
1323
+ * `PostToolUse` commite à chaque Write/Edit, un mois peut en compter des
1324
+ * milliers — seulement un plafond de sécurité large pour ne pas exploser
1325
+ * `MAX_GIT_BUFFER` sur un dossier anormalement actif.
1326
+ */
1327
+ async function listHistoryPeriod(casesRoot, homeDir, { caseName, since, until } = {}) {
1328
+ const startedAt = performance.now();
1329
+ const legalCase = resolveCase(casesRoot, caseName);
1330
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1331
+ if (!await latestCommit(legalCase, gitDir)) {
1332
+ logPerformance('listHistoryPeriod', startedAt, { commits: 0 });
1333
+ return [];
1334
+ }
1335
+ const historyRef = await activeHistoryRef(legalCase, gitDir);
1336
+ const raw = (await runGit(legalCase.root, [
1337
+ 'log', `--max-count=${MAX_HISTORY_PERIOD_COMMITS}`, '--date=iso-strict', '--name-only',
1338
+ ...(since ? [`--since=${since}`] : []),
1339
+ ...(until ? [`--until=${until}`] : []),
1340
+ '--pretty=format:%x1e%H%x1f%h%x1f%an%x1f%aI%x1f%s%x1f%b%x1f', historyRef,
1341
+ ], { gitDir })).stdout;
1342
+ const history = parseLogWithFiles(raw).map((entry) => {
1343
+ const { comment, sessionId, durationMs } = parseCommitTrailers(entry.body);
1344
+ return { ...entry, comment, sessionId, durationMs };
1345
+ });
1346
+ logPerformance('listHistoryPeriod', startedAt, { commits: history.length, since, until });
1347
+ return history;
1348
+ }
1349
+ function normalizeRelativeHistoryPath(relativePath) {
1350
+ const normalized = String(relativePath || '').replaceAll('\\', '/').replace(/^\.\//, '');
1351
+ if (!normalized || path.posix.isAbsolute(normalized) || normalized.split('/').includes('..')) {
1352
+ throw new Error('Chemin de fichier invalide.');
1353
+ }
1354
+ return normalized;
1355
+ }
1356
+ function validateRelativeSafePath(legalCase, relativePath) {
1357
+ const normalized = normalizeRelativeHistoryPath(relativePath);
1358
+ const absolute = path.join(legalCase.root, ...normalized.split('/'));
1359
+ if (isProtectedFile(absolute, legalCase.root) || !SAFE_EXTENSIONS.has(path.extname(normalized).toLowerCase())) {
1360
+ throw new Error('Ce fichier n’est pas accessible à l’IA.');
1361
+ }
1362
+ return normalized;
1363
+ }
1364
+ function validateRelativeHistoryPath(legalCase, relativePath) {
1365
+ const normalized = normalizeRelativeHistoryPath(relativePath);
1366
+ return isDocxPath(normalized) ? normalized : validateRelativeSafePath(legalCase, normalized);
1367
+ }
1368
+ async function revisionMetadata(legalCase, gitDir, hash) {
1369
+ if (!/^[0-9a-f]{7,64}$/i.test(String(hash || '')))
1370
+ throw new Error('Identifiant de révision invalide.');
1371
+ const commit = (await runGit(legalCase.root, ['rev-parse', '--verify', `${hash}^{commit}`], { gitDir })).stdout;
1372
+ if ((await runGit(legalCase.root, ['merge-base', '--is-ancestor', commit, await activeHistoryRef(legalCase, gitDir)], { gitDir, allowFailure: true })).code !== 0) {
1373
+ throw new Error('Cette révision ne fait pas partie de ce dossier juridique.');
1374
+ }
1375
+ const raw = (await runGit(legalCase.root, ['show', '-s', '--date=iso-strict', '--format=%H%x1f%h%x1f%an%x1f%aI%x1f%s%x1f%b', commit], { gitDir })).stdout;
1376
+ const [fullHash, shortHash, author, timestamp, subject, ...body] = raw.split('\x1f');
1377
+ return { commit, hash: fullHash, shortHash, author, timestamp, subject, body: body.join('\x1f').trim() };
1378
+ }
1379
+ function parseShortStat(raw) {
1380
+ const value = String(raw || '');
1381
+ return {
1382
+ files: Number(value.match(/(\d+) files? changed/)?.[1] || 0),
1383
+ added: Number(value.match(/(\d+) insertions?\(\+\)/)?.[1] || 0),
1384
+ deleted: Number(value.match(/(\d+) deletions?\(-\)/)?.[1] || 0),
1385
+ };
1386
+ }
1387
+ async function revisionDetails(casesRoot, homeDir, caseName, hash, filePath = '') {
1388
+ const startedAt = performance.now();
1389
+ const legalCase = resolveCase(casesRoot, caseName);
1390
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1391
+ const meta = await revisionMetadata(legalCase, gitDir, hash);
1392
+ const commitTree = (await runGit(legalCase.root, ['rev-parse', `${meta.commit}^{tree}`], { gitDir })).stdout;
1393
+ const parent = await runGit(legalCase.root, ['rev-parse', '--verify', `${meta.commit}^`], { gitDir, allowFailure: true });
1394
+ const parentTree = parent.code === 0
1395
+ ? (await runGit(legalCase.root, ['rev-parse', `${parent.stdout}^{tree}`], { gitDir })).stdout
1396
+ : await emptyTree(legalCase, gitDir);
1397
+ const files = await diffTrees(legalCase, gitDir, parentTree, commitTree);
1398
+ const selectedPath = filePath ? validateRelativeHistoryPath(legalCase, filePath) : '';
1399
+ const selectedFile = selectedPath ? files.find((file) => file.path === selectedPath) : null;
1400
+ if (selectedPath && !selectedFile)
1401
+ throw new Error('Ce fichier ne fait pas partie de cette révision.');
1402
+ // Sur un commit complet, Git doit parcourir tous les blobs une deuxième fois
1403
+ // pour produire le shortstat. Le patch contient déjà l'information utile et
1404
+ // est borné ci-dessous : ne calculer les statistiques que pour un fichier
1405
+ // explicitement sélectionné évite ce parcours redondant.
1406
+ const wordDiff = isDocxPath(selectedPath)
1407
+ ? await docxTextDiff(legalCase, await treeDocxManifest(legalCase, gitDir, parentTree), await treeDocxManifest(legalCase, gitDir, commitTree), selectedPath)
1408
+ : null;
1409
+ const stats = wordDiff?.stats || (selectedPath
1410
+ ? parseShortStat((await runGit(legalCase.root, [
1411
+ 'diff-tree', '--root', '--no-commit-id', '--shortstat', '-r', meta.commit, '--', selectedPath,
1412
+ ], { gitDir })).stdout)
1413
+ : { files: 0, added: 0, deleted: 0 });
1414
+ // Le premier clic sur un commit ne calcule que sa liste de fichiers. Le
1415
+ // patch, potentiellement volumineux, n'est demandé qu'après sélection d'un
1416
+ // fichier dans la colonne dédiée.
1417
+ const patchResult = wordDiff || (selectedPath
1418
+ ? await runGit(legalCase.root, [
1419
+ 'show', '--format=', '--no-ext-diff', '--unified=3', meta.commit, '--', selectedPath,
1420
+ ], {
1421
+ gitDir,
1422
+ maxOutputBytes: MAX_PATCH_BYTES,
1423
+ truncateOutput: true,
1424
+ })
1425
+ : { stdout: '', truncated: false });
1426
+ const result = {
1427
+ ...meta,
1428
+ kind: 'commit',
1429
+ files,
1430
+ filesCount: files.length,
1431
+ stats,
1432
+ selectedFile,
1433
+ selectedPath,
1434
+ patch: patchResult.stdout,
1435
+ truncated: patchResult.truncated,
1436
+ };
1437
+ logPerformance('revisionDetails', startedAt, {
1438
+ files: result.filesCount,
1439
+ selectedFile: Boolean(selectedPath),
1440
+ patchBytes: Buffer.byteLength(result.patch, 'utf8'),
1441
+ truncated: result.truncated,
1442
+ });
1443
+ return result;
1444
+ }
1445
+ async function worktreeDetails(casesRoot, homeDir, caseName, filePath = '', snapshot = '') {
1446
+ const startedAt = performance.now();
1447
+ const legalCase = resolveCase(casesRoot, caseName);
1448
+ const cached = caseStateCache.get(caseStateCacheKey(homeDir, legalCase));
1449
+ const state = snapshot && cached?.current.snapshot === snapshot
1450
+ ? cached
1451
+ : await workingState(casesRoot, homeDir, caseName);
1452
+ const selectedPath = filePath ? validateRelativeHistoryPath(state.legalCase, filePath) : '';
1453
+ if (selectedPath && !state.changes.some((file) => file.path === selectedPath)) {
1454
+ throw new Error('Ce fichier ne fait pas partie des modifications actuelles.');
1455
+ }
1456
+ const selectedFile = selectedPath ? state.changes.find((file) => file.path === selectedPath) : null;
1457
+ const wordDiff = isDocxPath(selectedPath)
1458
+ ? await docxTextDiff(state.legalCase, state.baselineDocx, state.current.docxManifest, selectedPath)
1459
+ : null;
1460
+ const statsRaw = wordDiff || !selectedPath ? '' : (await runGit(state.legalCase.root, [
1461
+ 'diff', '--shortstat', state.base, state.current.tree, '--', selectedPath,
1462
+ ], { gitDir: state.gitDir })).stdout;
1463
+ const stats = wordDiff?.stats || parseShortStat(statsRaw);
1464
+ const patchResult = wordDiff || (!selectedPath
1465
+ ? { stdout: '', truncated: false }
1466
+ : await runGit(state.legalCase.root, [
1467
+ 'diff', '--no-ext-diff', '--unified=3', state.base, state.current.tree, '--', selectedPath,
1468
+ ], {
1469
+ gitDir: state.gitDir,
1470
+ maxOutputBytes: MAX_PATCH_BYTES,
1471
+ truncateOutput: true,
1472
+ }));
1473
+ const result = {
1474
+ hash: 'WORKTREE',
1475
+ shortHash: '',
1476
+ author: 'Modifications locales',
1477
+ timestamp: new Date().toISOString(),
1478
+ subject: 'Modifications depuis le dernier commit',
1479
+ kind: 'worktree',
1480
+ files: state.changes,
1481
+ filesCount: state.changes.length,
1482
+ stats,
1483
+ selectedFile,
1484
+ selectedPath,
1485
+ patch: patchResult.stdout,
1486
+ truncated: patchResult.truncated,
1487
+ };
1488
+ logPerformance('worktreeDetails', startedAt, {
1489
+ files: state.changes.length,
1490
+ selectedFile: Boolean(selectedPath),
1491
+ patchBytes: Buffer.byteLength(result.patch, 'utf8'),
1492
+ truncated: result.truncated,
1493
+ });
1494
+ return result;
1495
+ }
1496
+ function listCases(casesRoot) {
1497
+ const requestedRoot = path.resolve(String(casesRoot || ''));
1498
+ if (!fs.existsSync(requestedRoot)) {
1499
+ return { name: 'PieceMaker', root: requestedRoot, branch: 'Dossiers indépendants', head: '', shortHead: '', folders: [], changes: [] };
1500
+ }
1501
+ const root = resolveCasesRoot(requestedRoot);
1502
+ const entries = fs.readdirSync(root, { withFileTypes: true })
1503
+ .filter((entry) => entry.isDirectory()
1504
+ && !entry.isSymbolicLink()
1505
+ && !entry.name.startsWith('.')
1506
+ && !isTechnicalCaseDirectoryName(entry.name))
1507
+ .sort((a, b) => a.name.localeCompare(b.name, 'fr'));
1508
+ return {
1509
+ name: path.basename(root),
1510
+ root,
1511
+ branch: 'Dossiers indépendants',
1512
+ head: '',
1513
+ shortHead: '',
1514
+ folders: entries.map((entry) => ({ name: entry.name, path: entry.name })),
1515
+ changes: [],
1516
+ };
1517
+ }
1518
+ async function caseOverview(casesRoot, homeDir, caseName) {
1519
+ const startedAt = performance.now();
1520
+ const state = await workingState(casesRoot, homeDir, caseName);
1521
+ const originals = await originalFilesOverview(state.legalCase.root, { safeFiles: state.current.files });
1522
+ const enrichedChanges = await Promise.all(state.changes.map(async (change) => {
1523
+ if (change.kind === 'deleted')
1524
+ return change;
1525
+ try {
1526
+ const stat = await fsp.stat(path.join(state.legalCase.root, ...change.path.split('/')));
1527
+ return { ...change, modifiedAt: stat.mtime.toISOString() };
1528
+ }
1529
+ catch {
1530
+ return change;
1531
+ }
1532
+ }));
1533
+ const folder = {
1534
+ name: state.legalCase.name,
1535
+ path: state.legalCase.name,
1536
+ changes: enrichedChanges.length,
1537
+ workingChanges: enrichedChanges,
1538
+ head: state.latest,
1539
+ shortHead: state.latest.slice(0, 7),
1540
+ snapshot: state.current.snapshot,
1541
+ originals,
1542
+ protectedOriginals: originals.filter((file) => file.protected).length,
1543
+ };
1544
+ logPerformance('caseOverview', startedAt, {
1545
+ files: state.current.files.length,
1546
+ changes: state.changes.length,
1547
+ originals: originals.length,
1548
+ });
1549
+ return folder;
1550
+ }
1551
+ async function repositoryOverview(casesRoot, homeDir = path.join(os.homedir(), '.piecemaker')) {
1552
+ const startedAt = performance.now();
1553
+ const repository = listCases(casesRoot);
1554
+ if (!repository.folders.length) {
1555
+ logPerformance('repositoryOverview', startedAt, { folders: 0 });
1556
+ return repository;
1557
+ }
1558
+ // Séquentiel : chaque dossier lance déjà une série de processus git, les
1559
+ // paralléliser en ferait exploser le nombre sur un poste de travail.
1560
+ const folders = [];
1561
+ for (const entry of repository.folders) {
1562
+ folders.push(await caseOverview(repository.root, homeDir, entry.name));
1563
+ }
1564
+ const result = { ...repository, folders };
1565
+ logPerformance('repositoryOverview', startedAt, {
1566
+ folders: folders.length,
1567
+ workingChanges: folders.reduce((count, folder) => count + folder.workingChanges.length, 0),
1568
+ originals: folders.reduce((count, folder) => count + folder.originals.length, 0),
1569
+ });
1570
+ return result;
1571
+ }
1572
+ function safeDestination(legalCase, relativePath) {
1573
+ const normalized = validateRelativeSafePath(legalCase, relativePath);
1574
+ let current = legalCase.root;
1575
+ const parts = normalized.split('/');
1576
+ for (const part of parts.slice(0, -1)) {
1577
+ current = path.join(current, part);
1578
+ if (fs.existsSync(current) && fs.lstatSync(current).isSymbolicLink())
1579
+ throw new Error('Restauration refusée à travers un lien symbolique.');
1580
+ }
1581
+ return { normalized, absolute: path.join(legalCase.root, ...parts) };
1582
+ }
1583
+ async function restoreRevision({ casesRoot, caseName, homeDir = path.join(os.homedir(), '.piecemaker'), hash } = {}) {
1584
+ const legalCase = resolveCase(casesRoot, caseName);
1585
+ const gitDir = await ensureHistoryRepo(homeDir, legalCase);
1586
+ const meta = await revisionMetadata(legalCase, gitDir, hash);
1587
+ const safety = await createCommit({
1588
+ casesRoot: legalCase.casesRoot,
1589
+ caseName: legalCase.name,
1590
+ homeDir,
1591
+ label: `Sauvegarde avant restauration de ${meta.shortHash}`,
1592
+ event: 'before-restore',
1593
+ });
1594
+ if (safety.skipped === 'busy')
1595
+ throw new Error('Un commit est déjà en cours. Réessayez dans quelques secondes.');
1596
+ const targetFiles = (await runGit(legalCase.root, ['ls-tree', '-r', '--name-only', meta.commit], { gitDir })).stdout
1597
+ .split(/\r?\n/)
1598
+ .filter((relative) => relative && relative !== DOCX_MANIFEST_PATH);
1599
+ const targetSet = new Set(targetFiles);
1600
+ for (const relative of await safeCaseFiles(legalCase.root)) {
1601
+ if (!targetSet.has(relative))
1602
+ fs.unlinkSync(safeDestination(legalCase, relative).absolute);
1603
+ }
1604
+ for (const relative of targetFiles) {
1605
+ const destination = safeDestination(legalCase, relative);
1606
+ fs.mkdirSync(path.dirname(destination.absolute), { recursive: true });
1607
+ const content = (await runGit(legalCase.root, ['show', `${meta.commit}:${destination.normalized}`], { gitDir, encoding: null })).stdout;
1608
+ const temporary = `${destination.absolute}.piecemaker-${process.pid}.tmp`;
1609
+ fs.writeFileSync(temporary, content);
1610
+ fs.renameSync(temporary, destination.absolute);
1611
+ }
1612
+ const restoredState = await createCommit({
1613
+ casesRoot: legalCase.casesRoot,
1614
+ caseName: legalCase.name,
1615
+ homeDir,
1616
+ label: `Restauration de ${meta.shortHash} · ${meta.subject}`,
1617
+ event: 'restore',
1618
+ });
1619
+ return {
1620
+ restored: true,
1621
+ revision: meta.commit,
1622
+ safetyCommit: safety.commit || null,
1623
+ restorationCommit: restoredState.commit || null,
1624
+ changes: (await workingState(legalCase.casesRoot, homeDir, legalCase.name)).changes,
1625
+ originalsPreserved: true,
1626
+ };
1627
+ }
1628
+ module.exports = {
1629
+ COMMIT_USER_NAME_KEY,
1630
+ GLOBAL_ENV_FILE,
1631
+ IDENTITY_CONFIG_FILE,
1632
+ SAFE_EXTENSIONS,
1633
+ readCommitIdentityConfig,
1634
+ caseOverview,
1635
+ checkoutHistoryBranch,
1636
+ createCommit,
1637
+ createHistoryBranch,
1638
+ historyBranches,
1639
+ historyMonths,
1640
+ historyRepo,
1641
+ isProtectedFile,
1642
+ isTechnicalCaseDirectoryName,
1643
+ listCases,
1644
+ logPerformance,
1645
+ listHistory,
1646
+ listHistoryPeriod,
1647
+ locateCaseFile,
1648
+ parseCommitTrailers,
1649
+ originalFilesOverview,
1650
+ repositoryOverview,
1651
+ resolveCommitIdentity,
1652
+ resolveCase,
1653
+ resolveCasesRoot,
1654
+ restoreRevision,
1655
+ revisionDetails,
1656
+ runGit,
1657
+ safeCaseFiles,
1658
+ worktreeDetails,
1659
+ };
1660
+ //# sourceMappingURL=commits.cjs.map