@piecemaker-legal/piecemaker 1.0.6 → 1.0.7

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 (209) hide show
  1. package/dist/assets/{abnfDiagram-VCTEODGH-DF7LFtT-.js → abnfDiagram-VCTEODGH-CR3_ADBu.js} +1 -1
  2. package/dist/assets/{arc-xOmjWeVH.js → arc-b92imMmc.js} +1 -1
  3. package/dist/assets/{architectureDiagram-5GKGNRK7-CESzNPwa.js → architectureDiagram-5GKGNRK7-Dfm5Epud.js} +1 -1
  4. package/dist/assets/{blockDiagram-I7D4REHJ-BjdN78Ad.js → blockDiagram-I7D4REHJ-B8kLLyAv.js} +1 -1
  5. package/dist/assets/{c4Diagram-7LVT6UL2-BcK9EDWT.js → c4Diagram-7LVT6UL2-BWSyAAWX.js} +1 -1
  6. package/dist/assets/channel-BbcW_Tkh.js +1 -0
  7. package/dist/assets/{chunk-2Q5K7J3B-DGUN1JFP.js → chunk-2Q5K7J3B-Ci743mcC.js} +1 -1
  8. package/dist/assets/{chunk-5VM5RSS4-BG3BBcFr.js → chunk-5VM5RSS4-SdXpal6h.js} +1 -1
  9. package/dist/assets/{chunk-F27PBJKO-CLIOfrF5.js → chunk-F27PBJKO-Rof94ueX.js} +1 -1
  10. package/dist/assets/{chunk-IMKFNOWR-D6lGkqij.js → chunk-IMKFNOWR-B3st6ECc.js} +1 -1
  11. package/dist/assets/{chunk-JWPE2WC7-BmF9vLBT.js → chunk-JWPE2WC7-alXmu5xU.js} +1 -1
  12. package/dist/assets/{chunk-POPQ4Y6H-C_0SR3ak.js → chunk-POPQ4Y6H-dMs1OCce.js} +1 -1
  13. package/dist/assets/{chunk-SVP7TREG-rT20Wfpp.js → chunk-SVP7TREG-BmM8FsmF.js} +1 -1
  14. package/dist/assets/{chunk-TICWLB2K-Cn2hkmcf.js → chunk-TICWLB2K-CL1LytYG.js} +1 -1
  15. package/dist/assets/{chunk-XXDRQBXY-Dm_eP1_v.js → chunk-XXDRQBXY-7U9iRPT1.js} +1 -1
  16. package/dist/assets/classDiagram-ZZMXUADV-D9_YRZ7i.js +1 -0
  17. package/dist/assets/classDiagram-v2-VYDZK3BY-D9_YRZ7i.js +1 -0
  18. package/dist/assets/{cose-bilkent-JH36ORCC-cJeeJsep.js → cose-bilkent-JH36ORCC-DFOMlhj2.js} +1 -1
  19. package/dist/assets/{cynefin-OW5HDTMX-DX2ePIXe.js → cynefin-OW5HDTMX-CDdJFd9d.js} +1 -1
  20. package/dist/assets/{cynefinDiagram-5FMLGOSQ-BvWXN-RR.js → cynefinDiagram-5FMLGOSQ-DPyVNrMW.js} +1 -1
  21. package/dist/assets/{dagre-GXQ25YYZ-CkwPRhGR.js → dagre-GXQ25YYZ-B3bpHa9D.js} +1 -1
  22. package/dist/assets/{diagram-S7CK7UJ4-CBGNzYyv.js → diagram-S7CK7UJ4-DeFO2rXB.js} +1 -1
  23. package/dist/assets/{diagram-UQ7AKVKN-CiwCU0SJ.js → diagram-UQ7AKVKN-CbdGTOVf.js} +1 -1
  24. package/dist/assets/{diagram-VSXAHHWV-Aekg4nTk.js → diagram-VSXAHHWV-DFfNQyMd.js} +1 -1
  25. package/dist/assets/{diagram-VX7I27RA-DPFP5K7r.js → diagram-VX7I27RA-DbNZ6_X3.js} +1 -1
  26. package/dist/assets/{diagram-Z3DM3KII-BHJkxoey.js → diagram-Z3DM3KII-B8F-ZkNJ.js} +1 -1
  27. package/dist/assets/{ebnfDiagram-PWID7BFC-2rV1P32T.js → ebnfDiagram-PWID7BFC-BfCCPPAP.js} +1 -1
  28. package/dist/assets/{erDiagram-RLTQ6QDP-C4BjyS_H.js → erDiagram-RLTQ6QDP-DcV-3Kzv.js} +1 -1
  29. package/dist/assets/{flowDiagram-HODETNUW-DL1TBlAG.js → flowDiagram-HODETNUW-BwSkJXCo.js} +1 -1
  30. package/dist/assets/{ganttDiagram-EL5Y4UJY-MKjvzCWz.js → ganttDiagram-EL5Y4UJY-BffHk77T.js} +1 -1
  31. package/dist/assets/{gitGraphDiagram-WWUBYQGX-CS_oTGK5.js → gitGraphDiagram-WWUBYQGX-CQ1EWa74.js} +1 -1
  32. package/dist/assets/{index-XOGQDqU3.js → index-BqK33gaZ.js} +120 -120
  33. package/dist/assets/index-D_Dc_nQv.css +1 -0
  34. package/dist/assets/{infoDiagram-27XIBGKW-ihUr2GjN.js → infoDiagram-27XIBGKW-DqIaBXQn.js} +1 -1
  35. package/dist/assets/{ishikawaDiagram-5VMMS53U-D2YAnuir.js → ishikawaDiagram-5VMMS53U-HlhsaZgv.js} +1 -1
  36. package/dist/assets/{journeyDiagram-3NMN7TZE-Bc2hSZGD.js → journeyDiagram-3NMN7TZE-BYO8-7rN.js} +1 -1
  37. package/dist/assets/{kanban-definition-UXKFOSKX-LRMGNonX.js → kanban-definition-UXKFOSKX-DXb8zHGT.js} +1 -1
  38. package/dist/assets/{layout-CcfWOlPV.js → layout-CREOVuEZ.js} +1 -1
  39. package/dist/assets/{linear-7JoS2gQO.js → linear-CVCrIRIY.js} +1 -1
  40. package/dist/assets/{mermaid.core-ijh_SsuN.js → mermaid.core-DFqeWtQR.js} +6 -6
  41. package/dist/assets/{mindmap-definition-YA3MSWOX-DCE4nzfF.js → mindmap-definition-YA3MSWOX-SUpXz333.js} +1 -1
  42. package/dist/assets/{pegDiagram-XKGWAZYB-SjaGa7lE.js → pegDiagram-XKGWAZYB-D-yWpve3.js} +1 -1
  43. package/dist/assets/{pieDiagram-E7YTZNPT-1xcRidSZ.js → pieDiagram-E7YTZNPT-BJX4Zp4Z.js} +1 -1
  44. package/dist/assets/{quadrantDiagram-AXDQQJYC-obHAHnYV.js → quadrantDiagram-AXDQQJYC-CHajheTu.js} +1 -1
  45. package/dist/assets/{railroadDiagram-O6MQD6OU-BsCVcRZb.js → railroadDiagram-O6MQD6OU-DHJWzW5A.js} +1 -1
  46. package/dist/assets/{requirementDiagram-BXWQKSXE-CUNkhvqb.js → requirementDiagram-BXWQKSXE-DigUIdso.js} +1 -1
  47. package/dist/assets/{sankeyDiagram-P5KCCOFB-DhezXMKm.js → sankeyDiagram-P5KCCOFB-CFUDDbA5.js} +1 -1
  48. package/dist/assets/{sequenceDiagram-WJ2MYXX4-CL9VswXH.js → sequenceDiagram-WJ2MYXX4-6tSaXfYD.js} +1 -1
  49. package/dist/assets/{sizeCapture-INFHLROL-t0g9jiEz.js → sizeCapture-INFHLROL-CXASEDKe.js} +1 -1
  50. package/dist/assets/{stateDiagram-D77RDMKH-BW-g-IOz.js → stateDiagram-D77RDMKH-DWTCAQfZ.js} +1 -1
  51. package/dist/assets/stateDiagram-v2-MP3YSRHH-HDQF4MGA.js +1 -0
  52. package/dist/assets/{swimlanes-42K2YHIH-LsuyeBte.js → swimlanes-42K2YHIH-7-oz5r-e.js} +1 -1
  53. package/dist/assets/swimlanesDiagram-VR7AAH4N-CJbgQFt8.js +8 -0
  54. package/dist/assets/{timeline-definition-24CTP7MA-B0cFka1R.js → timeline-definition-24CTP7MA-DVH5g4ty.js} +1 -1
  55. package/dist/assets/{vendor-codemirror-C5qqu4R7.js → vendor-codemirror-CjW0lHR5.js} +5 -5
  56. package/dist/assets/{vennDiagram-4TSXK5OY-D3HNCDR3.js → vennDiagram-4TSXK5OY-CQvY_ALZ.js} +1 -1
  57. package/dist/assets/{wardleyDiagram-VM6X3IG4-DJ3Co8nb.js → wardleyDiagram-VM6X3IG4-BdlTJgEc.js} +1 -1
  58. package/dist/assets/{xychartDiagram-S5SC5T6Z-Cz5E9New.js → xychartDiagram-S5SC5T6Z-CYn2sV77.js} +1 -1
  59. package/dist/favicon.png +0 -0
  60. package/dist/favicon.svg +1 -9
  61. package/dist/generate-icons.js +47 -46
  62. package/dist/icons/icon-128x128.png +0 -0
  63. package/dist/icons/icon-128x128.svg +1 -12
  64. package/dist/icons/icon-144x144.png +0 -0
  65. package/dist/icons/icon-144x144.svg +1 -12
  66. package/dist/icons/icon-152x152.png +0 -0
  67. package/dist/icons/icon-152x152.svg +1 -12
  68. package/dist/icons/icon-192x192.png +0 -0
  69. package/dist/icons/icon-192x192.svg +1 -12
  70. package/dist/icons/icon-384x384.png +0 -0
  71. package/dist/icons/icon-384x384.svg +1 -12
  72. package/dist/icons/icon-512x512.png +0 -0
  73. package/dist/icons/icon-512x512.svg +1 -12
  74. package/dist/icons/icon-72x72.png +0 -0
  75. package/dist/icons/icon-72x72.svg +1 -12
  76. package/dist/icons/icon-96x96.png +0 -0
  77. package/dist/icons/icon-96x96.svg +1 -12
  78. package/dist/index.html +3 -3
  79. package/dist/logo-128.png +0 -0
  80. package/dist/logo-256.png +0 -0
  81. package/dist/logo-32.png +0 -0
  82. package/dist/logo-512.png +0 -0
  83. package/dist/logo-64.png +0 -0
  84. package/dist/logo-sources/logo-black.png +0 -0
  85. package/dist/logo-sources/logo-white.png +0 -0
  86. package/dist/logo.svg +1 -17
  87. package/dist/sw.js +1 -1
  88. package/dist-server/plugins/piecemaker-dossier/src/institutional-terms.js +91 -0
  89. package/dist-server/plugins/piecemaker-dossier/src/institutional-terms.js.map +1 -0
  90. package/dist-server/plugins/piecemaker-dossier/src/knowledge.js +112 -10
  91. package/dist-server/plugins/piecemaker-dossier/src/knowledge.js.map +1 -1
  92. package/dist-server/plugins/piecemaker-dossier/src/scan-result.js +5 -1
  93. package/dist-server/plugins/piecemaker-dossier/src/scan-result.js.map +1 -1
  94. package/dist-server/server/index.js +60 -26
  95. package/dist-server/server/index.js.map +1 -1
  96. package/dist-server/server/modules/database/repositories/projects.db.js +28 -6
  97. package/dist-server/server/modules/database/repositories/projects.db.js.map +1 -1
  98. package/dist-server/server/modules/database/tests/projects.db.integration.test.js +58 -1
  99. package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -1
  100. package/dist-server/server/modules/plugins/plugins.routes.js +8 -1
  101. package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -1
  102. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js +2 -0
  103. package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js.map +1 -1
  104. package/dist-server/server/piecemaker/bodacc-search.js +191 -0
  105. package/dist-server/server/piecemaker/bodacc-search.js.map +1 -0
  106. package/dist-server/server/piecemaker/company-search.js +145 -0
  107. package/dist-server/server/piecemaker/company-search.js.map +1 -0
  108. package/dist-server/server/piecemaker/company-search.test.js +18 -0
  109. package/dist-server/server/piecemaker/company-search.test.js.map +1 -0
  110. package/dist-server/server/piecemaker/index.js +6 -2
  111. package/dist-server/server/piecemaker/index.js.map +1 -1
  112. package/dist-server/server/piecemaker/knowledge/index.js +9 -4
  113. package/dist-server/server/piecemaker/knowledge/index.js.map +1 -1
  114. package/dist-server/server/piecemaker/knowledge/pipeline.js +68 -58
  115. package/dist-server/server/piecemaker/knowledge/pipeline.js.map +1 -1
  116. package/dist-server/server/piecemaker/knowledge/routes.js +2 -4
  117. package/dist-server/server/piecemaker/knowledge/routes.js.map +1 -1
  118. package/dist-server/server/piecemaker/knowledge/scan-jobs.js +91 -0
  119. package/dist-server/server/piecemaker/knowledge/scan-jobs.js.map +1 -0
  120. package/dist-server/server/piecemaker/knowledge/service.js +18 -36
  121. package/dist-server/server/piecemaker/knowledge/service.js.map +1 -1
  122. package/dist-server/server/piecemaker/library/connector-installation.js +224 -0
  123. package/dist-server/server/piecemaker/library/connector-installation.js.map +1 -0
  124. package/dist-server/server/piecemaker/library/index.js +11 -1
  125. package/dist-server/server/piecemaker/library/index.js.map +1 -1
  126. package/dist-server/server/piecemaker/library/marketplace.js +102 -43
  127. package/dist-server/server/piecemaker/library/marketplace.js.map +1 -1
  128. package/dist-server/server/piecemaker/library/migrate.js +8 -1
  129. package/dist-server/server/piecemaker/library/migrate.js.map +1 -1
  130. package/dist-server/server/piecemaker/library/provider-agents.js +50 -0
  131. package/dist-server/server/piecemaker/library/provider-agents.js.map +1 -0
  132. package/dist-server/server/piecemaker/library/provider-connectors.js +80 -0
  133. package/dist-server/server/piecemaker/library/provider-connectors.js.map +1 -0
  134. package/dist-server/server/piecemaker/library/provider-skills.js +11 -2
  135. package/dist-server/server/piecemaker/library/provider-skills.js.map +1 -1
  136. package/dist-server/server/piecemaker/library/store.js +125 -35
  137. package/dist-server/server/piecemaker/library/store.js.map +1 -1
  138. package/dist-server/server/piecemaker/library/workspace-installation.js +53 -29
  139. package/dist-server/server/piecemaker/library/workspace-installation.js.map +1 -1
  140. package/dist-server/server/piecemaker/timesheet/service.js +4 -21
  141. package/dist-server/server/piecemaker/timesheet/service.js.map +1 -1
  142. package/package.json +3 -2
  143. package/scripts/piecemaker/cli/install-command.mjs +35 -9
  144. package/scripts/piecemaker/cli/lib/config.mjs +1 -0
  145. package/scripts/piecemaker/cli/lib/piecemaker-anonymizer.mjs +78 -0
  146. package/scripts/piecemaker/cli/lib/plugins.mjs +2 -0
  147. package/scripts/piecemaker/cli/lib/pwa.mjs +46 -7
  148. package/scripts/piecemaker/cli/lib/services.mjs +65 -4
  149. package/scripts/piecemaker/cli/piecemaker-command.test.mjs +25 -0
  150. package/scripts/piecemaker/cli/piecemaker.mjs +45 -44
  151. package/scripts/piecemaker/cli/piecemaker.ps1 +8 -0
  152. package/scripts/piecemaker/cli/piecemaker.sh +6 -1
  153. package/server/index.ts +52 -23
  154. package/server/modules/database/repositories/projects.db.ts +28 -6
  155. package/server/modules/database/tests/projects.db.integration.test.ts +63 -1
  156. package/server/modules/plugins/plugins.routes.ts +8 -1
  157. package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +5 -0
  158. package/server/piecemaker/anonymizer/client-config.cjs +10 -2
  159. package/server/piecemaker/anonymizer/dictionary.cjs +6 -72
  160. package/server/piecemaker/bodacc-search.ts +205 -0
  161. package/server/piecemaker/company-search.test.ts +26 -0
  162. package/server/piecemaker/company-search.ts +183 -0
  163. package/server/piecemaker/index.ts +8 -2
  164. package/server/piecemaker/knowledge/index.ts +9 -4
  165. package/server/piecemaker/knowledge/pipeline.ts +89 -57
  166. package/server/piecemaker/knowledge/routes.ts +2 -4
  167. package/server/piecemaker/knowledge/scan-jobs.ts +111 -0
  168. package/server/piecemaker/knowledge/service.ts +18 -33
  169. package/server/piecemaker/library/connector-installation.ts +248 -0
  170. package/server/piecemaker/library/index.ts +5 -1
  171. package/server/piecemaker/library/marketplace.ts +104 -39
  172. package/server/piecemaker/library/migrate.ts +8 -1
  173. package/server/piecemaker/library/provider-agents.ts +49 -0
  174. package/server/piecemaker/library/provider-connectors.ts +89 -0
  175. package/server/piecemaker/library/provider-skills.ts +10 -1
  176. package/server/piecemaker/library/store.ts +129 -36
  177. package/server/piecemaker/library/workspace-installation.ts +54 -29
  178. package/server/piecemaker/router.cjs +2 -1
  179. package/server/piecemaker/timesheet/service.ts +4 -16
  180. package/server/piecemaker/vendor/installer/steps/03-python-gliner.mjs +0 -27
  181. package/server/piecemaker/vendor/installer/steps/14-mxc-sandbox.mjs +1 -1
  182. package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/substitution.cjs +2 -3
  183. package/server/piecemaker/vendor/piecemaker-plugin/skills/conversion-md/SKILL.md +3 -3
  184. package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +3 -10
  185. package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +135 -4
  186. package/server/piecemaker/vendor/websocket-server/process-group.cjs +95 -0
  187. package/server/piecemaker/vendor/websocket-server/scripts/__pycache__/scan_utils.cpython-312.pyc +0 -0
  188. package/server/piecemaker/vendor/websocket-server/scripts/convert_and_scan_pipeline.py +280 -149
  189. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/model_config.cpython-312.pyc +0 -0
  190. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/scanner_worker.cpython-312.pyc +0 -0
  191. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/scanner_worker.py +35 -29
  192. package/server/piecemaker/vendor/websocket-server/scripts/requirements.txt +0 -5
  193. package/server/shared/types.ts +1 -0
  194. package/dist/assets/channel-Dz3eE5vU.js +0 -1
  195. package/dist/assets/classDiagram-ZZMXUADV-BC1eKV2j.js +0 -1
  196. package/dist/assets/classDiagram-v2-VYDZK3BY-BC1eKV2j.js +0 -1
  197. package/dist/assets/index-DhwJpHCq.css +0 -1
  198. package/dist/assets/stateDiagram-v2-MP3YSRHH-BXuT4zDG.js +0 -1
  199. package/dist/assets/swimlanesDiagram-VR7AAH4N-B0eYrB4U.js +0 -8
  200. package/server/piecemaker/vendor/websocket-server/case-instructions.cjs +0 -111
  201. package/server/piecemaker/vendor/websocket-server/scripts/ADDRESS_ANONYMIZATION.md +0 -216
  202. package/server/piecemaker/vendor/websocket-server/scripts/DEDUPLICATION_CHANGES.md +0 -134
  203. package/server/piecemaker/vendor/websocket-server/scripts/GLINER2_README.md +0 -138
  204. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/AUDIT_PERF_QUALITE.md +0 -246
  205. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/MODELE_COREML.md +0 -62
  206. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/coreml_runtime.cpython-312.pyc +0 -0
  207. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/build_coreml.py +0 -118
  208. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/coreml_runtime.py +0 -164
  209. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/presidio-gliner.py +0 -479
@@ -9,13 +9,17 @@ import express from 'express';
9
9
  import { createLibraryStore } from './store.js';
10
10
  import { createLibraryRouter } from './routes.js';
11
11
  import { createLibraryMarketplaceRouter, scanInstalledLibraryCollections } from './marketplace.js';
12
+ import { scanAndPersistLibraryProviderAgents } from './provider-agents.js';
13
+ import { scanAndPersistLibraryProviderConnectors } from './provider-connectors.js';
12
14
  import { scanAndPersistLibraryProviderSkills } from './provider-skills.js';
13
15
 
14
16
  export { installLibraryRuntime } from './runtime.js';
15
17
 
16
18
  export async function startLibraryBackend(home: string, applicationRoot: string) {
17
19
  const store = createLibraryStore(home);
18
- try { await scanAndPersistLibraryProviderSkills(store, undefined); } catch {}
20
+ try { await scanAndPersistLibraryProviderSkills(store, undefined, undefined, os.homedir()); } catch {}
21
+ try { scanAndPersistLibraryProviderAgents(store, os.homedir()); } catch {}
22
+ try { scanAndPersistLibraryProviderConnectors(store, os.homedir()); } catch {}
19
23
  try { scanInstalledLibraryCollections(store, os.homedir()); } catch {}
20
24
  const require = createRequire(import.meta.url);
21
25
  const { createActivationRouter } = require(path.join(applicationRoot, 'server/piecemaker/activation/index.cjs'));
@@ -6,7 +6,11 @@ import { spawnSync } from 'node:child_process';
6
6
  import express from 'express';
7
7
 
8
8
  import type { createLibraryStore } from './store.js';
9
+ import { normalizeProviderConnector } from './connector-installation.js';
9
10
  import { importLibraryDirectory } from './migrate.js';
11
+ import { scanAndPersistLibraryProviderAgents } from './provider-agents.js';
12
+ import { scanAndPersistLibraryProviderConnectors } from './provider-connectors.js';
13
+ import { scanAndPersistLibraryProviderSkills } from './provider-skills.js';
10
14
 
11
15
  type MarketplaceKind = 'connector' | 'skill' | 'plugin' | 'agent';
12
16
 
@@ -37,13 +41,26 @@ function marketplacePackageKinds(userHome: string, marketplaceName: string, plug
37
41
  if (fs.existsSync(path.join(root, 'agents'))) kinds.add('agent');
38
42
  }
39
43
  if (Array.isArray(entry?.skills) && entry.skills.length) kinds.add('skill');
40
- const searchable = `${plugin.name} ${plugin.description || ''}`.toLowerCase();
41
- if (/\bmcp\b|\bconnect(?:or|eur|s|ed|ion)?\b|\bintegration\b/.test(searchable)) kinds.add('connector');
42
- if (/\bskills?\b|\btoolkit\b|\bworkflow\b/.test(searchable)) kinds.add('skill');
43
- if (/\bagents?\b/.test(searchable)) kinds.add('agent');
44
+ if (marketplaceName === 'mcp-legifrance') kinds.add('connector');
44
45
  return [...kinds];
45
46
  }
46
47
 
48
+ function disableNativeClaudePlugin(userHome: string, id: string) {
49
+ const settingsFilename = path.join(userHome, '.claude/settings.json');
50
+ const settings = fs.existsSync(settingsFilename)
51
+ ? JSON.parse(fs.readFileSync(settingsFilename, 'utf8'))
52
+ : {};
53
+ const enabledPlugins = settings.enabledPlugins && typeof settings.enabledPlugins === 'object' && !Array.isArray(settings.enabledPlugins)
54
+ ? settings.enabledPlugins
55
+ : {};
56
+ if (enabledPlugins[id] === false) return;
57
+ settings.enabledPlugins = { ...enabledPlugins, [id]: false };
58
+ fs.mkdirSync(path.dirname(settingsFilename), { recursive: true, mode: 0o700 });
59
+ const temporary = `${settingsFilename}.library.tmp`;
60
+ fs.writeFileSync(temporary, JSON.stringify(settings, null, 2), { mode: 0o600 });
61
+ fs.renameSync(temporary, settingsFilename);
62
+ }
63
+
47
64
  export function scanInstalledLibraryCollections(store: ReturnType<typeof createLibraryStore>, userHome: string) {
48
65
  const filename = path.join(userHome, '.claude/plugins/installed_plugins.json');
49
66
  const registry = fs.existsSync(filename) ? JSON.parse(fs.readFileSync(filename, 'utf8')).plugins || {} : {};
@@ -51,7 +68,6 @@ export function scanInstalledLibraryCollections(store: ReturnType<typeof createL
51
68
  if (!fs.existsSync(pluginsDirectory) || fs.lstatSync(pluginsDirectory).isSymbolicLink()) return;
52
69
  const pluginsRoot = fs.realpathSync(pluginsDirectory);
53
70
  for (const [id, installs] of Object.entries(registry)) {
54
- if (store.hasCollection(id)) continue;
55
71
  if (!Array.isArray(installs)) continue;
56
72
  const install = installs.find((entry) => entry && typeof entry.installPath === 'string') as { installPath: string } | undefined;
57
73
  if (!install || !fs.existsSync(install.installPath)) continue;
@@ -60,7 +76,7 @@ export function scanInstalledLibraryCollections(store: ReturnType<typeof createL
60
76
  let manifest: { name?: string; displayName?: string; description?: string } = {};
61
77
  const manifestPath = path.join(installRoot, '.claude-plugin', 'plugin.json');
62
78
  try { manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); } catch {}
63
- const imported = [
79
+ const imported: Array<{ source: string; id: string; linked: boolean; rootPath?: string }> = [
64
80
  ...importLibraryDirectory(store, path.join(installRoot, 'skills'), 'skill', false),
65
81
  ...importLibraryDirectory(store, path.join(installRoot, 'agents'), 'agent', false),
66
82
  ];
@@ -72,23 +88,32 @@ export function scanInstalledLibraryCollections(store: ReturnType<typeof createL
72
88
  imported.push({ source, id: store.importFile(source, 'skill', false), linked: false });
73
89
  }
74
90
  }
75
- const files: Array<{ path: string; content: Buffer }> = [];
76
- let totalSize = 0;
77
- const collect = (directory: string, relative = '') => {
78
- for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
79
- if (entry.name === '.git' || entry.name === 'node_modules' || entry.name === '__pycache__' || entry.isSymbolicLink()) continue;
80
- const relativePath = path.posix.join(relative.split(path.sep).join('/'), entry.name);
81
- const absolutePath = path.join(directory, entry.name);
82
- if (entry.isDirectory()) collect(absolutePath, relativePath);
83
- else if (entry.isFile()) {
84
- const content = fs.readFileSync(absolutePath);
85
- totalSize += content.length;
86
- if (totalSize > 30 * 1024 * 1024 || files.length >= 5000) throw new Error(`Plugin trop volumineux : ${id}`);
87
- files.push({ path: relativePath, content });
91
+ const mcpPath = path.join(installRoot, '.mcp.json');
92
+ if (fs.existsSync(mcpPath) && !fs.lstatSync(mcpPath).isSymbolicLink()) {
93
+ try {
94
+ const parsed = JSON.parse(fs.readFileSync(mcpPath, 'utf8'));
95
+ const servers = parsed?.mcpServers && typeof parsed.mcpServers === 'object' && !Array.isArray(parsed.mcpServers)
96
+ ? parsed.mcpServers as Record<string, unknown>
97
+ : {};
98
+ for (const [name, raw] of Object.entries(servers)) {
99
+ const config = normalizeProviderConnector(raw);
100
+ if (!config) continue;
101
+ const source = `${mcpPath}#${name}`;
102
+ imported.push({
103
+ source,
104
+ id: store.importConnector({
105
+ name,
106
+ description: config.url || config.command || name,
107
+ config,
108
+ source,
109
+ namespace: id,
110
+ }),
111
+ linked: false,
112
+ rootPath: `mcp/${name}.json`,
113
+ });
88
114
  }
89
- }
90
- };
91
- collect(installRoot);
115
+ } catch {}
116
+ }
92
117
  const fallbackEntryName = imported.length ? store.document(imported[0].id).name : null;
93
118
  store.upsertCollection({
94
119
  id,
@@ -97,13 +122,46 @@ export function scanInstalledLibraryCollections(store: ReturnType<typeof createL
97
122
  source: installRoot,
98
123
  entries: imported.map((entry) => ({
99
124
  entryId: entry.id,
100
- rootPath: path.relative(installRoot, entry.source).split(path.sep).join('/'),
125
+ rootPath: entry.rootPath || path.relative(installRoot, entry.source).split(path.sep).join('/'),
101
126
  })),
102
- files,
127
+ files: [],
103
128
  });
104
129
  }
105
130
  }
106
131
 
132
+ function readInstalledClaudePlugins(userHome: string) {
133
+ const filename = path.join(userHome, '.claude/plugins/installed_plugins.json');
134
+ if (!fs.existsSync(filename)) return {};
135
+ const config = JSON.parse(fs.readFileSync(filename, 'utf8'));
136
+ return config.plugins && typeof config.plugins === 'object' && !Array.isArray(config.plugins)
137
+ ? config.plugins as Record<string, unknown>
138
+ : {};
139
+ }
140
+
141
+ function synchronizeInstalledPluginActivation(
142
+ store: ReturnType<typeof createLibraryStore>,
143
+ userHome: string,
144
+ workspacePath: string,
145
+ ) {
146
+ const settingsFilename = path.join(userHome, '.claude/settings.json');
147
+ if (!fs.existsSync(settingsFilename)) return store.listCollections(workspacePath);
148
+ const settings = JSON.parse(fs.readFileSync(settingsFilename, 'utf8'));
149
+ const enabledPlugins = settings.enabledPlugins && typeof settings.enabledPlugins === 'object' && !Array.isArray(settings.enabledPlugins)
150
+ ? settings.enabledPlugins as Record<string, unknown>
151
+ : {};
152
+ const installedPlugins = readInstalledClaudePlugins(userHome);
153
+ const collections = store.listCollections(workspacePath);
154
+
155
+ for (const id of Object.keys(installedPlugins)) {
156
+ const collection = collections.find((entry) => entry.id === id);
157
+ const enabled = enabledPlugins[id];
158
+ if (!collection || collection.componentCount === 0 || typeof enabled !== 'boolean' || collection.enabled === enabled) continue;
159
+ store.setCollectionEnabled(workspacePath, id, enabled);
160
+ }
161
+
162
+ return store.listCollections(workspacePath);
163
+ }
164
+
107
165
  export function createLibraryMarketplaceRouter(store: ReturnType<typeof createLibraryStore>, applicationRoot: string, userHome: string) {
108
166
  const require = createRequire(import.meta.url);
109
167
  const { listMarketplaceConnectors, registerOfficialMarketplace } = require(path.join(applicationRoot, 'server/piecemaker/vendor/websocket-server/admin-routes.cjs'));
@@ -123,15 +181,6 @@ export function createLibraryMarketplaceRouter(store: ReturnType<typeof createLi
123
181
  return fs.existsSync(filename) ? JSON.parse(fs.readFileSync(filename, 'utf8')).plugins || {} : {};
124
182
  };
125
183
  const importInstalledCollections = () => scanInstalledLibraryCollections(store, userHome);
126
- const disable = (id: string) => {
127
- const filename = path.join(userHome, '.claude/settings.json');
128
- const settings = fs.existsSync(filename) ? JSON.parse(fs.readFileSync(filename, 'utf8')) : {};
129
- settings.enabledPlugins = { ...settings.enabledPlugins, [id]: false };
130
- fs.mkdirSync(path.dirname(filename), { recursive: true, mode: 0o700 });
131
- const temporary = `${filename}.library.tmp`;
132
- fs.writeFileSync(temporary, JSON.stringify(settings, null, 2), { mode: 0o600 });
133
- fs.renameSync(temporary, filename);
134
- };
135
184
  router.get('/plugin/marketplace', (req, res) => {
136
185
  try {
137
186
  const marketplace = scope(req.query.scope);
@@ -152,7 +201,23 @@ export function createLibraryMarketplaceRouter(store: ReturnType<typeof createLi
152
201
  });
153
202
  router.get('/plugins', (req, res) => {
154
203
  try {
155
- res.json({ plugins: store.listCollections(typeof req.query.workspacePath === 'string' ? req.query.workspacePath : undefined) });
204
+ const workspacePath = typeof req.query.workspacePath === 'string' ? req.query.workspacePath : undefined;
205
+ res.json({ plugins: store.listCollections(workspacePath) });
206
+ } catch (error) { res.status(400).json({ error: (error as Error).message }); }
207
+ });
208
+ router.post('/plugins/sync', async (req, res) => {
209
+ try {
210
+ const workspacePath = typeof req.body?.workspacePath === 'string' ? req.body.workspacePath : undefined;
211
+ await scanAndPersistLibraryProviderSkills(store, workspacePath, undefined, userHome);
212
+ scanAndPersistLibraryProviderAgents(store, userHome);
213
+ scanAndPersistLibraryProviderConnectors(store, userHome);
214
+ scanInstalledLibraryCollections(store, userHome);
215
+ res.json({
216
+ ok: true,
217
+ plugins: workspacePath
218
+ ? synchronizeInstalledPluginActivation(store, userHome, workspacePath)
219
+ : store.listCollections(),
220
+ });
156
221
  } catch (error) { res.status(400).json({ error: (error as Error).message }); }
157
222
  });
158
223
  router.post('/plugins/scan', (_req, res) => {
@@ -183,14 +248,14 @@ export function createLibraryMarketplaceRouter(store: ReturnType<typeof createLi
183
248
  try {
184
249
  const marketplace = scope(req.body?.scope);
185
250
  const id = req.body?.id;
186
- if (typeof id !== 'string' || !/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+$/.test(id) || !id.endsWith(`@${marketplace.name}`)) throw new Error('Connecteur invalide.');
187
- if (installed()[id]) throw new Error('Connecteur déjà installé. Son activation se règle par dossier.');
251
+ if (typeof id !== 'string' || !/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+$/.test(id) || !id.endsWith(`@${marketplace.name}`)) throw new Error('Élément invalide.');
252
+ if (installed()[id]) throw new Error('Déjà installé. Son activation se règle par dossier.');
188
253
  const catalog = listMarketplaceConnectors(run, { marketplaceName: marketplace.name });
189
- if (!catalog.plugins.some((plugin: { id: string }) => plugin.id === id)) throw new Error('Connecteur absent du catalogue.');
190
- disable(id);
254
+ if (!catalog.plugins.some((plugin: { id: string }) => plugin.id === id)) throw new Error('Élément absent du catalogue.');
255
+ disableNativeClaudePlugin(userHome, id);
191
256
  let result;
192
257
  try { result = run('claude', ['plugin', 'install', id, '--scope', 'user']); }
193
- finally { disable(id); }
258
+ finally { disableNativeClaudePlugin(userHome, id); }
194
259
  if (!result.ok) throw new Error(result.output || 'Installation impossible.');
195
260
  importInstalledCollections();
196
261
  res.json({ ok: true, enabled: false });
@@ -29,12 +29,19 @@ export function migratePersonalLibrary(store: ReturnType<typeof createLibrarySto
29
29
  [path.join(userHome, '.claude', 'skills'), 'skill'],
30
30
  [path.join(userHome, '.codex', 'skills'), 'skill'],
31
31
  [path.join(userHome, '.agents', 'skills'), 'skill'],
32
+ [path.join(userHome, '.cursor', 'skills'), 'skill'],
33
+ [path.join(userHome, '.config', 'opencode', 'skills'), 'skill'],
34
+ [path.join(userHome, '.grok', 'skills'), 'skill'],
32
35
  [path.join(userHome, '.claude', 'agents'), 'agent'],
36
+ [path.join(userHome, '.cursor', 'agents'), 'agent'],
37
+ [path.join(userHome, '.grok', 'agents'), 'agent'],
38
+ [path.join(userHome, '.config', 'opencode', 'agents'), 'agent'],
39
+ [path.join(userHome, '.config', 'opencode', 'agent'), 'agent'],
33
40
  [path.join(userHome, '.piecemaker', 'library', 'skills'), 'skill'],
34
41
  [path.join(userHome, '.piecemaker', 'library', 'agents'), 'agent'],
35
42
  ] as const) imported.push(...importLibraryDirectory(store, directory, kind));
36
43
  if (withdraw) {
37
- const candidates = imported.filter((entry) => ['.claude', '.codex', '.agents'].some((provider) => entry.source.startsWith(path.join(userHome, provider) + path.sep)));
44
+ const candidates = imported.filter((entry) => ['.claude', '.codex', '.agents', '.cursor', '.grok', path.join('.config', 'opencode')].some((provider) => entry.source.startsWith(path.join(userHome, provider) + path.sep)));
38
45
  const backup = path.join(store.directory, `migration-${Date.now()}`);
39
46
  fs.mkdirSync(backup, { recursive: true, mode: 0o700 });
40
47
  fs.writeFileSync(path.join(backup, 'manifest.json'), JSON.stringify(candidates, null, 2), { mode: 0o600 });
@@ -0,0 +1,49 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createRequire } from 'node:module';
4
+
5
+ import { importLibraryDirectory } from './migrate.js';
6
+ import type { createLibraryStore } from './store.js';
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const TOML = require('@iarna/toml') as { parse(value: string): Record<string, unknown> };
10
+
11
+ function importTomlAgents(store: ReturnType<typeof createLibraryStore>, directory: string) {
12
+ if (!fs.existsSync(directory) || fs.lstatSync(directory).isSymbolicLink()) return [];
13
+ const imported: string[] = [];
14
+ for (const item of fs.readdirSync(directory, { withFileTypes: true })) {
15
+ if (!item.isFile() || !item.name.toLowerCase().endsWith('.toml')) continue;
16
+ const source = path.join(directory, item.name);
17
+ if (fs.lstatSync(source).isSymbolicLink()) continue;
18
+ try {
19
+ const parsed = TOML.parse(fs.readFileSync(source, 'utf8'));
20
+ const name = typeof parsed.name === 'string' && parsed.name.trim() ? parsed.name : path.basename(item.name, '.toml');
21
+ const description = typeof parsed.description === 'string' ? parsed.description : '';
22
+ const body = typeof parsed.developer_instructions === 'string' ? parsed.developer_instructions : '';
23
+ imported.push(store.importContent(source, 'agent', `---\nname: ${name}\ndescription: ${description}\n---\n${body}\n`));
24
+ } catch {}
25
+ }
26
+ return imported;
27
+ }
28
+
29
+ export function scanAndPersistLibraryProviderAgents(store: ReturnType<typeof createLibraryStore>, userHome: string) {
30
+ const markdownDirectories = [
31
+ path.join(userHome, '.claude', 'agents'),
32
+ path.join(userHome, '.cursor', 'agents'),
33
+ path.join(userHome, '.config', 'opencode', 'agent'),
34
+ path.join(userHome, '.config', 'opencode', 'agents'),
35
+ path.join(userHome, '.grok', 'agents'),
36
+ ];
37
+ for (const directory of markdownDirectories) {
38
+ try { importLibraryDirectory(store, directory, 'agent', false); } catch {}
39
+ }
40
+ try { importTomlAgents(store, path.join(userHome, '.codex', 'agents')); } catch {}
41
+ }
42
+
43
+ export function scanAndPersistLibraryClaudeAgents(
44
+ store: ReturnType<typeof createLibraryStore>,
45
+ _workspacePath: string | undefined,
46
+ userHome: string,
47
+ ) {
48
+ scanAndPersistLibraryProviderAgents(store, userHome);
49
+ }
@@ -0,0 +1,89 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createRequire } from 'node:module';
4
+
5
+ import { normalizeProviderConnector, type LibraryConnectorConfig } from './connector-installation.js';
6
+ import type { createLibraryStore } from './store.js';
7
+
8
+ const require = createRequire(import.meta.url);
9
+ const TOML = require('@iarna/toml') as { parse(value: string): Record<string, unknown> };
10
+
11
+ export const REGISTRE_PUBLIC_CONNECTOR = Object.freeze({
12
+ name: 'registre-public',
13
+ url: 'https://registre-public.com/api/mcp',
14
+ });
15
+
16
+ type ImportedConnector = {
17
+ name: string;
18
+ description: string;
19
+ config: LibraryConnectorConfig;
20
+ source: string;
21
+ };
22
+
23
+ function readJson(filePath: string) {
24
+ if (!fs.existsSync(filePath)) return {};
25
+ try {
26
+ const value = JSON.parse(fs.readFileSync(filePath, 'utf8'));
27
+ return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
28
+ } catch {
29
+ return {};
30
+ }
31
+ }
32
+
33
+ function readToml(filePath: string) {
34
+ if (!fs.existsSync(filePath)) return {};
35
+ try {
36
+ const value = TOML.parse(fs.readFileSync(filePath, 'utf8'));
37
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
38
+ } catch {
39
+ return {};
40
+ }
41
+ }
42
+
43
+ function objectRecord(value: unknown) {
44
+ return value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
45
+ }
46
+
47
+ function collectServers(source: string, servers: Record<string, unknown>, collected: ImportedConnector[]) {
48
+ for (const [name, raw] of Object.entries(servers)) {
49
+ const config = normalizeProviderConnector(raw);
50
+ if (!config) continue;
51
+ collected.push({
52
+ name,
53
+ description: config.url || config.command || name,
54
+ config,
55
+ source: `${source}#${name}`,
56
+ });
57
+ }
58
+ }
59
+
60
+ export function listUserProviderConnectors(userHome: string) {
61
+ const collected: ImportedConnector[] = [];
62
+ collectServers(path.join(userHome, '.claude.json'), objectRecord(readJson(path.join(userHome, '.claude.json')).mcpServers), collected);
63
+ collectServers(path.join(userHome, '.codex', 'config.toml'), objectRecord(readToml(path.join(userHome, '.codex', 'config.toml')).mcp_servers), collected);
64
+ collectServers(path.join(userHome, '.cursor', 'mcp.json'), objectRecord(readJson(path.join(userHome, '.cursor', 'mcp.json')).mcpServers), collected);
65
+ const opencodeJson = path.join(userHome, '.config', 'opencode', 'opencode.json');
66
+ const opencodeJsonc = path.join(userHome, '.config', 'opencode', 'opencode.jsonc');
67
+ const opencodePath = fs.existsSync(opencodeJson) ? opencodeJson : opencodeJsonc;
68
+ collectServers(opencodePath, objectRecord(readJson(opencodePath).mcp), collected);
69
+ collectServers(path.join(userHome, '.grok', 'config.toml'), objectRecord(readToml(path.join(userHome, '.grok', 'config.toml')).mcp_servers), collected);
70
+ return collected;
71
+ }
72
+
73
+ export function seedDefaultLibraryConnectors(store: ReturnType<typeof createLibraryStore>) {
74
+ return store.importConnector({
75
+ name: REGISTRE_PUBLIC_CONNECTOR.name,
76
+ description: REGISTRE_PUBLIC_CONNECTOR.url,
77
+ config: { transport: 'http', url: REGISTRE_PUBLIC_CONNECTOR.url },
78
+ source: 'piecemaker:default:registre-public',
79
+ });
80
+ }
81
+
82
+ export function scanAndPersistLibraryProviderConnectors(store: ReturnType<typeof createLibraryStore>, userHome: string) {
83
+ seedDefaultLibraryConnectors(store);
84
+ const imported: string[] = [];
85
+ for (const connector of listUserProviderConnectors(userHome)) {
86
+ try { imported.push(store.importConnector(connector)); } catch {}
87
+ }
88
+ return imported;
89
+ }
@@ -1,6 +1,9 @@
1
+ import path from 'node:path';
2
+
1
3
  import { providerSkillsService } from '@/modules/providers/index.js';
2
4
  import type { LLMProvider, ProviderSkillListOptions } from '@/shared/types.js';
3
5
 
6
+ import { importLibraryDirectory } from './migrate.js';
4
7
  import type { createLibraryStore } from './store.js';
5
8
 
6
9
  const LIBRARY_SKILL_PROVIDERS: LLMProvider[] = ['claude', 'codex', 'cursor', 'mistral', 'opencode'];
@@ -35,14 +38,20 @@ export async function scanAndPersistLibraryProviderSkills(
35
38
  store: ReturnType<typeof createLibraryStore>,
36
39
  workspacePath: string | undefined,
37
40
  reader: ProviderSkillsReader = providerSkillsService,
41
+ userHome?: string,
38
42
  ) {
39
43
  const result = await listLibraryProviderSkills(workspacePath, reader);
40
44
  for (const provider of result.providers) {
41
45
  for (const skill of provider.skills) {
42
- if (!skill.sourcePath) continue;
46
+ if (!skill.sourcePath || skill.scope !== 'user' || skill.pluginId || skill.pluginName) continue;
43
47
  try { store.importFile(skill.sourcePath, 'skill'); }
44
48
  catch { try { store.importFile(skill.sourcePath, 'skill', false); } catch {} }
45
49
  }
46
50
  }
51
+ if (userHome) {
52
+ try { importLibraryDirectory(store, path.join(userHome, '.grok', 'skills'), 'skill', false); } catch {}
53
+ }
47
54
  return result;
48
55
  }
56
+
57
+ export { scanAndPersistLibraryClaudeAgents, scanAndPersistLibraryProviderAgents } from './provider-agents.js';