@piecemaker-legal/piecemaker 1.1.1 → 2.0.1
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/{abnfDiagram-VCTEODGH-DEXWh3LH.js → abnfDiagram-VCTEODGH-C2JDmlZx.js} +1 -1
- package/dist/assets/{arc-CoTRLXKW.js → arc-XhSg5Mrj.js} +1 -1
- package/dist/assets/{architectureDiagram-5GKGNRK7-Cg-jO9oR.js → architectureDiagram-5GKGNRK7-DKREuXxk.js} +1 -1
- package/dist/assets/{blockDiagram-I7D4REHJ-ChXwQSIq.js → blockDiagram-I7D4REHJ-CNK0Tp5d.js} +1 -1
- package/dist/assets/{c4Diagram-7LVT6UL2-Bw2VGggd.js → c4Diagram-7LVT6UL2-C8fJzWVp.js} +1 -1
- package/dist/assets/channel-DO5hoFdU.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-C1WdqrLP.js → chunk-2Q5K7J3B-DlE8nLJo.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-BerUZBa1.js → chunk-5VM5RSS4-CSm-2TZ4.js} +1 -1
- package/dist/assets/{chunk-F27PBJKO-5W7ax2gB.js → chunk-F27PBJKO-CSgnXT2c.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-JgDN1h4T.js → chunk-IMKFNOWR-C6bkt6C1.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-ulNHnEdQ.js → chunk-JWPE2WC7-jUR52MBO.js} +1 -1
- package/dist/assets/{chunk-POPQ4Y6H-D4aTDC2T.js → chunk-POPQ4Y6H-D0UAL7O7.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-BA5zX4XF.js → chunk-SVP7TREG-C9dtOEii.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-DhOULVhX.js → chunk-TICWLB2K-BEzWKT39.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-CkpCgrVg.js → chunk-XXDRQBXY-uD1oklVY.js} +1 -1
- package/dist/assets/classDiagram-ZZMXUADV-BsQtwznI.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-BsQtwznI.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-0xUSfjfV.js → cose-bilkent-JH36ORCC-aGjlSdMe.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-BE6fNu2_.js → cynefin-OW5HDTMX-D3G4OYOn.js} +1 -1
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-rFMnZ9b3.js → cynefinDiagram-5FMLGOSQ-9swRDUnu.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-C1p4ffd7.js → dagre-GXQ25YYZ-lvaAGdqY.js} +1 -1
- package/dist/assets/{diagram-S7CK7UJ4-BV_3Xj4O.js → diagram-S7CK7UJ4-BaZ6YIkR.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-Bb_Evkrm.js → diagram-UQ7AKVKN-COJ2Gb38.js} +1 -1
- package/dist/assets/{diagram-VSXAHHWV-BzgupjxD.js → diagram-VSXAHHWV-CYZEkbzP.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-D1c67z76.js → diagram-VX7I27RA-fFeQJ4ae.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-DsJAJGKE.js → diagram-Z3DM3KII-B7knszDV.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-B1ge_obq.js → ebnfDiagram-PWID7BFC-Dk0l329Y.js} +1 -1
- package/dist/assets/{erDiagram-RLTQ6QDP-DrV-tggw.js → erDiagram-RLTQ6QDP-CtpYxui8.js} +1 -1
- package/dist/assets/{flowDiagram-HODETNUW-CVzDiSQ3.js → flowDiagram-HODETNUW-aVWueRJD.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-CGRdSN9D.js → ganttDiagram-EL5Y4UJY-DfrX-B7p.js} +1 -1
- package/dist/assets/{gitGraphDiagram-WWUBYQGX-CAfvFXzL.js → gitGraphDiagram-WWUBYQGX-BFB1ZPF3.js} +1 -1
- package/dist/assets/{index-DaxH81ZJ.js → index-DqRygn9E.js} +170 -169
- package/dist/assets/index-Ds4HaAjz.css +1 -0
- package/dist/assets/{infoDiagram-27XIBGKW-DTshEkGK.js → infoDiagram-27XIBGKW-CuYkzm43.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-DkbshVxp.js → ishikawaDiagram-5VMMS53U-EMiw8Akh.js} +1 -1
- package/dist/assets/{journeyDiagram-3NMN7TZE-v5qE8xpn.js → journeyDiagram-3NMN7TZE-DCoLV1f8.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-a9CNMFLt.js → kanban-definition-UXKFOSKX-CyA4Yinu.js} +1 -1
- package/dist/assets/{layout-DrW4R1TH.js → layout-BlaB0grA.js} +1 -1
- package/dist/assets/{linear-Cs3qpXT_.js → linear-DLX3dJDH.js} +1 -1
- package/dist/assets/{mermaid.core-C7Ti-Fty.js → mermaid.core-Cy51CT89.js} +6 -6
- package/dist/assets/{mindmap-definition-YA3MSWOX-B0VDdIcG.js → mindmap-definition-YA3MSWOX-OBXjfL7I.js} +1 -1
- package/dist/assets/{pegDiagram-XKGWAZYB-CV1L7MjP.js → pegDiagram-XKGWAZYB-C_BJjUh1.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-DSCuzVTV.js → pieDiagram-E7YTZNPT-jIpbr3Fi.js} +1 -1
- package/dist/assets/{quadrantDiagram-AXDQQJYC-hzX-9AKo.js → quadrantDiagram-AXDQQJYC-C1A15xI5.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-BbmzIqcp.js → railroadDiagram-O6MQD6OU-Rslzn1pI.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-CQCRRBSL.js → requirementDiagram-BXWQKSXE-LlfURO5-.js} +1 -1
- package/dist/assets/{sankeyDiagram-P5KCCOFB-kiaLcW6X.js → sankeyDiagram-P5KCCOFB-B5BPF4-O.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-Bgx8ST7Q.js → sequenceDiagram-WJ2MYXX4-orYZe9zX.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-BTjJ-ygN.js → sizeCapture-INFHLROL-Co-K5Cfb.js} +1 -1
- package/dist/assets/{stateDiagram-D77RDMKH-D48RR1FL.js → stateDiagram-D77RDMKH-COEx1aH2.js} +1 -1
- package/dist/assets/{stateDiagram-v2-MP3YSRHH-B-XwSR-z.js → stateDiagram-v2-MP3YSRHH-DaeTZvmy.js} +1 -1
- package/dist/assets/{swimlanes-42K2YHIH-BhE-QuEZ.js → swimlanes-42K2YHIH-BHQaDhfZ.js} +1 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-BHW8q5M5.js +8 -0
- package/dist/assets/{timeline-definition-24CTP7MA-Cm7EUWWt.js → timeline-definition-24CTP7MA-COqCRwGX.js} +1 -1
- package/dist/assets/{vennDiagram-4TSXK5OY-X-nC9wZ0.js → vennDiagram-4TSXK5OY-nym5XSnr.js} +1 -1
- package/dist/assets/{wardleyDiagram-VM6X3IG4-D33YvEQZ.js → wardleyDiagram-VM6X3IG4-DEPPey_W.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-lziwBKsM.js → xychartDiagram-S5SC5T6Z-uSJ404kL.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/sw.js +1 -1
- package/dist-server/server/index.js +3 -1
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/piecemaker/index.js +7 -3
- package/dist-server/server/piecemaker/index.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/index.js +13 -6
- package/dist-server/server/piecemaker/knowledge/index.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/local-routes.js +55 -0
- package/dist-server/server/piecemaker/knowledge/local-routes.js.map +1 -0
- package/dist-server/server/piecemaker/knowledge/scan-jobs.js +3 -1
- package/dist-server/server/piecemaker/knowledge/scan-jobs.js.map +1 -1
- package/dist-server/server/piecemaker/library/index.js +14 -41
- package/dist-server/server/piecemaker/library/index.js.map +1 -1
- package/dist-server/server/piecemaker/library/store.js +11 -3
- package/dist-server/server/piecemaker/library/store.js.map +1 -1
- package/dist-server/server/piecemaker/library/workspace-installation.js +26 -3
- package/dist-server/server/piecemaker/library/workspace-installation.js.map +1 -1
- package/dist-server/server/piecemaker/timesheet/service.js +8 -7
- package/dist-server/server/piecemaker/timesheet/service.js.map +1 -1
- package/dist-server/server/piecemaker/timesheet/store.js +5 -3
- package/dist-server/server/piecemaker/timesheet/store.js.map +1 -1
- package/package.json +1 -1
- package/product.config.json +2 -0
- package/scripts/piecemaker/build-app-icon.py +88 -0
- package/scripts/piecemaker/cli/lib/piecemaker-anonymizer.mjs +2 -2
- package/scripts/piecemaker/hooks/proxy-guard.mjs +19 -54
- package/scripts/release/assert-piecemaker-version.mjs +25 -0
- package/server/index.ts +4 -1
- package/server/piecemaker/anonymizer/client-config.cjs +45 -162
- package/server/piecemaker/anonymizer/hudsucker-fixture.cjs +127 -0
- package/server/piecemaker/anonymizer/hudsucker-proxy/Cargo.lock +2396 -0
- package/server/piecemaker/anonymizer/hudsucker-proxy/Cargo.toml +14 -0
- package/server/piecemaker/anonymizer/hudsucker-proxy/src/main.rs +501 -0
- package/server/piecemaker/anonymizer/providers.cjs +14 -135
- package/server/piecemaker/anonymizer/rewriter-bridge.cjs +221 -0
- package/server/piecemaker/anonymizer/service.cjs +144 -28
- package/server/piecemaker/index.ts +8 -3
- package/server/piecemaker/knowledge/index.ts +14 -6
- package/server/piecemaker/knowledge/local-routes.ts +72 -0
- package/server/piecemaker/knowledge/scan-jobs.ts +4 -1
- package/server/piecemaker/library/index.ts +14 -34
- package/server/piecemaker/library/store.ts +11 -3
- package/server/piecemaker/library/workspace-installation.ts +20 -3
- package/server/piecemaker/timesheet/service.ts +9 -7
- package/server/piecemaker/timesheet/store.ts +5 -3
- package/server/piecemaker/vendor/installer/assets/claude-hooks/piecemaker-guard-secrets.mjs +0 -1
- package/server/piecemaker/vendor/installer/assets/piecemaker.icns +0 -0
- package/server/piecemaker/vendor/installer/assets/piecemaker.ico +0 -0
- package/server/piecemaker/vendor/installer/bin/piecemaker.mjs +56 -206
- package/server/piecemaker/vendor/installer/lib/commandes.mjs +2 -4
- package/server/piecemaker/vendor/installer/lib/conversion-client.mjs +74 -0
- package/server/piecemaker/vendor/installer/lib/service.mjs +4 -358
- package/server/piecemaker/vendor/installer/lib/state.mjs +0 -6
- package/server/piecemaker/vendor/installer/steps/03-python-gliner.mjs +4 -4
- package/server/piecemaker/vendor/installer/steps/09-claude-assets.mjs +0 -31
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/statusline.mjs +3 -4
- package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +1 -49
- package/server/piecemaker/vendor/websocket-server/claude-hooks.cjs +14 -12
- package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +17 -476
- package/server/piecemaker/vendor/websocket-server/scripts/convert_and_scan_pipeline.py +2 -2
- package/server/piecemaker/vendor/websocket-server/scripts/mineru_improved_1.py +11 -2
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/scanner_worker.py +13 -37
- package/server/piecemaker/vendor/websocket-server/scripts/requirements.txt +1 -7
- package/server/piecemaker/vendor/websocket-server/scripts/warmup.py +14 -85
- package/dist/assets/channel-DdzrPZ6Y.js +0 -1
- package/dist/assets/classDiagram-ZZMXUADV-Dim2o8E5.js +0 -1
- package/dist/assets/classDiagram-v2-VYDZK3BY-Dim2o8E5.js +0 -1
- package/dist/assets/index-D_Dc_nQv.css +0 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-DR525d5V.js +0 -8
- package/server/piecemaker/anonymizer/proxy.cjs +0 -365
- package/server/piecemaker/vendor/installer/assets/PieceMakerApp.swift +0 -189
- package/server/piecemaker/vendor/installer/lib/desktop-launcher.mjs +0 -305
- package/server/piecemaker/vendor/installer/steps/05-certificats.mjs +0 -171
- package/server/piecemaker/vendor/installer/steps/14-mxc-sandbox.mjs +0 -271
- package/server/piecemaker/vendor/installer/steps/15-pwa-desktop.mjs +0 -64
- package/server/piecemaker/vendor/installer/templates/root-CLAUDE.md +0 -56
- package/server/piecemaker/vendor/installer/templates/workspace-CLAUDE.md +0 -52
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
10
10
|
* piecemaker menu interactif
|
|
11
|
-
* piecemaker open démarre le serveur et ouvre l'interface web
|
|
12
|
-
* piecemaker start|stop|restart gère le serveur local
|
|
13
|
-
* piecemaker status|logs affiche l'état ou les journaux
|
|
14
11
|
* piecemaker chronology affiche la chronologie du dossier courant
|
|
15
12
|
* piecemaker chronology write --path <pièce> --correction-json <json>
|
|
16
13
|
* crée une correction de chronologie pour une pièce
|
|
@@ -35,21 +32,12 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
35
32
|
|
|
36
33
|
import { banner, title, log, write, blank, summary, spinner, badge, c } from '../lib/ui.mjs';
|
|
37
34
|
import { select, confirm, multiSelect, pause, nonInteractive } from '../lib/prompt.mjs';
|
|
38
|
-
import { HOME_DIR, REPO_ROOT, commandExists, findPython
|
|
35
|
+
import { GIT_REPO_ROOT, HOME_DIR, REPO_ROOT, commandExists, findPython } from '../lib/platform.mjs';
|
|
39
36
|
import { COMMANDS, CHRONOLOGY_ACTIONS } from '../lib/commandes.mjs';
|
|
40
37
|
import { loadConfig, readEnv, markStep, loadState, CONFIG_FILE } from '../lib/state.mjs';
|
|
41
38
|
import { scheduleStepResume, selectStepsToResume } from '../lib/resume-steps.mjs';
|
|
42
|
-
import {
|
|
43
|
-
|
|
44
|
-
openAdmin,
|
|
45
|
-
readLogs,
|
|
46
|
-
restartTelegramDaemon,
|
|
47
|
-
startServer,
|
|
48
|
-
stopServer,
|
|
49
|
-
checkForUpdate,
|
|
50
|
-
updateRepository,
|
|
51
|
-
depositRootClaudeMd,
|
|
52
|
-
} from '../lib/service.mjs';
|
|
39
|
+
import { appServerPort, readLocalScanJob, startLocalScan } from '../lib/conversion-client.mjs';
|
|
40
|
+
import { restartTelegramDaemon, checkForUpdate, updateRepository } from '../lib/service.mjs';
|
|
53
41
|
|
|
54
42
|
const require = createRequire(import.meta.url);
|
|
55
43
|
const CLAUDE_ASSETS_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/claude-assets.cjs');
|
|
@@ -58,6 +46,7 @@ const CENTRAL_MAPPING_MODULE = path.resolve(path.dirname(fileURLToPath(import.me
|
|
|
58
46
|
const DOCUMENT_INDEX_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/document-index.cjs');
|
|
59
47
|
const CASE_INSTRUCTIONS_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/case-instructions.cjs');
|
|
60
48
|
const ORIGINALS_PIPELINE_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/originals-pipeline.cjs');
|
|
49
|
+
const APP_CLI_LIB = path.join(GIT_REPO_ROOT, 'scripts', 'piecemaker', 'cli', 'lib');
|
|
61
50
|
|
|
62
51
|
/**
|
|
63
52
|
* The bootstrap/update command is also distributed as an installer-only
|
|
@@ -87,17 +76,17 @@ function loadCentralMappingIntegration() {
|
|
|
87
76
|
function reconcileCentralMapping() {
|
|
88
77
|
let hooksRemoved = false;
|
|
89
78
|
const claude = loadClaudeIntegrations();
|
|
90
|
-
if (typeof claude?.
|
|
91
|
-
const cleanup = claude.
|
|
79
|
+
if (typeof claude?.removeDeprecatedHooks === 'function') {
|
|
80
|
+
const cleanup = claude.removeDeprecatedHooks(os.homedir());
|
|
92
81
|
hooksRemoved = Boolean(cleanup.changed);
|
|
93
|
-
if (!cleanup.ok) log.warn(`
|
|
94
|
-
else if (cleanup.changed) log.ok('
|
|
82
|
+
if (!cleanup.ok) log.warn(`Hooks hérités non nettoyés (${cleanup.reason}).`);
|
|
83
|
+
else if (cleanup.changed) log.ok('Hooks hérités Claude Code retirés.');
|
|
95
84
|
}
|
|
96
85
|
|
|
97
86
|
const integration = loadCentralMappingIntegration();
|
|
98
87
|
const central = integration?.syncCentralMapping(loadConfig());
|
|
99
88
|
if (central) log.ok(`Mapping central du proxy reconstruit (${central.entities || 0} entité(s)).`);
|
|
100
|
-
else log.warn('Mapping central du proxy non reconstruit ; relancez « piecemaker
|
|
89
|
+
else log.warn('Mapping central du proxy non reconstruit ; relancez « piecemaker ».');
|
|
101
90
|
return hooksRemoved;
|
|
102
91
|
}
|
|
103
92
|
|
|
@@ -118,28 +107,6 @@ function reconcileCaseInstructions() {
|
|
|
118
107
|
}
|
|
119
108
|
}
|
|
120
109
|
|
|
121
|
-
/** Rejoue la partie non interactive de l'étape 15 après une mise à jour, mais
|
|
122
|
-
* seulement pour une application Bureau déjà installée. Le chargement reste
|
|
123
|
-
* dynamique : il intervient après le reset Git et utilise donc la nouvelle
|
|
124
|
-
* version de l'étape qui vient d'être téléchargée. */
|
|
125
|
-
async function refreshDesktopApplicationAfterUpdate() {
|
|
126
|
-
const stepPath = path.join(STEPS_DIR, '15-pwa-desktop.mjs');
|
|
127
|
-
if (!fs.existsSync(stepPath)) return false;
|
|
128
|
-
try {
|
|
129
|
-
const step = await import(`${pathToFileURL(stepPath).href}?update=${Date.now()}`);
|
|
130
|
-
if (typeof step.refreshInstalledDesktopApplication !== 'function') return false;
|
|
131
|
-
const result = await step.refreshInstalledDesktopApplication();
|
|
132
|
-
if (result.status !== 'skipped') markStep('15-pwa-desktop', result.status, result.note || '');
|
|
133
|
-
if (result.status === 'done') log.ok('Application PieceMaker sur le Bureau mise à jour.');
|
|
134
|
-
else if (result.status === 'partial') log.warn(`Application Bureau partiellement mise à jour : ${result.note}`);
|
|
135
|
-
else if (result.status === 'failed') log.warn(`Application Bureau non mise à jour : ${result.note}`);
|
|
136
|
-
return result.status === 'done';
|
|
137
|
-
} catch (error) {
|
|
138
|
-
log.warn(`Application Bureau non mise à jour (${error.message}).`);
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
110
|
/**
|
|
144
111
|
* Reprend en tâche de fond les étapes d'installation restées incomplètes.
|
|
145
112
|
*
|
|
@@ -381,12 +348,6 @@ async function runCheck(steps, ctx) {
|
|
|
381
348
|
function printHelp() {
|
|
382
349
|
write(` ${c.bold('piecemaker')} — PieceMaker local`);
|
|
383
350
|
blank();
|
|
384
|
-
write(' open démarre le serveur et ouvre l’interface web');
|
|
385
|
-
write(' start démarre le serveur local en arrière-plan');
|
|
386
|
-
write(' stop arrête le serveur local');
|
|
387
|
-
write(' restart redémarre le serveur local');
|
|
388
|
-
write(' status affiche l’état du serveur');
|
|
389
|
-
write(' logs affiche les dernières lignes du journal');
|
|
390
351
|
write(' chronology [read] affiche la chronologie pseudonymisée du dossier courant');
|
|
391
352
|
write(' chronology write --path <pièce> --correction-json <json> crée une correction de chronologie');
|
|
392
353
|
write(' chronology edit --path <pièce> --correction-json <json> modifie une correction existante');
|
|
@@ -449,17 +410,6 @@ async function installerMenu(steps, ctx, { allowBack = false } = {}) {
|
|
|
449
410
|
}
|
|
450
411
|
}
|
|
451
412
|
|
|
452
|
-
function printServerStatus(status) {
|
|
453
|
-
title('État local');
|
|
454
|
-
const rows = [
|
|
455
|
-
['Serveur HTTPS', status.running ? badge.done : badge.todo, status.running ? `PID ${status.pid || 'externe'}` : 'arrêté'],
|
|
456
|
-
['Interface web', status.running ? badge.done : badge.todo, status.url],
|
|
457
|
-
['Journal', badge.todo, status.logFile],
|
|
458
|
-
];
|
|
459
|
-
summary(rows);
|
|
460
|
-
blank();
|
|
461
|
-
}
|
|
462
|
-
|
|
463
413
|
function formatChronologyText(chronology) {
|
|
464
414
|
const lines = [];
|
|
465
415
|
lines.push(`Chronologie : ${chronology.stats.documents} pièce(s), ${chronology.stats.dated} datée(s), ${chronology.stats.entities} entité(s).`);
|
|
@@ -626,139 +576,99 @@ function publicConversionResult(job) {
|
|
|
626
576
|
return {
|
|
627
577
|
id: job?.id || null,
|
|
628
578
|
state: job?.state || 'error',
|
|
579
|
+
phase: job?.phase || null,
|
|
629
580
|
processed: Number(job?.processed) || 0,
|
|
630
581
|
total: Number(job?.total) || 0,
|
|
631
|
-
skipped: Number(job?.skipped) || 0,
|
|
632
582
|
result: {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
...(Number.isFinite(result.
|
|
636
|
-
...(Number.isFinite(result.mappingTotal) ? { mappingTotal: result.mappingTotal } : {}),
|
|
637
|
-
...(result.upToDate ? { upToDate: true } : {}),
|
|
638
|
-
...(result.commit ? {
|
|
639
|
-
commitCreated: Boolean(result.commit.created),
|
|
640
|
-
commit: result.commit.hash || null,
|
|
641
|
-
} : {}),
|
|
583
|
+
documents: Number(result.documents) || 0,
|
|
584
|
+
...(Number.isFinite(result.nodes) ? { nodes: result.nodes } : {}),
|
|
585
|
+
...(Number.isFinite(result.edges) ? { edges: result.edges } : {}),
|
|
642
586
|
},
|
|
643
587
|
};
|
|
644
588
|
}
|
|
645
589
|
|
|
646
|
-
async function waitForConversionJob(
|
|
647
|
-
let job =
|
|
648
|
-
let reportedState = '';
|
|
590
|
+
async function waitForConversionJob({ folder, id }, { json = false } = {}) {
|
|
591
|
+
let job = null;
|
|
649
592
|
let reportedPercent = -10;
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
593
|
+
do {
|
|
594
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
595
|
+
({ job } = await readLocalScanJob({ folder, id }));
|
|
596
|
+
if (!json && job && job.percent >= reportedPercent + 10) {
|
|
597
|
+
log.info(`Conversion et analyse PII : ${job.percent || 0} % (${job.processed || 0}/${job.total || 0})`);
|
|
655
598
|
reportedPercent = job.percent || 0;
|
|
656
599
|
}
|
|
657
|
-
|
|
658
|
-
job = getJob(job.id);
|
|
659
|
-
}
|
|
600
|
+
} while (job && job.state === 'running');
|
|
660
601
|
if (!job) throw new Error('Le travail de conversion a expiré avant sa fin.');
|
|
661
602
|
if (job.state === 'error') throw new Error(job.error || 'La conversion a échoué.');
|
|
603
|
+
if (job.state === 'cancelled') throw new Error('La conversion a été annulée.');
|
|
662
604
|
return job;
|
|
663
605
|
}
|
|
664
606
|
|
|
607
|
+
async function ensureServerForConversion({ json = false } = {}) {
|
|
608
|
+
const servicesModule = path.join(APP_CLI_LIB, 'services.mjs');
|
|
609
|
+
if (!fs.existsSync(servicesModule)) {
|
|
610
|
+
throw new Error(`Le serveur applicatif doit être démarré par la commande « piecemaker » avant la conversion (port ${appServerPort()}).`);
|
|
611
|
+
}
|
|
612
|
+
const { appServerReachable, startApplication } = await import(pathToFileURL(servicesModule).href);
|
|
613
|
+
if (await appServerReachable()) return;
|
|
614
|
+
if (!json) log.info(`Serveur applicatif arrêté : démarrage sur le port ${appServerPort()} avant conversion.`);
|
|
615
|
+
const { resolveNodeRuntime } = await import(pathToFileURL(path.join(APP_CLI_LIB, 'node-runtime.mjs')).href);
|
|
616
|
+
const outcome = await startApplication(resolveNodeRuntime(), {
|
|
617
|
+
step: (text) => { if (!json) log.info(text); },
|
|
618
|
+
});
|
|
619
|
+
if (outcome.serverUp === false) {
|
|
620
|
+
throw new Error(`Le serveur applicatif n'a pas démarré.${outcome.logTail ? `\n${outcome.logTail}` : ''}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
665
624
|
async function runConversionCommand(flags) {
|
|
666
625
|
if (!fs.existsSync(ORIGINALS_PIPELINE_MODULE)) {
|
|
667
626
|
throw new Error('Le module de conversion PieceMaker est introuvable.');
|
|
668
627
|
}
|
|
669
|
-
const config = loadConfig();
|
|
670
628
|
const { locateConfiguredCase } = require('../../piecemaker-plugin/scripts/lib/case-folders.cjs');
|
|
671
|
-
const located = locateConfiguredCase(
|
|
629
|
+
const located = locateConfiguredCase(loadConfig(), flags.caseTarget || process.cwd());
|
|
672
630
|
if (!located) {
|
|
673
631
|
throw new Error('Lancez la commande depuis un dossier juridique enregistré ou passez --case <chemin>.');
|
|
674
632
|
}
|
|
675
633
|
|
|
676
|
-
|
|
677
|
-
// autonome reproduit ce choix sans exiger que le serveur PieceMaker tourne.
|
|
678
|
-
const configuredVenv = venvPaths(config.venvPath);
|
|
679
|
-
const python = process.env.PYTHON_PATH
|
|
680
|
-
|| readEnv().PYTHON_PATH
|
|
681
|
-
|| config.pythonPath
|
|
682
|
-
|| (configuredVenv.exists ? configuredVenv.python : null)
|
|
683
|
-
|| findPython()?.command;
|
|
684
|
-
if (!python) throw new Error('Aucun interpréteur Python 3.10+ n’est disponible pour la conversion.');
|
|
685
|
-
process.env.PYTHON_PATH = python;
|
|
686
|
-
|
|
687
|
-
const { getJob, listOriginals, startOriginalsJob } = require(ORIGINALS_PIPELINE_MODULE);
|
|
634
|
+
const { listOriginals } = require(ORIGINALS_PIPELINE_MODULE);
|
|
688
635
|
const originals = await listOriginals(located.caseRoot);
|
|
689
|
-
const
|
|
636
|
+
const selected = resolveConversionFiles(
|
|
690
637
|
originals,
|
|
691
638
|
flags.conversionDocuments || [],
|
|
692
639
|
located.caseRoot,
|
|
693
640
|
);
|
|
641
|
+
const requestedFiles = selected.length || !flags.force
|
|
642
|
+
? selected
|
|
643
|
+
: originals.map((original) => original.path);
|
|
694
644
|
if (!flags.json) {
|
|
695
645
|
log.info(requestedFiles.length
|
|
696
646
|
? `Conversion et pseudonymisation de ${requestedFiles.length} pièce(s) sélectionnée(s).`
|
|
697
647
|
: 'Conversion et pseudonymisation des pièces qui ne sont pas encore prêtes.');
|
|
698
648
|
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
});
|
|
707
|
-
const job = await waitForConversionJob(initialJob, getJob, { json: flags.json });
|
|
649
|
+
|
|
650
|
+
await ensureServerForConversion({ json: flags.json });
|
|
651
|
+
const started = await startLocalScan({ folder: located.caseRoot, files: requestedFiles });
|
|
652
|
+
const job = await waitForConversionJob(
|
|
653
|
+
{ folder: located.caseRoot, id: started.job?.id },
|
|
654
|
+
{ json: flags.json },
|
|
655
|
+
);
|
|
708
656
|
const result = publicConversionResult(job);
|
|
709
657
|
if (flags.json) process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
710
|
-
else
|
|
711
|
-
else log.ok(`Conversion et pseudonymisation terminées : ${result.result.scanned} pièce(s).`);
|
|
658
|
+
else log.ok(`Conversion et pseudonymisation terminées : ${result.result.documents} pièce(s).`);
|
|
712
659
|
return 0;
|
|
713
660
|
}
|
|
714
661
|
|
|
715
662
|
async function runOperationalCommand(command, knownUpdate = null, flags = {}) {
|
|
716
663
|
if (command === 'chronology') return runChronologyCommand(flags);
|
|
717
664
|
if (command === 'conversion') return runConversionCommand(flags);
|
|
718
|
-
if (command === 'open') {
|
|
719
|
-
const status = await openAdmin();
|
|
720
|
-
log.ok(`Interface ouverte : ${status.url}`);
|
|
721
|
-
return 0;
|
|
722
|
-
}
|
|
723
|
-
if (command === 'start') {
|
|
724
|
-
const status = await startServer();
|
|
725
|
-
log.ok(status.started ? `Serveur démarré : ${status.url}` : `Serveur déjà actif : ${status.url}`);
|
|
726
|
-
return 0;
|
|
727
|
-
}
|
|
728
|
-
if (command === 'stop') {
|
|
729
|
-
const status = await stopServer();
|
|
730
|
-
if (status.alreadyStopped) log.info('Le serveur est déjà arrêté.');
|
|
731
|
-
else log.ok('Serveur arrêté.');
|
|
732
|
-
return 0;
|
|
733
|
-
}
|
|
734
|
-
if (command === 'restart') {
|
|
735
|
-
await stopServer();
|
|
736
|
-
const status = await startServer();
|
|
737
|
-
log.ok(`Serveur redémarré : ${status.url}`);
|
|
738
|
-
return 0;
|
|
739
|
-
}
|
|
740
|
-
if (command === 'status') {
|
|
741
|
-
const status = await getServerStatus();
|
|
742
|
-
printServerStatus(status);
|
|
743
|
-
return 0;
|
|
744
|
-
}
|
|
745
|
-
if (command === 'logs') {
|
|
746
|
-
title('Journal du serveur HTTPS');
|
|
747
|
-
const content = readLogs();
|
|
748
|
-
write(content || ' Aucun journal disponible.');
|
|
749
|
-
blank();
|
|
750
|
-
return 0;
|
|
751
|
-
}
|
|
752
665
|
if (command === 'update') {
|
|
753
|
-
// Look before stopping anything: an up-to-date install must not lose its
|
|
754
|
-
// server for the duration of a no-op npm install.
|
|
755
666
|
const pending = knownUpdate ?? checkForUpdate();
|
|
756
667
|
if (!pending.available) {
|
|
757
668
|
log.ok(`PieceMaker est déjà à jour (${pending.ref}, ${pending.current.slice(0, 7)}).`);
|
|
758
669
|
reconcileCaseInstructions();
|
|
759
|
-
await refreshDesktopApplicationAfterUpdate();
|
|
760
670
|
if (reconcileCentralMapping()) {
|
|
761
|
-
log.info('Rouvrez les sessions Claude Code actives pour oublier les
|
|
671
|
+
log.info('Rouvrez les sessions Claude Code actives pour oublier les hooks hérités.');
|
|
762
672
|
}
|
|
763
673
|
// « update » reste le geste de remise à niveau : même sans nouveau commit,
|
|
764
674
|
// une étape d'installation restée incomplète repart en tâche de fond.
|
|
@@ -771,24 +681,10 @@ async function runOperationalCommand(command, knownUpdate = null, flags = {}) {
|
|
|
771
681
|
log.info(`Restauration de l’installation depuis le dépôt distant (${pending.localChanges} fichier(s) localement modifié(s)).`);
|
|
772
682
|
}
|
|
773
683
|
|
|
774
|
-
// A live server on the port is a PieceMaker server (the health probe
|
|
775
|
-
// answered 200), whether we started it or not — e.g. one launched by hand
|
|
776
|
-
// from the dev clone, so with no PID file it comes back unmanaged. We adopt
|
|
777
|
-
// it: stop whatever holds the port and bring a managed server back below,
|
|
778
|
-
// rather than leaving the user to restart it themselves.
|
|
779
|
-
const previous = await getServerStatus();
|
|
780
|
-
if (previous.running) await stopServer();
|
|
781
684
|
try {
|
|
782
685
|
const result = updateRepository(pending);
|
|
783
686
|
log.ok(`PieceMaker mis à jour (${result.ref}, ${result.target.slice(0, 7)}).`);
|
|
784
687
|
|
|
785
|
-
// CLAUDE.md racine est gitignoré : « git reset --hard » ci-dessus le
|
|
786
|
-
// supprime dès qu'un clone récupère le commit qui l'a dé-versionné. On
|
|
787
|
-
// redépose donc la persona utilisateur depuis le gabarit (absent → écrit,
|
|
788
|
-
// présent → intact), même source que l'étape d'installation 09.
|
|
789
|
-
if (depositRootClaudeMd().status === 'deposited') {
|
|
790
|
-
log.ok('CLAUDE.md (persona utilisateur) redéposé depuis le gabarit.');
|
|
791
|
-
}
|
|
792
688
|
reconcileCaseInstructions();
|
|
793
689
|
|
|
794
690
|
if (result.pythonChanged) {
|
|
@@ -813,13 +709,8 @@ async function runOperationalCommand(command, knownUpdate = null, flags = {}) {
|
|
|
813
709
|
}
|
|
814
710
|
|
|
815
711
|
reconcileCentralMapping();
|
|
816
|
-
await refreshDesktopApplicationAfterUpdate();
|
|
817
712
|
log.info('Rouvrez les sessions Claude Code/Codex actives pour charger les hooks et le MCP mis à jour.');
|
|
818
713
|
} finally {
|
|
819
|
-
if (previous.running) {
|
|
820
|
-
const restarted = await startServer();
|
|
821
|
-
log.ok(`Serveur redémarré : ${restarted.url}`);
|
|
822
|
-
}
|
|
823
714
|
const daemon = restartTelegramDaemon();
|
|
824
715
|
if (daemon.restarted) log.ok('Moniteur Telegram redémarré.');
|
|
825
716
|
else if (daemon.reason && daemon.reason !== 'absent' && daemon.reason !== 'unsupported') {
|
|
@@ -859,49 +750,14 @@ function checkForUpdateOnOpen() {
|
|
|
859
750
|
}
|
|
860
751
|
}
|
|
861
752
|
|
|
862
|
-
/**
|
|
863
|
-
* Bare `piecemaker` should land on a live server. Start it if it is down, but
|
|
864
|
-
* never block the menu on failure: a missing certificate or a boot error is
|
|
865
|
-
* reported and the interactive installer below stays reachable to fix it.
|
|
866
|
-
* The browser is left closed on purpose — the menu's "Ouvrir l'interface"
|
|
867
|
-
* entry is how the admin pane gets opened.
|
|
868
|
-
*/
|
|
869
|
-
async function ensureServerRunning() {
|
|
870
|
-
let status;
|
|
871
|
-
try {
|
|
872
|
-
status = await getServerStatus();
|
|
873
|
-
} catch {
|
|
874
|
-
return;
|
|
875
|
-
}
|
|
876
|
-
if (status.running) return;
|
|
877
|
-
|
|
878
|
-
const spin = spinner('Démarrage du serveur local...');
|
|
879
|
-
try {
|
|
880
|
-
const started = await startServer();
|
|
881
|
-
spin.stop();
|
|
882
|
-
log.ok(`Serveur démarré : ${started.url}`);
|
|
883
|
-
} catch (error) {
|
|
884
|
-
spin.stop();
|
|
885
|
-
log.warn(`Serveur non démarré : ${error.message}`);
|
|
886
|
-
log.detail('Réparez-le via « Installer ou réparer des composants » ci-dessous.');
|
|
887
|
-
}
|
|
888
|
-
blank();
|
|
889
|
-
}
|
|
890
|
-
|
|
891
753
|
async function mainMenu(steps, ctx, knownUpdate = null) {
|
|
892
754
|
for (;;) {
|
|
893
|
-
const status = await getServerStatus();
|
|
894
|
-
printServerStatus(status);
|
|
895
755
|
const choice = await select('Que voulez-vous faire ?', [
|
|
896
|
-
{ value: 'open', label: 'Ouvrir l’interface graphique', hint: 'paramètres, skills et agents' },
|
|
897
|
-
{ value: status.running ? 'stop' : 'start', label: status.running ? 'Arrêter le serveur local' : 'Démarrer le serveur local' },
|
|
898
|
-
{ value: 'status', label: 'Actualiser l’état' },
|
|
899
756
|
{ value: 'install', label: 'Installer ou réparer des composants' },
|
|
900
757
|
{
|
|
901
758
|
value: 'update',
|
|
902
759
|
label: knownUpdate?.remoteAvailable ? 'Mettre à jour PieceMaker — MAJ disponible' : 'Mettre à jour PieceMaker',
|
|
903
760
|
},
|
|
904
|
-
{ value: 'logs', label: 'Afficher les journaux' },
|
|
905
761
|
{ value: 'quit', label: 'Quitter' },
|
|
906
762
|
]);
|
|
907
763
|
|
|
@@ -918,7 +774,6 @@ async function mainMenu(steps, ctx, knownUpdate = null) {
|
|
|
918
774
|
} catch (error) {
|
|
919
775
|
log.error(error.message);
|
|
920
776
|
}
|
|
921
|
-
if (choice === 'open') return;
|
|
922
777
|
await pause();
|
|
923
778
|
}
|
|
924
779
|
}
|
|
@@ -978,9 +833,7 @@ async function main() {
|
|
|
978
833
|
return runOperationalCommand(flags.command, null, flags);
|
|
979
834
|
}
|
|
980
835
|
|
|
981
|
-
// `update`
|
|
982
|
-
// avant ensureServerRunning() plus bas, pour ne pas démarrer un serveur juste
|
|
983
|
-
// avant de le couper. Il enchaîne aussi sur la reprise des étapes.
|
|
836
|
+
// `update` enchaîne sur la reprise des étapes : il passe avant le menu.
|
|
984
837
|
let autoUpdated = false;
|
|
985
838
|
if (opensInteractiveInstaller && knownUpdate?.available) {
|
|
986
839
|
try {
|
|
@@ -1050,10 +903,7 @@ async function main() {
|
|
|
1050
903
|
}
|
|
1051
904
|
|
|
1052
905
|
if (flags.command === 'install') await installerMenu(steps, ctx);
|
|
1053
|
-
else
|
|
1054
|
-
await ensureServerRunning();
|
|
1055
|
-
await mainMenu(steps, ctx, knownUpdate);
|
|
1056
|
-
}
|
|
906
|
+
else await mainMenu(steps, ctx, knownUpdate);
|
|
1057
907
|
return 0;
|
|
1058
908
|
}
|
|
1059
909
|
|
|
@@ -4,10 +4,8 @@
|
|
|
4
4
|
* Isolée dans son propre module parce que `installer/bin/piecemaker.mjs`
|
|
5
5
|
* lance `main()` dès son import : rien ne peut l'importer sans ouvrir le menu
|
|
6
6
|
* interactif et donc toucher aux services réels de la machine. Ce module-ci
|
|
7
|
-
* est importable sans effet de bord
|
|
8
|
-
* (`test/commandes-templates.test.mjs`) de confronter cette surface aux
|
|
9
|
-
* outils MCP et aux commandes citées dans les templates.
|
|
7
|
+
* est importable sans effet de bord.
|
|
10
8
|
*/
|
|
11
9
|
|
|
12
|
-
export const COMMANDS = new Set(['
|
|
10
|
+
export const COMMANDS = new Set(['chronology', 'conversion', 'install', 'doctor', 'check', 'update']);
|
|
13
11
|
export const CHRONOLOGY_ACTIONS = new Set(['read', 'write', 'edit']);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client HTTP de la conversion PieceMaker.
|
|
3
|
+
*
|
|
4
|
+
* La conversion et l'analyse PII n'ont qu'un seul point d'entrée : la route
|
|
5
|
+
* `knowledge/scan` du serveur applicatif. Le CLI en est un client, sur la
|
|
6
|
+
* boucle locale, via le montage `/api/piecemaker/local` placé avant
|
|
7
|
+
* l'authentification. Le serveur applicatif écoute en clair sur le port du
|
|
8
|
+
* CLI (`PIECEMAKER_APP_PORT`, 3003 par défaut) : aucun certificat n'entre en
|
|
9
|
+
* jeu et la requête ne sort jamais de 127.0.0.1.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import http from 'node:http';
|
|
13
|
+
|
|
14
|
+
const LOCAL_BASE = '/api/piecemaker/local';
|
|
15
|
+
|
|
16
|
+
export function appServerPort() {
|
|
17
|
+
const parsed = Number.parseInt(process.env.PIECEMAKER_APP_PORT || '', 10);
|
|
18
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : 3003;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function requestJson({ method, path, body }) {
|
|
22
|
+
const payload = body === undefined ? null : Buffer.from(JSON.stringify(body));
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const request = http.request(
|
|
25
|
+
{
|
|
26
|
+
hostname: '127.0.0.1',
|
|
27
|
+
port: appServerPort(),
|
|
28
|
+
path,
|
|
29
|
+
method,
|
|
30
|
+
timeout: 30_000,
|
|
31
|
+
headers: {
|
|
32
|
+
Accept: 'application/json',
|
|
33
|
+
...(payload ? { 'Content-Type': 'application/json', 'Content-Length': payload.length } : {}),
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
(response) => {
|
|
37
|
+
const chunks = [];
|
|
38
|
+
response.on('data', (chunk) => chunks.push(chunk));
|
|
39
|
+
response.on('end', () => {
|
|
40
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
41
|
+
let parsed = null;
|
|
42
|
+
try {
|
|
43
|
+
parsed = raw ? JSON.parse(raw) : null;
|
|
44
|
+
} catch {
|
|
45
|
+
reject(new Error(`Réponse illisible du serveur PieceMaker (${response.statusCode}).`));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (response.statusCode >= 400) {
|
|
49
|
+
reject(new Error(parsed?.error || `Le serveur PieceMaker a répondu ${response.statusCode}.`));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
resolve(parsed);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
request.on('timeout', () => request.destroy(new Error('Le serveur PieceMaker n’a pas répondu à temps.')));
|
|
57
|
+
request.on('error', reject);
|
|
58
|
+
if (payload) request.write(payload);
|
|
59
|
+
request.end();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function startLocalScan({ folder, files }) {
|
|
64
|
+
return requestJson({
|
|
65
|
+
method: 'POST',
|
|
66
|
+
path: `${LOCAL_BASE}/scan`,
|
|
67
|
+
body: { folder, ...(files?.length ? { files } : {}) },
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function readLocalScanJob({ folder, id }) {
|
|
72
|
+
const query = new URLSearchParams({ folder, ...(id ? { id } : {}) });
|
|
73
|
+
return requestJson({ method: 'GET', path: `${LOCAL_BASE}/scan/job?${query}` });
|
|
74
|
+
}
|