@piecemaker-legal/piecemaker 2.0.8 → 2.0.10
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.
- package/dist/assets/FindReplaceDialog-KU5TEIBJ-CQ76sPaJ.js +1 -0
- package/dist/assets/FootnotePropertiesDialog-W3YHM4BV-BpgYQvvd.js +1 -0
- package/dist/assets/HyperlinkDialog-ZYH7ZHRF-qIPBOssF.css +1 -0
- package/dist/assets/HyperlinkDialog-ZYH7ZHRF-z08UbYbL.js +144 -0
- package/dist/assets/ImagePositionDialog-HEWYR6Q3-CFzOnzAt.js +1 -0
- package/dist/assets/ImagePropertiesDialog-RAB47C6M-D-ThGU-b.js +1 -0
- package/dist/assets/PageSetupDialog-AIGIXO3E-_PYIO8eb.js +1 -0
- package/dist/assets/SplitCellDialog-IFBKYCD6-Cb9uQOB8.js +1 -0
- package/dist/assets/TablePropertiesDialog-TMLKGOOW-12vmjb6B.js +1 -0
- package/dist/assets/WatermarkDialog-KRL7WMIS-C-d8rzt2.js +1 -0
- package/dist/assets/{abnfDiagram-VCTEODGH-XuFdW3jA.js → abnfDiagram-VCTEODGH-B4OsX7eF.js} +1 -1
- package/dist/assets/arc-BK1oUIk7.js +1 -0
- package/dist/assets/architectureDiagram-5GKGNRK7-CfaFI6L7.js +36 -0
- package/dist/assets/{blockDiagram-I7D4REHJ-CsgOSDLB.js → blockDiagram-I7D4REHJ-DQEI2azY.js} +1 -1
- package/dist/assets/{c4Diagram-7LVT6UL2-awKtsGCB.js → c4Diagram-7LVT6UL2-DbravpVi.js} +1 -1
- package/dist/assets/channel-DVyNr2Yg.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-DA5F8ig-.js → chunk-2Q5K7J3B-BLpZ9huC.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DawRFEGW.js → chunk-5VM5RSS4-BLlEdmX9.js} +1 -1
- package/dist/assets/{chunk-F27PBJKO-BO6B_U1p.js → chunk-F27PBJKO-D-ZNhI6q.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-Dhrf_k6W.js → chunk-IMKFNOWR-vzSiKnhh.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BTGX4CJ7.js → chunk-JWPE2WC7-DfF0k4nb.js} +1 -1
- package/dist/assets/{chunk-POPQ4Y6H-ByKLZ0wa.js → chunk-POPQ4Y6H-BnwCYsPP.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-DNCtUeow.js → chunk-SVP7TREG-DRxc8fhq.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-bgcAtBKw.js → chunk-TICWLB2K-Dd2Q-md-.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-AD-pwqOj.js → chunk-XXDRQBXY-DBjkEUp_.js} +1 -1
- package/dist/assets/classDiagram-ZZMXUADV-2pGPHl5H.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-2pGPHl5H.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-D23VMTjy.js → cose-bilkent-JH36ORCC-By6PS4oe.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-thDLtHBg.js → cynefin-OW5HDTMX-YxWpjc5W.js} +1 -1
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-BTG5qDGi.js → cynefinDiagram-5FMLGOSQ-DrtXzz3p.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-yXAeLV32.js → dagre-GXQ25YYZ-BDpTLKqZ.js} +1 -1
- package/dist/assets/{diagram-S7CK7UJ4-v1-YDY3c.js → diagram-S7CK7UJ4-C4LvqeCs.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-DlO9hQ63.js → diagram-UQ7AKVKN-BTpnMeHp.js} +1 -1
- package/dist/assets/{diagram-VSXAHHWV-B3Bz2C6Y.js → diagram-VSXAHHWV-DucHHWev.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-BosIgZRa.js → diagram-VX7I27RA-DYHZNmmH.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-C1MFbIji.js → diagram-Z3DM3KII-BHIH2BGN.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-B6g9aRAb.js → ebnfDiagram-PWID7BFC-CGiEkwj0.js} +1 -1
- package/dist/assets/{erDiagram-RLTQ6QDP-BuV5RUQ-.js → erDiagram-RLTQ6QDP-AJMHi2Us.js} +1 -1
- package/dist/assets/{flowDiagram-HODETNUW-OFcS8Psg.js → flowDiagram-HODETNUW-BqzANBh2.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-CxCIs-y4.js → ganttDiagram-EL5Y4UJY-B0xPDY2_.js} +1 -1
- package/dist/assets/{gitGraphDiagram-WWUBYQGX-DQHfgTRq.js → gitGraphDiagram-WWUBYQGX-CzPX5CNO.js} +1 -1
- package/dist/assets/{index-BPmxqMd5.js → index-Bk2iXKnJ.js} +140 -140
- package/dist/assets/index-Dc9wNuS4.css +1 -0
- package/dist/assets/{infoDiagram-27XIBGKW-UvDaFHGE.js → infoDiagram-27XIBGKW-Cjc44H0O.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-B04u_588.js → ishikawaDiagram-5VMMS53U-BWhr2v7r.js} +1 -1
- package/dist/assets/{journeyDiagram-3NMN7TZE-BYvBbjXl.js → journeyDiagram-3NMN7TZE-Bl4r6RrP.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-DxAJd2LW.js → kanban-definition-UXKFOSKX-FV-T0Vy1.js} +6 -6
- package/dist/assets/layout-CTfb1sAF.js +1 -0
- package/dist/assets/{linear-CmWY0F-m.js → linear-Dfgi6vlo.js} +1 -1
- package/dist/assets/{mermaid.core-ClUcKNvb.js → mermaid.core-DOCGsdlo.js} +7 -7
- package/dist/assets/{mindmap-definition-YA3MSWOX-DZ2GO-J-.js → mindmap-definition-YA3MSWOX-CymQ86ir.js} +1 -1
- package/dist/assets/{pegDiagram-XKGWAZYB-DF4i_o7r.js → pegDiagram-XKGWAZYB-1VMq_vi0.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-G20Z0KTO.js → pieDiagram-E7YTZNPT-C5GgXtJU.js} +1 -1
- package/dist/assets/processTemplate-GPFDLQMX-B1sVV2O0.js +22 -0
- package/dist/assets/{quadrantDiagram-AXDQQJYC-5MRlN0BO.js → quadrantDiagram-AXDQQJYC-C6zpryYf.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-B4Fp-guo.js → railroadDiagram-O6MQD6OU-D-sv4SWi.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-DFL0eww_.js → requirementDiagram-BXWQKSXE-CkjY-z4B.js} +1 -1
- package/dist/assets/sankeyDiagram-P5KCCOFB-De-d8Q6L.js +40 -0
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-iP9OUxwi.js → sequenceDiagram-WJ2MYXX4-DCsGSJa9.js} +1 -1
- package/dist/assets/{server.browser-BzI1jrZw.js → server.browser-BY3bL-IX.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-C95kgcA-.js → sizeCapture-INFHLROL-xINZhgER.js} +1 -1
- package/dist/assets/stateDiagram-D77RDMKH-CuLUTWSL.js +1 -0
- package/dist/assets/stateDiagram-v2-MP3YSRHH-Cnbs-M92.js +1 -0
- package/dist/assets/{swimlanes-42K2YHIH-BbMY7ECY.js → swimlanes-42K2YHIH-BwxARD7N.js} +1 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-D7p8qZI2.js +8 -0
- package/dist/assets/{timeline-definition-24CTP7MA-BQs8wPer.js → timeline-definition-24CTP7MA-BIOvnn-l.js} +3 -3
- package/dist/assets/{vendor-codemirror-CjW0lHR5.js → vendor-codemirror-CN-sJePf.js} +2 -2
- package/dist/assets/{vendor-react-D809iwXR.js → vendor-react-B22wqN3J.js} +5 -5
- package/dist/assets/{vennDiagram-4TSXK5OY-Imm0EPbt.js → vennDiagram-4TSXK5OY-BSD6Pfmt.js} +4 -4
- package/dist/assets/{wardleyDiagram-VM6X3IG4-DpMMDayn.js → wardleyDiagram-VM6X3IG4-7Zz2iRkF.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-DdLp1sYL.js → xychartDiagram-S5SC5T6Z-Ctx17Y1D.js} +1 -1
- package/dist/index.html +4 -4
- package/dist/sw.js +1 -1
- package/dist-server/server/modules/providers/list/mistral/mistral-models.provider.js +4 -53
- package/dist-server/server/modules/providers/list/mistral/mistral-models.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/mistral/mistral-runtime.provider.js +2 -3
- package/dist-server/server/modules/providers/list/mistral/mistral-runtime.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/mistral/mistral-vibe-models.js +30 -0
- package/dist-server/server/modules/providers/list/mistral/mistral-vibe-models.js.map +1 -0
- package/dist-server/server/modules/providers/tests/mistral-vibe-models.test.js +24 -0
- package/dist-server/server/modules/providers/tests/mistral-vibe-models.test.js.map +1 -0
- package/dist-server/server/piecemaker/anonymizer/lifecycle.js +2 -3
- package/dist-server/server/piecemaker/anonymizer/lifecycle.js.map +1 -1
- package/dist-server/server/piecemaker/desktop-update/index.js +4 -3
- package/dist-server/server/piecemaker/desktop-update/index.js.map +1 -1
- package/dist-server/server/piecemaker/docx-document.js +50 -0
- package/dist-server/server/piecemaker/docx-document.js.map +1 -0
- package/dist-server/server/piecemaker/index.js +9 -2
- package/dist-server/server/piecemaker/index.js.map +1 -1
- package/dist-server/server/piecemaker/model-discovery/codex-catalog.js +46 -0
- package/dist-server/server/piecemaker/model-discovery/codex-catalog.js.map +1 -0
- package/dist-server/server/piecemaker/model-discovery/index.js +42 -0
- package/dist-server/server/piecemaker/model-discovery/index.js.map +1 -0
- package/dist-server/server/piecemaker/model-discovery/mistral-catalog.js +19 -0
- package/dist-server/server/piecemaker/model-discovery/mistral-catalog.js.map +1 -0
- package/dist-server/server/piecemaker/model-discovery/stdio-rpc.js +61 -0
- package/dist-server/server/piecemaker/model-discovery/stdio-rpc.js.map +1 -0
- package/dist-server/server/piecemaker/project-registry.js +29 -0
- package/dist-server/server/piecemaker/project-registry.js.map +1 -0
- package/package.json +12 -1
- package/scripts/piecemaker/cli/disable-anonymizer.mjs +19 -0
- package/scripts/piecemaker/cli/lib/config.mjs +0 -1
- package/scripts/piecemaker/cli/lib/services.mjs +1 -10
- package/scripts/piecemaker/cli/piecemaker.mjs +0 -3
- package/server/modules/providers/list/mistral/mistral-models.provider.ts +4 -53
- package/server/modules/providers/list/mistral/mistral-runtime.provider.ts +2 -3
- package/server/modules/providers/list/mistral/mistral-vibe-models.ts +43 -0
- package/server/modules/providers/tests/mistral-vibe-models.test.ts +27 -0
- package/server/piecemaker/anonymizer/client-config.cjs +92 -92
- package/server/piecemaker/anonymizer/hudsucker-fixture.cjs +9 -16
- package/server/piecemaker/anonymizer/hudsucker-proxy/Cargo.toml +1 -1
- package/server/piecemaker/anonymizer/hudsucker-proxy/src/main.rs +251 -268
- package/server/piecemaker/anonymizer/lifecycle.ts +2 -3
- package/server/piecemaker/anonymizer/rewriter-bridge.cjs +6 -0
- package/server/piecemaker/anonymizer/service.cjs +117 -175
- package/server/piecemaker/desktop-update/index.ts +4 -3
- package/server/piecemaker/docx-document.ts +54 -0
- package/server/piecemaker/harness/decisions.cjs +1 -1
- package/server/piecemaker/harness/index.cjs +2 -3
- package/server/piecemaker/harness/verification.cjs +1 -1
- package/server/piecemaker/index.ts +11 -3
- package/server/piecemaker/model-discovery/codex-catalog.ts +67 -0
- package/server/piecemaker/model-discovery/index.ts +69 -0
- package/server/piecemaker/model-discovery/mistral-catalog.ts +36 -0
- package/server/piecemaker/model-discovery/stdio-rpc.ts +79 -0
- package/server/piecemaker/project-registry.ts +34 -0
- package/server/piecemaker/router.cjs +6 -7
- package/server/piecemaker/vendor/installer/bin/piecemaker.mjs +31 -77
- package/server/piecemaker/vendor/installer/lib/codex-skills.mjs +2 -84
- package/server/piecemaker/vendor/installer/lib/service.mjs +4 -24
- package/server/piecemaker/vendor/installer/steps/06-hooks.mjs +10 -21
- package/server/piecemaker/vendor/installer/steps/09-claude-assets.mjs +0 -11
- package/server/piecemaker/vendor/installer/steps/09-codex-plugin.mjs +6 -36
- package/server/piecemaker/vendor/installer/steps/13-garde-secrets.mjs +30 -12
- package/server/piecemaker/vendor/piecemaker-plugin/README.md +2 -9
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/billing-track.mjs +5 -5
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/classify-ai-documents.mjs +8 -8
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/commit-track.mjs +2 -2
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/compile-recherche.mjs +4 -6
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folders.cjs +71 -38
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.cjs +8 -38
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/protection.cjs +82 -61
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/protect-originals.mjs +4 -55
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/statusline.mjs +24 -117
- package/server/piecemaker/vendor/piecemaker-plugin/skills/tamponnage/SKILL.md +2 -2
- package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +15 -121
- package/server/piecemaker/vendor/websocket-server/case-registry.cjs +16 -32
- package/server/piecemaker/vendor/websocket-server/claude-hooks.cjs +0 -73
- package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +0 -7
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/scanner_worker.py +2 -0
- package/server/piecemaker/vendor/websocket-server/stamping-routes.cjs +3 -12
- package/server/piecemaker/vendor/websocket-server/workspace-paths.cjs +6 -6
- package/dist/assets/arc-CsCtfL20.js +0 -1
- package/dist/assets/architectureDiagram-5GKGNRK7-DGxozBGS.js +0 -36
- package/dist/assets/channel-DnynWwYa.js +0 -1
- package/dist/assets/classDiagram-ZZMXUADV-CHIsGj2B.js +0 -1
- package/dist/assets/classDiagram-v2-VYDZK3BY-CHIsGj2B.js +0 -1
- package/dist/assets/index-WwknP0l4.css +0 -1
- package/dist/assets/layout-R7w2kLxO.js +0 -1
- package/dist/assets/sankeyDiagram-P5KCCOFB-CpOdmqdy.js +0 -40
- package/dist/assets/stateDiagram-D77RDMKH-D9WHRvlY.js +0 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-D9Qlflkb.js +0 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-CA64dwpM.js +0 -8
- package/scripts/piecemaker/cli/lib/piecemaker-anonymizer.mjs +0 -78
- package/scripts/piecemaker/hooks/proxy-guard.mjs +0 -251
- package/server/piecemaker/anonymizer/providers.cjs +0 -120
- package/server/piecemaker/vendor/installer/steps/08-telegram.mjs +0 -482
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/central-mapping.cjs +0 -0
- package/server/piecemaker/vendor/websocket-server/telegram-admin.cjs +0 -602
|
@@ -1,120 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* statusLine Claude Code — bandeau permanent d'état de l'anonymisation PieceMaker.
|
|
4
|
-
*
|
|
5
|
-
* Contrat statusLine (type "command") : JSON sur stdin décrivant la session
|
|
6
|
-
* (workspace, model...), une seule ligne sur stdout, exit 0. Appelé très
|
|
7
|
-
* souvent (à chaque rendu de l'interface) : ce script doit rester rapide et
|
|
8
|
-
* ne jamais bloquer ni jeter.
|
|
9
|
-
*
|
|
10
|
-
* Le badge reflète les deux mêmes conditions que `proxy-guard.mjs` (routage
|
|
11
|
-
* + proxy vivant), mais sans autostart ni journalisation : une statusLine
|
|
12
|
-
* n'est pas le bon endroit pour une action de fond, seulement pour un
|
|
13
|
-
* affichage. Le sondage réseau est borné à 400 ms et son résultat est mis en
|
|
14
|
-
* cache 5 s dans ~/.piecemaker/proxy-statusline.json pour éviter une requête
|
|
15
|
-
* à chaque frappe.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import fs from 'node:fs';
|
|
19
2
|
import http from 'node:http';
|
|
20
|
-
import os from 'node:os';
|
|
21
3
|
import path from 'node:path';
|
|
22
|
-
import {
|
|
4
|
+
import { loadPieceMakerConfig, readHookPayload } from './lib/hook-io.mjs';
|
|
23
5
|
|
|
24
|
-
const CACHE_FILE = path.join(HOME_DIR, 'proxy-statusline.json');
|
|
25
|
-
const CACHE_TTL_MS = 5000;
|
|
26
6
|
const PROBE_TIMEOUT_MS = 400;
|
|
27
7
|
const STDIN_TIMEOUT_MS = 1000;
|
|
28
|
-
const DEFAULT_PORT = 4000;
|
|
29
8
|
const FLUSH_TIMEOUT_MS = 1000;
|
|
9
|
+
const VERT = '\u001b[32m';
|
|
10
|
+
const ROUGE = '\u001b[31m';
|
|
11
|
+
const RESET = '\u001b[0m';
|
|
30
12
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
function validPort(value) {
|
|
34
|
-
const port = Number(value);
|
|
35
|
-
return Number.isInteger(port) && port >= 1024 && port <= 65535 ? port : DEFAULT_PORT;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Même définition du routage que proxy-guard.mjs — lecture directe, jamais de throw. */
|
|
39
|
-
function readRouting() {
|
|
40
|
-
try {
|
|
41
|
-
const settings = JSON.parse(fs.readFileSync(SETTINGS_FILE, 'utf8'));
|
|
42
|
-
const value = settings?.env?.HTTPS_PROXY;
|
|
43
|
-
if (typeof value !== 'string' || !value) return false;
|
|
44
|
-
const url = new URL(value);
|
|
45
|
-
return ['127.0.0.1', 'localhost'].includes(url.hostname);
|
|
46
|
-
} catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Cache court entre deux sondages. Un cache illisible/absent n'empêche pas de sonder. */
|
|
52
|
-
function readCache() {
|
|
13
|
+
function routedProxy() {
|
|
53
14
|
try {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
if (Date.now() - parsed.ts > CACHE_TTL_MS) return null;
|
|
57
|
-
return parsed;
|
|
15
|
+
const url = new URL(process.env.HTTPS_PROXY || process.env.https_proxy || '');
|
|
16
|
+
return ['127.0.0.1', 'localhost'].includes(url.hostname) ? url : null;
|
|
58
17
|
} catch {
|
|
59
18
|
return null;
|
|
60
19
|
}
|
|
61
20
|
}
|
|
62
21
|
|
|
63
|
-
function
|
|
64
|
-
try {
|
|
65
|
-
fs.mkdirSync(HOME_DIR, { recursive: true });
|
|
66
|
-
fs.writeFileSync(CACHE_FILE, JSON.stringify({ ts: Date.now(), actif }), 'utf8');
|
|
67
|
-
} catch {
|
|
68
|
-
// Le cache est un confort de performance, pas une garantie.
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function probe(port, timeoutMs) {
|
|
22
|
+
function proxyHealthy(proxy) {
|
|
73
23
|
return new Promise((resolve) => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const request = http.get({
|
|
82
|
-
hostname: '127.0.0.1',
|
|
83
|
-
port,
|
|
84
|
-
path: '/health/liveliness',
|
|
85
|
-
timeout: timeoutMs,
|
|
86
|
-
}, (response) => {
|
|
87
|
-
response.resume();
|
|
88
|
-
finish(response.statusCode === 200);
|
|
89
|
-
});
|
|
90
|
-
request.on('timeout', () => { request.destroy(); finish(false); });
|
|
91
|
-
request.on('error', () => finish(false));
|
|
92
|
-
} catch {
|
|
93
|
-
finish(false);
|
|
94
|
-
}
|
|
24
|
+
const request = http.get({ hostname: proxy.hostname, port: proxy.port, path: '/health', timeout: PROBE_TIMEOUT_MS }, (response) => {
|
|
25
|
+
response.resume();
|
|
26
|
+
resolve(response.statusCode === 200);
|
|
27
|
+
});
|
|
28
|
+
request.on('timeout', () => { request.destroy(); resolve(false); });
|
|
29
|
+
request.on('error', () => resolve(false));
|
|
95
30
|
});
|
|
96
31
|
}
|
|
97
32
|
|
|
98
|
-
/**
|
|
99
|
-
* Couleur ANSI du badge : vert quand l'anonymisation est effective, rouge
|
|
100
|
-
* sinon. Claude Code rend les séquences ANSI de la statusLine ; on n'en met
|
|
101
|
-
* que sur le badge, jamais sur le dossier ni le modèle.
|
|
102
|
-
*/
|
|
103
|
-
const VERT = '\u001b[32m';
|
|
104
|
-
const ROUGE = '\u001b[31m';
|
|
105
|
-
const RESET = '\u001b[0m';
|
|
106
|
-
|
|
107
33
|
function colore(texte, couleur) {
|
|
108
34
|
return process.env.NO_COLOR ? texte : `${couleur}${texte}${RESET}`;
|
|
109
35
|
}
|
|
110
36
|
|
|
111
|
-
function badge(
|
|
112
|
-
|
|
113
|
-
if (
|
|
114
|
-
return colore('
|
|
37
|
+
async function badge() {
|
|
38
|
+
const proxy = routedProxy();
|
|
39
|
+
if (!proxy) return colore('⚠️ Anonymisation PieceMaker inactive — accès direct', ROUGE);
|
|
40
|
+
if (await proxyHealthy(proxy)) return colore('🔒 Anonymisation PieceMaker active ✓', VERT);
|
|
41
|
+
return colore('⛔ Anonymisation PieceMaker indisponible — requêtes bloquées (relancer piecemaker)', ROUGE);
|
|
115
42
|
}
|
|
116
43
|
|
|
117
|
-
/** Écrit la ligne et quitte proprement, en attendant le flush comme hook-io.mjs::emit. */
|
|
118
44
|
function printAndExit(text) {
|
|
119
45
|
const guard = setTimeout(() => process.exit(0), FLUSH_TIMEOUT_MS);
|
|
120
46
|
guard.unref?.();
|
|
@@ -139,35 +65,16 @@ function safeCwdName(cwd) {
|
|
|
139
65
|
}
|
|
140
66
|
|
|
141
67
|
async function main() {
|
|
142
|
-
|
|
143
|
-
try {
|
|
144
|
-
payload = await readHookPayload(STDIN_TIMEOUT_MS);
|
|
145
|
-
} catch {
|
|
146
|
-
payload = null;
|
|
147
|
-
}
|
|
148
|
-
|
|
68
|
+
const payload = await readHookPayload(STDIN_TIMEOUT_MS).catch(() => null);
|
|
149
69
|
const dirName = safeCwdName(payload?.workspace?.current_dir || payload?.cwd);
|
|
150
70
|
const modelName = typeof payload?.model?.display_name === 'string' ? payload.model.display_name : '';
|
|
151
|
-
|
|
152
|
-
let config = {};
|
|
71
|
+
let disabled = false;
|
|
153
72
|
try {
|
|
154
|
-
|
|
73
|
+
disabled = loadPieceMakerConfig()?.anonymizer?.enabled === false;
|
|
155
74
|
} catch {
|
|
156
|
-
|
|
75
|
+
disabled = false;
|
|
157
76
|
}
|
|
158
|
-
const
|
|
159
|
-
const routed = readRouting();
|
|
160
|
-
|
|
161
|
-
const cached = readCache();
|
|
162
|
-
let actif;
|
|
163
|
-
if (cached) {
|
|
164
|
-
actif = cached.actif;
|
|
165
|
-
} else {
|
|
166
|
-
actif = await probe(port, PROBE_TIMEOUT_MS);
|
|
167
|
-
writeCache(actif);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const parts = [badge(routed, actif)];
|
|
77
|
+
const parts = [disabled ? 'Anonymisation PieceMaker désactivée' : await badge()];
|
|
171
78
|
if (dirName) parts.push(dirName);
|
|
172
79
|
if (modelName) parts.push(modelName);
|
|
173
80
|
printAndExit(parts.join(' · '));
|
|
@@ -40,8 +40,8 @@ dossier ni par utilisateur.
|
|
|
40
40
|
haute définition : forme, contour, police, couleur et épaisseur, puis
|
|
41
41
|
« Enregistrer le tampon »).
|
|
42
42
|
2. **La liste des pièces vient des dossiers juridiques enregistrés** :
|
|
43
|
-
`GET /api/admin/dossiers` → `listDossiers` bâtit la liste sur
|
|
44
|
-
|
|
43
|
+
`GET /api/admin/dossiers` → `listDossiers` bâtit la liste sur les projets
|
|
44
|
+
publiés par le serveur (`~/.piecemaker/projects.json`), et chaque
|
|
45
45
|
pièce est un **fichier original** du dossier (tout fichier qui n'est ni
|
|
46
46
|
`.md` ni `.json`, via `listOriginals`), **identifié par son chemin relatif
|
|
47
47
|
au dossier** — aucun `compilation_dossier_*.json` n'est requis. L'ancien
|
|
@@ -5,9 +5,9 @@ const crypto = require('node:crypto');
|
|
|
5
5
|
const { spawn, spawnSync } = require('child_process');
|
|
6
6
|
const { performance } = require('node:perf_hooks');
|
|
7
7
|
const {
|
|
8
|
-
|
|
8
|
+
listProjectCases,
|
|
9
|
+
projectCaseEntry,
|
|
9
10
|
readRegistryConfig,
|
|
10
|
-
registerCaseFolder,
|
|
11
11
|
resolveCaseReference,
|
|
12
12
|
validateSelectedCaseFolder,
|
|
13
13
|
} = require('./case-registry.cjs');
|
|
@@ -67,13 +67,6 @@ const {
|
|
|
67
67
|
unregisterClaudeAsset,
|
|
68
68
|
} = require('./claude-assets.cjs');
|
|
69
69
|
const { claudeHooksStatus } = require('./claude-hooks.cjs');
|
|
70
|
-
const {
|
|
71
|
-
controlDossierBot,
|
|
72
|
-
controlTelegram,
|
|
73
|
-
getTelegramState,
|
|
74
|
-
saveDossierBot,
|
|
75
|
-
saveTelegramConfig,
|
|
76
|
-
} = require('./telegram-admin.cjs');
|
|
77
70
|
const {
|
|
78
71
|
DEFAULT_CASE_FOLDER_STRUCTURE,
|
|
79
72
|
configuredCaseFolderStructure,
|
|
@@ -208,8 +201,9 @@ async function registerLegalCase({
|
|
|
208
201
|
homeDir,
|
|
209
202
|
} = {}) {
|
|
210
203
|
const root = validateSelectedCaseFolder(folder);
|
|
211
|
-
const
|
|
212
|
-
|
|
204
|
+
const entry = projectCaseEntry(root);
|
|
205
|
+
if (!entry) throw new Error('Ce dossier n’est pas un projet enregistré.');
|
|
206
|
+
const structure = ensureCaseFolderStructure(root, readRegistryConfig(configFile));
|
|
213
207
|
const protection = readProtection(root);
|
|
214
208
|
if (!protection.exists) writeProtection(root, { unprotected: [] });
|
|
215
209
|
const currentMapping = readCaseMapping(root);
|
|
@@ -217,11 +211,8 @@ async function registerLegalCase({
|
|
|
217
211
|
? currentMapping
|
|
218
212
|
: writeCaseMapping(root, { mapping: {}, reverse_mapping: {} });
|
|
219
213
|
|
|
220
|
-
const registered = registerCaseFolder(previous, root);
|
|
221
|
-
atomicWrite(configFile, `${JSON.stringify(registered.config, null, 2)}\n`);
|
|
222
|
-
|
|
223
214
|
const folderOverview = await caseOverview(path.dirname(root), homeDir, path.basename(root));
|
|
224
|
-
folderOverview.path =
|
|
215
|
+
folderOverview.path = entry.id;
|
|
225
216
|
folderOverview.location = root;
|
|
226
217
|
folderOverview.registered = true;
|
|
227
218
|
folderOverview.branches = await historyBranches(path.dirname(root), homeDir, path.basename(root));
|
|
@@ -237,20 +228,12 @@ async function registerLegalCase({
|
|
|
237
228
|
|
|
238
229
|
function defaultConfig(repoRoot, homeDir = path.join(os.homedir(), '.piecemaker')) {
|
|
239
230
|
return {
|
|
240
|
-
port: 43098,
|
|
241
231
|
pythonPath: null,
|
|
242
232
|
venvPath: path.join(homeDir, 'venv'),
|
|
243
|
-
adminTheme: 'light',
|
|
244
233
|
caseFolderStructure: { ...DEFAULT_CASE_FOLDER_STRUCTURE },
|
|
245
234
|
};
|
|
246
235
|
}
|
|
247
236
|
|
|
248
|
-
function validateAdminTheme(value) {
|
|
249
|
-
const theme = String(value || '');
|
|
250
|
-
if (theme !== 'light' && theme !== 'dark') throw new Error('Le thème doit être « light » ou « dark ».');
|
|
251
|
-
return theme;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
237
|
function readJson(file, fallback) {
|
|
255
238
|
try {
|
|
256
239
|
return fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) : fallback;
|
|
@@ -741,7 +724,6 @@ async function configurationOverview({ repoRoot, homeDir, userHome, getRuntimeSt
|
|
|
741
724
|
},
|
|
742
725
|
];
|
|
743
726
|
const models = await ollamaState(fetchImpl);
|
|
744
|
-
const telegram = getTelegramState({ repoRoot, homeDir, userHome });
|
|
745
727
|
|
|
746
728
|
// Moteurs Python locaux du venv — détection par présence de paquet, sans import
|
|
747
729
|
// (importer gliner2/mineru chargerait des centaines de Mo à chaque appel).
|
|
@@ -777,22 +759,11 @@ async function configurationOverview({ repoRoot, homeDir, userHome, getRuntimeSt
|
|
|
777
759
|
&& glinerModelReady;
|
|
778
760
|
const mineruReady = hasPackage('mineru') || hasPackage('magic_pdf')
|
|
779
761
|
|| fs.existsSync(path.join(venvDir, 'bin', 'mineru'));
|
|
780
|
-
const folders =
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
id: entry.id,
|
|
786
|
-
name: entry.name,
|
|
787
|
-
path: entry.root,
|
|
788
|
-
bot: bot ? {
|
|
789
|
-
id: bot.id,
|
|
790
|
-
name: bot.name,
|
|
791
|
-
configured: Boolean(bot.linked),
|
|
792
|
-
running: Boolean(bot.running),
|
|
793
|
-
} : null,
|
|
794
|
-
};
|
|
795
|
-
});
|
|
762
|
+
const folders = listProjectCases().map((entry) => ({
|
|
763
|
+
id: entry.id,
|
|
764
|
+
name: entry.name,
|
|
765
|
+
path: entry.root,
|
|
766
|
+
}));
|
|
796
767
|
|
|
797
768
|
return {
|
|
798
769
|
components: {
|
|
@@ -845,22 +816,6 @@ async function configurationOverview({ repoRoot, homeDir, userHome, getRuntimeSt
|
|
|
845
816
|
? 'OCR local · PDF scannés et images'
|
|
846
817
|
: 'Optionnel · non installé',
|
|
847
818
|
},
|
|
848
|
-
telegram: {
|
|
849
|
-
name: 'Telegram',
|
|
850
|
-
installed: true,
|
|
851
|
-
optional: true,
|
|
852
|
-
configured: Boolean(telegram.assistant.token.configured || telegram.monitor.token.configured),
|
|
853
|
-
summary: (() => {
|
|
854
|
-
const running = [telegram.assistant.running && 'Assistant', telegram.monitor.running && 'Surveillance'].filter(Boolean);
|
|
855
|
-
if (running.length) return `${running.join(' + ')} en ligne`;
|
|
856
|
-
if (telegram.assistant.token.configured || telegram.monitor.token.configured) return 'Configuré · arrêté';
|
|
857
|
-
return 'Aucun bot configuré';
|
|
858
|
-
})(),
|
|
859
|
-
bots: [
|
|
860
|
-
{ name: telegram.assistant.name, role: 'Assistant', configured: Boolean(telegram.assistant.token.configured), running: Boolean(telegram.assistant.running) },
|
|
861
|
-
{ name: telegram.monitor.name, role: 'Surveillance', configured: Boolean(telegram.monitor.token.configured), running: Boolean(telegram.monitor.running) },
|
|
862
|
-
],
|
|
863
|
-
},
|
|
864
819
|
},
|
|
865
820
|
models: {
|
|
866
821
|
provider: 'Ollama',
|
|
@@ -1584,9 +1539,8 @@ function finishAdminTiming(res, metric, startedAt, details = {}) {
|
|
|
1584
1539
|
// dans l'arborescence. Chaque dossier expose ses pièces originales — tout fichier
|
|
1585
1540
|
// qui n'est ni `.md` ni `.json` —, identifiées par leur chemin relatif au dossier.
|
|
1586
1541
|
async function listDossiers(repoRoot, homeDir) {
|
|
1587
|
-
const config = readRegistryConfig(path.join(homeDir, 'config.json'));
|
|
1588
1542
|
const dossiers = [];
|
|
1589
|
-
for (const entry of
|
|
1543
|
+
for (const entry of listProjectCases()) {
|
|
1590
1544
|
let originals;
|
|
1591
1545
|
try {
|
|
1592
1546
|
originals = await listOriginals(entry.root);
|
|
@@ -2045,11 +1999,10 @@ function createAdminRouter({
|
|
|
2045
1999
|
const envFile = path.join(repoRoot, '.env');
|
|
2046
2000
|
const registryConfig = () => readRegistryConfig(configFile);
|
|
2047
2001
|
const selectedCase = (reference) => {
|
|
2048
|
-
const
|
|
2049
|
-
const legalCase = resolveCaseReference(config, reference);
|
|
2002
|
+
const legalCase = resolveCaseReference(reference);
|
|
2050
2003
|
// Migration idempotente des dossiers enregistrés avant l'introduction de
|
|
2051
2004
|
// l'arborescence métier. Le manifeste fige les noms utilisés par ce dossier.
|
|
2052
|
-
ensureCaseFolderStructure(legalCase.root,
|
|
2005
|
+
ensureCaseFolderStructure(legalCase.root, registryConfig());
|
|
2053
2006
|
return legalCase;
|
|
2054
2007
|
};
|
|
2055
2008
|
|
|
@@ -2166,13 +2119,7 @@ function createAdminRouter({
|
|
|
2166
2119
|
const patch = req.body?.config || {};
|
|
2167
2120
|
const next = { ...current };
|
|
2168
2121
|
|
|
2169
|
-
if (patch.port !== undefined) {
|
|
2170
|
-
const port = Number(patch.port);
|
|
2171
|
-
if (!Number.isInteger(port) || port < 1024 || port > 65535) throw new Error('Le port doit être compris entre 1024 et 65535.');
|
|
2172
|
-
next.port = port;
|
|
2173
|
-
}
|
|
2174
2122
|
if (patch.pythonPath !== undefined) next.pythonPath = String(patch.pythonPath || '').trim() || null;
|
|
2175
|
-
if (patch.adminTheme !== undefined) next.adminTheme = validateAdminTheme(patch.adminTheme);
|
|
2176
2123
|
if (patch.caseFolderStructure !== undefined) {
|
|
2177
2124
|
next.caseFolderStructure = normalizeCaseFolderStructure({
|
|
2178
2125
|
...current.caseFolderStructure,
|
|
@@ -2421,8 +2368,7 @@ function createAdminRouter({
|
|
|
2421
2368
|
router.get('/repository', async (req, res) => {
|
|
2422
2369
|
const startedAt = performance.now();
|
|
2423
2370
|
try {
|
|
2424
|
-
const
|
|
2425
|
-
const entries = listConfiguredCases(config);
|
|
2371
|
+
const entries = listProjectCases();
|
|
2426
2372
|
const overview = {
|
|
2427
2373
|
name: 'PieceMaker',
|
|
2428
2374
|
root: '',
|
|
@@ -2444,21 +2390,6 @@ function createAdminRouter({
|
|
|
2444
2390
|
}
|
|
2445
2391
|
});
|
|
2446
2392
|
|
|
2447
|
-
router.post('/repository/cases', async (req, res) => {
|
|
2448
|
-
try {
|
|
2449
|
-
const selected = await pickFolder(process.platform, userHome);
|
|
2450
|
-
if (!selected) return res.json({ ok: true, cancelled: true });
|
|
2451
|
-
const result = await registerLegalCase({
|
|
2452
|
-
folder: selected,
|
|
2453
|
-
configFile,
|
|
2454
|
-
homeDir,
|
|
2455
|
-
});
|
|
2456
|
-
res.status(201).json({ ok: true, ...result });
|
|
2457
|
-
} catch (error) {
|
|
2458
|
-
res.status(400).json({ error: error.message });
|
|
2459
|
-
}
|
|
2460
|
-
});
|
|
2461
|
-
|
|
2462
2393
|
router.get('/repository/case', async (req, res) => {
|
|
2463
2394
|
const startedAt = performance.now();
|
|
2464
2395
|
try {
|
|
@@ -2980,42 +2911,6 @@ function createAdminRouter({
|
|
|
2980
2911
|
}
|
|
2981
2912
|
});
|
|
2982
2913
|
|
|
2983
|
-
router.get('/telegram', (req, res) => {
|
|
2984
|
-
res.json(getTelegramState({ repoRoot, homeDir, userHome }));
|
|
2985
|
-
});
|
|
2986
|
-
|
|
2987
|
-
router.put('/telegram', (req, res) => {
|
|
2988
|
-
try {
|
|
2989
|
-
res.json({ ok: true, ...saveTelegramConfig({ repoRoot, homeDir, userHome }, req.body) });
|
|
2990
|
-
} catch (error) {
|
|
2991
|
-
res.status(400).json({ error: error.message });
|
|
2992
|
-
}
|
|
2993
|
-
});
|
|
2994
|
-
|
|
2995
|
-
router.post('/telegram/:role/:action', (req, res) => {
|
|
2996
|
-
try {
|
|
2997
|
-
res.json(controlTelegram({ repoRoot, homeDir, userHome }, req.params.role, req.params.action));
|
|
2998
|
-
} catch (error) {
|
|
2999
|
-
res.status(400).json({ error: error.message });
|
|
3000
|
-
}
|
|
3001
|
-
});
|
|
3002
|
-
|
|
3003
|
-
router.put('/telegram/dossiers/:id', (req, res) => {
|
|
3004
|
-
try {
|
|
3005
|
-
res.json({ ok: true, dossier: saveDossierBot({ repoRoot, homeDir, userHome }, req.params.id, req.body) });
|
|
3006
|
-
} catch (error) {
|
|
3007
|
-
res.status(400).json({ error: error.message });
|
|
3008
|
-
}
|
|
3009
|
-
});
|
|
3010
|
-
|
|
3011
|
-
router.post('/telegram/dossiers/:id/:action', (req, res) => {
|
|
3012
|
-
try {
|
|
3013
|
-
res.json(controlDossierBot({ repoRoot, homeDir, userHome }, req.params.id, req.params.action));
|
|
3014
|
-
} catch (error) {
|
|
3015
|
-
res.status(400).json({ error: error.message });
|
|
3016
|
-
}
|
|
3017
|
-
});
|
|
3018
|
-
|
|
3019
2914
|
return router;
|
|
3020
2915
|
}
|
|
3021
2916
|
|
|
@@ -3057,5 +2952,4 @@ module.exports = {
|
|
|
3057
2952
|
saveManagedFile,
|
|
3058
2953
|
selectLocalFolder,
|
|
3059
2954
|
updateEnvFile,
|
|
3060
|
-
validateAdminTheme,
|
|
3061
2955
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Legal-case registry: every CloudCLI project published by the server is a case. */
|
|
2
2
|
const crypto = require('node:crypto');
|
|
3
3
|
const fs = require('node:fs');
|
|
4
4
|
const path = require('node:path');
|
|
@@ -6,10 +6,7 @@ const path = require('node:path');
|
|
|
6
6
|
const {
|
|
7
7
|
isTechnicalCaseDirectoryName,
|
|
8
8
|
} = require('../piecemaker-plugin/scripts/lib/commits.cjs');
|
|
9
|
-
const {
|
|
10
|
-
configuredWatchPaths,
|
|
11
|
-
registeredCaseFolders,
|
|
12
|
-
} = require('../piecemaker-plugin/scripts/lib/case-folders.cjs');
|
|
9
|
+
const { registeredProjectFolders } = require('../piecemaker-plugin/scripts/lib/case-folders.cjs');
|
|
13
10
|
|
|
14
11
|
function readRegistryConfig(configFile) {
|
|
15
12
|
try {
|
|
@@ -25,8 +22,8 @@ function caseFolderId(folder) {
|
|
|
25
22
|
return `folder-${digest}`;
|
|
26
23
|
}
|
|
27
24
|
|
|
28
|
-
function
|
|
29
|
-
return
|
|
25
|
+
function projectEntries() {
|
|
26
|
+
return registeredProjectFolders().map((root) => ({
|
|
30
27
|
id: caseFolderId(root),
|
|
31
28
|
name: path.basename(root),
|
|
32
29
|
root,
|
|
@@ -36,22 +33,21 @@ function explicitEntries(config) {
|
|
|
36
33
|
}));
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
* longer a workspace root whose immediate children are listed automatically —
|
|
42
|
-
* a matter appears once it has been registered from the admin panel.
|
|
43
|
-
*/
|
|
44
|
-
function listConfiguredCases(config) {
|
|
45
|
-
return explicitEntries(config).sort((a, b) =>
|
|
36
|
+
function listProjectCases() {
|
|
37
|
+
return projectEntries().sort((a, b) =>
|
|
46
38
|
a.name.localeCompare(b.name, 'fr') || a.root.localeCompare(b.root, 'fr'));
|
|
47
39
|
}
|
|
48
40
|
|
|
49
|
-
function resolveCaseReference(
|
|
41
|
+
function resolveCaseReference(reference) {
|
|
50
42
|
const token = String(reference || '').trim();
|
|
51
43
|
if (!token) throw new Error('Dossier juridique invalide.');
|
|
52
|
-
const
|
|
53
|
-
if (!
|
|
54
|
-
return
|
|
44
|
+
const entry = projectEntries().find((candidate) => candidate.id === token);
|
|
45
|
+
if (!entry) throw new Error('Ce dossier juridique n’est pas un projet enregistré.');
|
|
46
|
+
return entry;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function projectCaseEntry(root) {
|
|
50
|
+
return projectEntries().find((entry) => entry.root === root) || null;
|
|
55
51
|
}
|
|
56
52
|
|
|
57
53
|
function validateSelectedCaseFolder(folder) {
|
|
@@ -71,23 +67,11 @@ function validateSelectedCaseFolder(folder) {
|
|
|
71
67
|
return root;
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
function registerCaseFolder(config, folder) {
|
|
75
|
-
const root = validateSelectedCaseFolder(folder);
|
|
76
|
-
const existing = registeredCaseFolders(config);
|
|
77
|
-
const caseFolders = [...new Set([...existing, root])];
|
|
78
|
-
const next = { ...config, caseFolders };
|
|
79
|
-
next.anonymization = {
|
|
80
|
-
...(config?.anonymization || {}),
|
|
81
|
-
watchPaths: configuredWatchPaths(next),
|
|
82
|
-
};
|
|
83
|
-
return { config: next, entry: explicitEntries(next).find((item) => item.root === root) };
|
|
84
|
-
}
|
|
85
|
-
|
|
86
70
|
module.exports = {
|
|
87
71
|
caseFolderId,
|
|
88
|
-
|
|
72
|
+
listProjectCases,
|
|
73
|
+
projectCaseEntry,
|
|
89
74
|
readRegistryConfig,
|
|
90
|
-
registerCaseFolder,
|
|
91
75
|
resolveCaseReference,
|
|
92
76
|
validateSelectedCaseFolder,
|
|
93
77
|
};
|
|
@@ -10,9 +10,6 @@
|
|
|
10
10
|
const fs = require('fs');
|
|
11
11
|
const path = require('path');
|
|
12
12
|
|
|
13
|
-
/** Racine du dépôt git, quatre niveaux au-dessus de ce fichier vendorisé. */
|
|
14
|
-
const GIT_REPO_ROOT = path.resolve(__dirname, '..', '..', '..', '..');
|
|
15
|
-
|
|
16
13
|
const DEPRECATED_HOOKS = new Set([
|
|
17
14
|
'anonymize-read.mjs',
|
|
18
15
|
'deanonymize-write.mjs',
|
|
@@ -231,74 +228,6 @@ function installClaudeHooks(repoRoot, userHome) {
|
|
|
231
228
|
return { ok: true, changed: changed || cleanup.changed, registered, settings: target, cleanup };
|
|
232
229
|
}
|
|
233
230
|
|
|
234
|
-
/**
|
|
235
|
-
* Sentinelle SessionStart (proxy PII) — script unique, partagé avec Codex,
|
|
236
|
-
* hors de piecemaker-plugin/ (voir scripts/piecemaker/hooks/proxy-guard.mjs).
|
|
237
|
-
* Non sourcée depuis hooks.json : son placeholder ${CLAUDE_PLUGIN_ROOT} ne
|
|
238
|
-
* peut pas désigner un script qui n'est délibérément pas vendorisé.
|
|
239
|
-
*/
|
|
240
|
-
function sessionHookScriptPath() {
|
|
241
|
-
return path.join(GIT_REPO_ROOT, 'scripts', 'piecemaker', 'hooks', 'proxy-guard.mjs');
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function sessionHookCommand() {
|
|
245
|
-
return `node "${sessionHookScriptPath().replaceAll('"', '\\"')}"`;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function isOwnSessionHook(hook) {
|
|
249
|
-
const command = typeof hook?.command === 'string' ? hook.command : '';
|
|
250
|
-
return command.includes('proxy-guard.mjs');
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function claudeSessionHookStatus(userHome) {
|
|
254
|
-
const target = settingsPath(userHome);
|
|
255
|
-
const command = sessionHookCommand();
|
|
256
|
-
if (!fs.existsSync(target)) return { ok: false, reason: 'settings-absent', command };
|
|
257
|
-
const settings = readJson(target);
|
|
258
|
-
if (!settings) return { ok: false, reason: 'settings-invalide', command };
|
|
259
|
-
const groups = Array.isArray(settings.hooks?.SessionStart) ? settings.hooks.SessionStart : [];
|
|
260
|
-
const managed = groups.flatMap((group) => Array.isArray(group?.hooks) ? group.hooks : []).filter(isOwnSessionHook);
|
|
261
|
-
const exact = groups.some((group) => group?.matcher === 'startup|resume|clear'
|
|
262
|
-
&& Array.isArray(group.hooks)
|
|
263
|
-
&& group.hooks.some((hook) => hook?.type === 'command' && hook.command === command));
|
|
264
|
-
return { ok: exact && managed.length === 1, reason: exact && managed.length === 1 ? '' : 'hook-absent-ou-perime', command };
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/** Fusionne uniquement la sentinelle SessionStart ; tous les hooks personnels sont conservés. */
|
|
268
|
-
function installClaudeSessionHook(userHome) {
|
|
269
|
-
const target = settingsPath(userHome);
|
|
270
|
-
const command = sessionHookCommand();
|
|
271
|
-
|
|
272
|
-
let settings = {};
|
|
273
|
-
if (fs.existsSync(target)) {
|
|
274
|
-
settings = readJson(target);
|
|
275
|
-
if (!settings) return { ok: false, changed: false, reason: 'settings-invalide', command, settings: target };
|
|
276
|
-
}
|
|
277
|
-
if (!settings.hooks || typeof settings.hooks !== 'object' || Array.isArray(settings.hooks)) settings.hooks = {};
|
|
278
|
-
|
|
279
|
-
const groups = Array.isArray(settings.hooks.SessionStart) ? settings.hooks.SessionStart : [];
|
|
280
|
-
const preserved = [];
|
|
281
|
-
for (const group of groups) {
|
|
282
|
-
if (!group || typeof group !== 'object' || Array.isArray(group)) {
|
|
283
|
-
preserved.push(group);
|
|
284
|
-
continue;
|
|
285
|
-
}
|
|
286
|
-
const hooks = Array.isArray(group.hooks) ? group.hooks.filter((hook) => !isOwnSessionHook(hook)) : [];
|
|
287
|
-
if (hooks.length || !Array.isArray(group.hooks)) preserved.push({ ...group, hooks });
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const status = claudeSessionHookStatus(userHome);
|
|
291
|
-
if (status.ok) return { ok: true, changed: false, command, settings: target };
|
|
292
|
-
|
|
293
|
-
settings.hooks.SessionStart = [...preserved, {
|
|
294
|
-
matcher: 'startup|resume|clear',
|
|
295
|
-
hooks: [{ type: 'command', command, timeout: 45 }],
|
|
296
|
-
}];
|
|
297
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
298
|
-
fs.writeFileSync(target, `${JSON.stringify(settings, null, 2)}\n`, 'utf8');
|
|
299
|
-
return { ok: true, changed: true, command, settings: target };
|
|
300
|
-
}
|
|
301
|
-
|
|
302
231
|
/**
|
|
303
232
|
* statusLine Claude Code — même logique de matérialisation que les hooks,
|
|
304
233
|
* mais pour une clé unique de settings.json (`statusLine`) plutôt qu'un
|
|
@@ -371,11 +300,9 @@ function installClaudeStatusLine(repoRoot, userHome) {
|
|
|
371
300
|
|
|
372
301
|
module.exports = {
|
|
373
302
|
claudeHooksStatus,
|
|
374
|
-
claudeSessionHookStatus,
|
|
375
303
|
claudeStatusLineStatus,
|
|
376
304
|
directHookGroups,
|
|
377
305
|
installClaudeHooks,
|
|
378
|
-
installClaudeSessionHook,
|
|
379
306
|
installClaudeStatusLine,
|
|
380
307
|
removeDeprecatedHooks,
|
|
381
308
|
settingsPath,
|
|
@@ -45,11 +45,6 @@ const {
|
|
|
45
45
|
// Vocabulaire des sigles de sociétés (SA_1, SARL_1, PERS_MORALE_1…), miroir de
|
|
46
46
|
// `_LEGAL_FORMS` (scan_utils.py) — sert à classer un code déjà attribué.
|
|
47
47
|
const { isSocieteCode, societeCounterKey, detectCompanySigle, LEGAL_FORM_TOKENS } = require('./legal-forms.cjs');
|
|
48
|
-
// À chaque enregistrement d'un mapping de dossier, le mapping central global est
|
|
49
|
-
// reconstruit et dé-conflicté : c'est lui que le hook central applique à toute
|
|
50
|
-
// lecture, dossier ou non. `syncCentralMapping` ne jette jamais — un central qui
|
|
51
|
-
// échoue ne doit pas faire échouer la sauvegarde du dossier.
|
|
52
|
-
const { syncCentralMapping } = require('../piecemaker-plugin/scripts/lib/central-mapping.cjs');
|
|
53
48
|
|
|
54
49
|
const SCRIPTS_DIR = path.join(__dirname, 'scripts');
|
|
55
50
|
const PIECEMAKER_HOME = path.join(os.homedir(), '.piecemaker');
|
|
@@ -154,8 +149,6 @@ function writeCaseMapping(caseRoot, document) {
|
|
|
154
149
|
fs.unlinkSync(full);
|
|
155
150
|
}
|
|
156
151
|
}
|
|
157
|
-
// Le mapping central reflète désormais ce dossier. Best-effort et jamais bloquant.
|
|
158
|
-
try { syncCentralMapping(); } catch { /* le central ne doit pas bloquer une sauvegarde */ }
|
|
159
152
|
return { file, exists: true, ignored: payload.ignored || [], ...payload };
|
|
160
153
|
}
|
|
161
154
|
|
|
@@ -26,6 +26,8 @@ from collections import defaultdict
|
|
|
26
26
|
from importlib.metadata import PackageNotFoundError, version as package_version
|
|
27
27
|
from typing import Dict, List, Optional
|
|
28
28
|
|
|
29
|
+
os.environ["HF_HUB_OFFLINE"] = "1"
|
|
30
|
+
|
|
29
31
|
# ---------------------------------------------------------------------------
|
|
30
32
|
# Heavy imports — these are the expensive ones (~30-60s)
|
|
31
33
|
# ---------------------------------------------------------------------------
|