@piecemaker-legal/piecemaker 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/assets/{abnfDiagram-VCTEODGH-C2JDmlZx.js → abnfDiagram-VCTEODGH-BeQS_HnO.js} +1 -1
  2. package/dist/assets/{arc-XhSg5Mrj.js → arc-ClYjD3aM.js} +1 -1
  3. package/dist/assets/{architectureDiagram-5GKGNRK7-DKREuXxk.js → architectureDiagram-5GKGNRK7-Csdihb1L.js} +1 -1
  4. package/dist/assets/{blockDiagram-I7D4REHJ-CNK0Tp5d.js → blockDiagram-I7D4REHJ-BuXey9ht.js} +1 -1
  5. package/dist/assets/{c4Diagram-7LVT6UL2-C8fJzWVp.js → c4Diagram-7LVT6UL2-DdO-ovOy.js} +1 -1
  6. package/dist/assets/channel-DhuuSCHK.js +1 -0
  7. package/dist/assets/{chunk-2Q5K7J3B-DlE8nLJo.js → chunk-2Q5K7J3B-D3hzWzSc.js} +1 -1
  8. package/dist/assets/{chunk-5VM5RSS4-CSm-2TZ4.js → chunk-5VM5RSS4-DeT3cR6k.js} +1 -1
  9. package/dist/assets/{chunk-F27PBJKO-CSgnXT2c.js → chunk-F27PBJKO-bazGi1ru.js} +1 -1
  10. package/dist/assets/{chunk-IMKFNOWR-C6bkt6C1.js → chunk-IMKFNOWR-BE3ZXrPd.js} +1 -1
  11. package/dist/assets/{chunk-JWPE2WC7-jUR52MBO.js → chunk-JWPE2WC7-dTAsgByE.js} +1 -1
  12. package/dist/assets/{chunk-POPQ4Y6H-D0UAL7O7.js → chunk-POPQ4Y6H-DKYrzMSd.js} +1 -1
  13. package/dist/assets/{chunk-SVP7TREG-C9dtOEii.js → chunk-SVP7TREG-BTtrMvhE.js} +1 -1
  14. package/dist/assets/{chunk-TICWLB2K-BEzWKT39.js → chunk-TICWLB2K-CZPHShPS.js} +1 -1
  15. package/dist/assets/{chunk-XXDRQBXY-uD1oklVY.js → chunk-XXDRQBXY-B0byFHaU.js} +1 -1
  16. package/dist/assets/classDiagram-ZZMXUADV-CO0E82Dl.js +1 -0
  17. package/dist/assets/classDiagram-v2-VYDZK3BY-CO0E82Dl.js +1 -0
  18. package/dist/assets/{cose-bilkent-JH36ORCC-aGjlSdMe.js → cose-bilkent-JH36ORCC-BbLCzlaU.js} +1 -1
  19. package/dist/assets/{cynefin-OW5HDTMX-D3G4OYOn.js → cynefin-OW5HDTMX-CQ8ui4YD.js} +1 -1
  20. package/dist/assets/{cynefinDiagram-5FMLGOSQ-9swRDUnu.js → cynefinDiagram-5FMLGOSQ-T-GL1aIf.js} +1 -1
  21. package/dist/assets/{dagre-GXQ25YYZ-lvaAGdqY.js → dagre-GXQ25YYZ-CXxVKznH.js} +1 -1
  22. package/dist/assets/{diagram-S7CK7UJ4-BaZ6YIkR.js → diagram-S7CK7UJ4-B_-1Mf_7.js} +1 -1
  23. package/dist/assets/{diagram-UQ7AKVKN-COJ2Gb38.js → diagram-UQ7AKVKN-Bs-OB8xI.js} +1 -1
  24. package/dist/assets/{diagram-VSXAHHWV-CYZEkbzP.js → diagram-VSXAHHWV-BpUqq93o.js} +1 -1
  25. package/dist/assets/{diagram-VX7I27RA-fFeQJ4ae.js → diagram-VX7I27RA-CZ6hSUo6.js} +1 -1
  26. package/dist/assets/{diagram-Z3DM3KII-B7knszDV.js → diagram-Z3DM3KII-DVZiDO6S.js} +1 -1
  27. package/dist/assets/{ebnfDiagram-PWID7BFC-Dk0l329Y.js → ebnfDiagram-PWID7BFC-D_1izoKK.js} +1 -1
  28. package/dist/assets/{erDiagram-RLTQ6QDP-CtpYxui8.js → erDiagram-RLTQ6QDP-_jSi4sg-.js} +1 -1
  29. package/dist/assets/{flowDiagram-HODETNUW-aVWueRJD.js → flowDiagram-HODETNUW-BtBM7ez3.js} +1 -1
  30. package/dist/assets/{ganttDiagram-EL5Y4UJY-DfrX-B7p.js → ganttDiagram-EL5Y4UJY-Bz2nxw7c.js} +1 -1
  31. package/dist/assets/{gitGraphDiagram-WWUBYQGX-BFB1ZPF3.js → gitGraphDiagram-WWUBYQGX-8Q3I3hoE.js} +1 -1
  32. package/dist/assets/{index-DqRygn9E.js → index-CZUj0Tlu.js} +157 -158
  33. package/dist/assets/{index-Ds4HaAjz.css → index-DcfdIMj-.css} +1 -1
  34. package/dist/assets/{infoDiagram-27XIBGKW-CuYkzm43.js → infoDiagram-27XIBGKW-Cc6eKjfU.js} +1 -1
  35. package/dist/assets/{ishikawaDiagram-5VMMS53U-EMiw8Akh.js → ishikawaDiagram-5VMMS53U-Bd3w97qM.js} +1 -1
  36. package/dist/assets/{journeyDiagram-3NMN7TZE-DCoLV1f8.js → journeyDiagram-3NMN7TZE-Cy6XbK5X.js} +1 -1
  37. package/dist/assets/{kanban-definition-UXKFOSKX-CyA4Yinu.js → kanban-definition-UXKFOSKX-kyLqWDpr.js} +1 -1
  38. package/dist/assets/{layout-BlaB0grA.js → layout-DXpPSEft.js} +1 -1
  39. package/dist/assets/{linear-DLX3dJDH.js → linear-DH_h9cDZ.js} +1 -1
  40. package/dist/assets/{mermaid.core-Cy51CT89.js → mermaid.core-BghXiB7p.js} +6 -6
  41. package/dist/assets/{mindmap-definition-YA3MSWOX-OBXjfL7I.js → mindmap-definition-YA3MSWOX-C2xxEXsP.js} +1 -1
  42. package/dist/assets/{pegDiagram-XKGWAZYB-C_BJjUh1.js → pegDiagram-XKGWAZYB-DuppHX4-.js} +1 -1
  43. package/dist/assets/{pieDiagram-E7YTZNPT-jIpbr3Fi.js → pieDiagram-E7YTZNPT-BCukPZ2a.js} +1 -1
  44. package/dist/assets/{quadrantDiagram-AXDQQJYC-C1A15xI5.js → quadrantDiagram-AXDQQJYC-Dm_ojY_7.js} +1 -1
  45. package/dist/assets/{railroadDiagram-O6MQD6OU-Rslzn1pI.js → railroadDiagram-O6MQD6OU-BzdOv7BJ.js} +1 -1
  46. package/dist/assets/{requirementDiagram-BXWQKSXE-LlfURO5-.js → requirementDiagram-BXWQKSXE-DgewPP_g.js} +1 -1
  47. package/dist/assets/{sankeyDiagram-P5KCCOFB-B5BPF4-O.js → sankeyDiagram-P5KCCOFB-vEIMvCSt.js} +1 -1
  48. package/dist/assets/{sequenceDiagram-WJ2MYXX4-orYZe9zX.js → sequenceDiagram-WJ2MYXX4-BL_31NoY.js} +1 -1
  49. package/dist/assets/{sizeCapture-INFHLROL-Co-K5Cfb.js → sizeCapture-INFHLROL-Ch6u4xo6.js} +1 -1
  50. package/dist/assets/{stateDiagram-D77RDMKH-COEx1aH2.js → stateDiagram-D77RDMKH-ByquMuJv.js} +1 -1
  51. package/dist/assets/{stateDiagram-v2-MP3YSRHH-DaeTZvmy.js → stateDiagram-v2-MP3YSRHH-_QRJP_vn.js} +1 -1
  52. package/dist/assets/{swimlanes-42K2YHIH-BHQaDhfZ.js → swimlanes-42K2YHIH-BZyXEHOb.js} +1 -1
  53. package/dist/assets/swimlanesDiagram-VR7AAH4N-sqZwZwbP.js +8 -0
  54. package/dist/assets/{timeline-definition-24CTP7MA-COqCRwGX.js → timeline-definition-24CTP7MA-CLBivayK.js} +1 -1
  55. package/dist/assets/{vennDiagram-4TSXK5OY-nym5XSnr.js → vennDiagram-4TSXK5OY-3dJ2PRqR.js} +1 -1
  56. package/dist/assets/{wardleyDiagram-VM6X3IG4-DEPPey_W.js → wardleyDiagram-VM6X3IG4-C279LT36.js} +1 -1
  57. package/dist/assets/{xychartDiagram-S5SC5T6Z-uSJ404kL.js → xychartDiagram-S5SC5T6Z-FoqPDrei.js} +1 -1
  58. package/dist/index.html +2 -2
  59. package/dist/sw.js +1 -1
  60. package/dist-server/server/piecemaker/harness/citations.routes.js +18 -1
  61. package/dist-server/server/piecemaker/harness/citations.routes.js.map +1 -1
  62. package/dist-server/server/piecemaker/harness/legifrance-html.js +112 -0
  63. package/dist-server/server/piecemaker/harness/legifrance-html.js.map +1 -0
  64. package/package.json +1 -1
  65. package/server/piecemaker/harness/citations.routes.ts +23 -1
  66. package/server/piecemaker/harness/legifrance-html.ts +107 -0
  67. package/dist/assets/channel-DO5hoFdU.js +0 -1
  68. package/dist/assets/classDiagram-ZZMXUADV-BsQtwznI.js +0 -1
  69. package/dist/assets/classDiagram-v2-VYDZK3BY-BsQtwznI.js +0 -1
  70. package/dist/assets/swimlanesDiagram-VR7AAH4N-BHW8q5M5.js +0 -8
@@ -0,0 +1,107 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ const TEXT_ID = /^(JURITEXT|CETATEXT|LEGIARTI)\d{12}$/;
6
+ const TOKEN_URL = 'https://oauth.piste.gouv.fr/api/oauth/token';
7
+ const API_URL = 'https://api.piste.gouv.fr/dila/legifrance/lf-engine-app';
8
+
9
+ function decodeEntities(value: string) {
10
+ return value
11
+ .replace(/&/gi, '&')
12
+ .replace(/ /gi, ' ')
13
+ .replace(/&lt;/gi, '<')
14
+ .replace(/&gt;/gi, '>')
15
+ .replace(/&quot;/gi, '"')
16
+ .replace(/&apos;/gi, "'")
17
+ .replace(/&#(\d+);/g, (_, code: string) => String.fromCodePoint(Number(code)))
18
+ .replace(/&#x([0-9a-f]+);/gi, (_, code: string) => String.fromCodePoint(Number.parseInt(code, 16)));
19
+ }
20
+
21
+ export function blocksFromLegifranceHtml(html: string): string[] {
22
+ if (!html) return [];
23
+ const broken = html
24
+ .replace(/<script[\s\S]*?<\/script>/gi, '')
25
+ .replace(/<style[\s\S]*?<\/style>/gi, '')
26
+ .replace(/<rech_ecli[\s\S]*?<\/rech_ecli>/gi, '')
27
+ .replace(/<br\s*\/?>/gi, '\n')
28
+ .replace(/<\/br>/gi, '')
29
+ .replace(/<\/p>/gi, '\n')
30
+ .replace(/<p\b[^>]*>/gi, '\n');
31
+ return decodeEntities(broken.replace(/<[^>]+>/g, ''))
32
+ .split(/\n+/)
33
+ .map((block) => block.replace(/[ \t\f\v]+/g, ' ').trim())
34
+ .filter(Boolean);
35
+ }
36
+
37
+ type PisteCredentials = { id: string; secret: string };
38
+
39
+ async function readCredentials(): Promise<PisteCredentials | null> {
40
+ const fromEnv = process.env.LEGIFRANCE_CLIENT_ID && process.env.LEGIFRANCE_CLIENT_SECRET
41
+ ? { id: process.env.LEGIFRANCE_CLIENT_ID, secret: process.env.LEGIFRANCE_CLIENT_SECRET }
42
+ : null;
43
+ if (fromEnv) return fromEnv;
44
+ try {
45
+ const file = await readFile(path.join(os.homedir(), '.config', 'mcp-legifrance', '.env'), 'utf8');
46
+ const values: Record<string, string> = {};
47
+ for (const line of file.split('\n')) {
48
+ const match = line.match(/^\s*([A-Z0-9_]+)\s*=(.*)$/);
49
+ if (match) values[match[1]] = match[2].trim().replace(/^["']|["']$/g, '');
50
+ }
51
+ if (!values.LEGIFRANCE_CLIENT_ID || !values.LEGIFRANCE_CLIENT_SECRET) return null;
52
+ return { id: values.LEGIFRANCE_CLIENT_ID, secret: values.LEGIFRANCE_CLIENT_SECRET };
53
+ } catch {
54
+ return null;
55
+ }
56
+ }
57
+
58
+ let tokenCache: { id: string; value: string; expiresAt: number } | null = null;
59
+
60
+ async function accessToken(credentials: PisteCredentials) {
61
+ if (tokenCache && tokenCache.id === credentials.id && tokenCache.expiresAt > Date.now() + 60_000) return tokenCache.value;
62
+ const response = await fetch(TOKEN_URL, {
63
+ method: 'POST',
64
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
65
+ body: new URLSearchParams({
66
+ grant_type: 'client_credentials',
67
+ client_id: credentials.id,
68
+ client_secret: credentials.secret,
69
+ scope: 'openid',
70
+ }),
71
+ signal: AbortSignal.timeout(15_000),
72
+ });
73
+ if (!response.ok) return null;
74
+ const body = await response.json() as { access_token?: string; expires_in?: number };
75
+ if (!body.access_token) return null;
76
+ tokenCache = { id: credentials.id, value: body.access_token, expiresAt: Date.now() + (body.expires_in ?? 3600) * 1000 };
77
+ return body.access_token;
78
+ }
79
+
80
+ async function texteHtml(id: string, token: string) {
81
+ const article = id.startsWith('LEGIARTI');
82
+ const response = await fetch(`${API_URL}${article ? '/consult/getArticle' : '/consult/juri'}`, {
83
+ method: 'POST',
84
+ headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' },
85
+ body: JSON.stringify(article ? { id } : { textId: id }),
86
+ signal: AbortSignal.timeout(20_000),
87
+ });
88
+ if (!response.ok) return '';
89
+ const body = await response.json() as { text?: { texteHtml?: string; texte?: string }; article?: { texteHtml?: string; texte?: string } };
90
+ const record = body.article ?? body.text;
91
+ if (typeof record?.texteHtml === 'string' && record.texteHtml) return record.texteHtml;
92
+ return typeof record?.texte === 'string' ? record.texte : '';
93
+ }
94
+
95
+ export async function loadLegifranceBlocks(id: string): Promise<string[] | null> {
96
+ if (!TEXT_ID.test(id)) return null;
97
+ try {
98
+ const credentials = await readCredentials();
99
+ if (!credentials) return null;
100
+ const token = await accessToken(credentials);
101
+ if (!token) return null;
102
+ const blocks = blocksFromLegifranceHtml(await texteHtml(id, token));
103
+ return blocks.length ? blocks : null;
104
+ } catch {
105
+ return null;
106
+ }
107
+ }
@@ -1 +0,0 @@
1
- import{ah as o,ai as n}from"./mermaid.core-Cy51CT89.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-TICWLB2K-BEzWKT39.js";import{_ as i}from"./mermaid.core-Cy51CT89.js";import"./chunk-5VM5RSS4-CSm-2TZ4.js";import"./chunk-XXDRQBXY-uD1oklVY.js";import"./chunk-POPQ4Y6H-D0UAL7O7.js";import"./chunk-F27PBJKO-CSgnXT2c.js";import"./index-DqRygn9E.js";import"./vendor-codemirror-CjW0lHR5.js";import"./vendor-react-D809iwXR.js";import"./vendor-xterm-BWUgpGtR.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-TICWLB2K-BEzWKT39.js";import{_ as i}from"./mermaid.core-Cy51CT89.js";import"./chunk-5VM5RSS4-CSm-2TZ4.js";import"./chunk-XXDRQBXY-uD1oklVY.js";import"./chunk-POPQ4Y6H-D0UAL7O7.js";import"./chunk-F27PBJKO-CSgnXT2c.js";import"./index-DqRygn9E.js";import"./vendor-codemirror-CjW0lHR5.js";import"./vendor-react-D809iwXR.js";import"./vendor-xterm-BWUgpGtR.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};
@@ -1,8 +0,0 @@
1
- import{c as r,s as e}from"./flowDiagram-HODETNUW-aVWueRJD.js";import{_ as a}from"./mermaid.core-Cy51CT89.js";import"./chunk-5VM5RSS4-CSm-2TZ4.js";import"./chunk-XXDRQBXY-uD1oklVY.js";import"./chunk-POPQ4Y6H-D0UAL7O7.js";import"./chunk-F27PBJKO-CSgnXT2c.js";import"./index-DqRygn9E.js";import"./vendor-codemirror-CjW0lHR5.js";import"./vendor-react-D809iwXR.js";import"./vendor-xterm-BWUgpGtR.js";import"./channel-DO5hoFdU.js";var o=a(t=>`${e(t)}
2
- .swimlane.cluster rect {
3
- stroke: ${t.clusterBorder} !important;
4
- }
5
- [data-look="neo"].cluster rect {
6
- filter: none;
7
- }
8
- `,"getStyles"),m=o,g=r({defaultLayout:"swimlane",styles:m});export{g as diagram};