@piecemaker-legal/piecemaker 2.0.11 → 2.0.13
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-BucOHLdm.js → FindReplaceDialog-KU5TEIBJ-DiS1F6O4.js} +1 -1
- package/dist/assets/{FootnotePropertiesDialog-W3YHM4BV-D5UqbelV.js → FootnotePropertiesDialog-W3YHM4BV-BMRWztwh.js} +1 -1
- package/dist/assets/{HyperlinkDialog-ZYH7ZHRF-8yEhLigd.js → HyperlinkDialog-ZYH7ZHRF-D5r9CZf2.js} +4 -4
- package/dist/assets/{ImagePositionDialog-HEWYR6Q3-wGIBYxCm.js → ImagePositionDialog-HEWYR6Q3-EeK_GFbX.js} +1 -1
- package/dist/assets/{ImagePropertiesDialog-RAB47C6M-D86PckZ2.js → ImagePropertiesDialog-RAB47C6M-BgrZEZLp.js} +1 -1
- package/dist/assets/{PageSetupDialog-AIGIXO3E-DLETP-7v.js → PageSetupDialog-AIGIXO3E-DdFpkcLH.js} +1 -1
- package/dist/assets/{SplitCellDialog-IFBKYCD6-CwdQBXeb.js → SplitCellDialog-IFBKYCD6-B2J0yPH6.js} +1 -1
- package/dist/assets/{TablePropertiesDialog-TMLKGOOW-j2nA7KJs.js → TablePropertiesDialog-TMLKGOOW-iTyD5Vwt.js} +1 -1
- package/dist/assets/{WatermarkDialog-KRL7WMIS-XFJ9gTkC.js → WatermarkDialog-KRL7WMIS-CdwIWeEi.js} +1 -1
- package/dist/assets/{abnfDiagram-VCTEODGH-DiCrND_Y.js → abnfDiagram-VCTEODGH-CCQgv7yc.js} +1 -1
- package/dist/assets/{arc-DOjgbMYz.js → arc-B-Y10mRQ.js} +1 -1
- package/dist/assets/{architectureDiagram-5GKGNRK7-brzIFVhl.js → architectureDiagram-5GKGNRK7-C-mYZ4DW.js} +1 -1
- package/dist/assets/{blockDiagram-I7D4REHJ-C8JhTjQQ.js → blockDiagram-I7D4REHJ-Bby14xNO.js} +1 -1
- package/dist/assets/{c4Diagram-7LVT6UL2-jfYxccyk.js → c4Diagram-7LVT6UL2-CoqTzQi7.js} +1 -1
- package/dist/assets/channel-BxbXkYrr.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-CrlEShp9.js → chunk-2Q5K7J3B-CYlmti0k.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-DzPlUHGq.js → chunk-5VM5RSS4-W35KZUQj.js} +1 -1
- package/dist/assets/{chunk-F27PBJKO-Cp9cpeWU.js → chunk-F27PBJKO-BVIu5FJA.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-BifUldEN.js → chunk-IMKFNOWR-DRf1mnVb.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-ggPEIkWu.js → chunk-JWPE2WC7-CUJ1N2G9.js} +1 -1
- package/dist/assets/{chunk-POPQ4Y6H-3h_nayRX.js → chunk-POPQ4Y6H-p6IVobio.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-CH29aG6J.js → chunk-SVP7TREG-DOM_pdOM.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-PluJUM5k.js → chunk-TICWLB2K-VqAu84r8.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-DXU39Vwg.js → chunk-XXDRQBXY-vaUsyH7g.js} +1 -1
- package/dist/assets/classDiagram-ZZMXUADV-COu_XNpX.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-COu_XNpX.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-Dz6roYrN.js → cose-bilkent-JH36ORCC-B_sTVfyq.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-BLzrpSit.js → cynefin-OW5HDTMX-DvnWaxw0.js} +1 -1
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-kfxnERDZ.js → cynefinDiagram-5FMLGOSQ-DriBDRYQ.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-DP57bp-N.js → dagre-GXQ25YYZ-BAwYXMGG.js} +1 -1
- package/dist/assets/{diagram-S7CK7UJ4-DAlsrQVW.js → diagram-S7CK7UJ4-DX03OYpD.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-By5yrMer.js → diagram-UQ7AKVKN-rdUs_hF8.js} +1 -1
- package/dist/assets/{diagram-VSXAHHWV-Dx89kryN.js → diagram-VSXAHHWV-CobmLXkM.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-B9fARitZ.js → diagram-VX7I27RA-B18D7USE.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-DC15CEH1.js → diagram-Z3DM3KII-CRrNHL6r.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-BKQzghGF.js → ebnfDiagram-PWID7BFC-HXzGHTn6.js} +1 -1
- package/dist/assets/{erDiagram-RLTQ6QDP-CPY6RM7G.js → erDiagram-RLTQ6QDP-lbfD5sxC.js} +1 -1
- package/dist/assets/{flowDiagram-HODETNUW-4dL4GJcf.js → flowDiagram-HODETNUW-Dd0lb1Fm.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-D4-cVcfb.js → ganttDiagram-EL5Y4UJY-CKBO9TRh.js} +1 -1
- package/dist/assets/{gitGraphDiagram-WWUBYQGX-BMeVIEiX.js → gitGraphDiagram-WWUBYQGX-Ds_AlKrJ.js} +1 -1
- package/dist/assets/index-C5slQNvE.css +1 -0
- package/dist/assets/{index-DNtFDOni.js → index-C9XXF765.js} +146 -146
- package/dist/assets/{infoDiagram-27XIBGKW-D5qMSUEU.js → infoDiagram-27XIBGKW-BbNgbn6W.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-BDnyKRHm.js → ishikawaDiagram-5VMMS53U-B9FZGWPM.js} +1 -1
- package/dist/assets/{journeyDiagram-3NMN7TZE-dGz5ZGzq.js → journeyDiagram-3NMN7TZE-9z26Mgkz.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-D7UAz7o_.js → kanban-definition-UXKFOSKX-dQoIQkFu.js} +1 -1
- package/dist/assets/{layout-DKrmEGrz.js → layout-C03dZv1L.js} +1 -1
- package/dist/assets/{linear-CrTdMY-p.js → linear-BAgwn459.js} +1 -1
- package/dist/assets/{mermaid.core-CXQOT5G6.js → mermaid.core-Bb-zdGYl.js} +6 -6
- package/dist/assets/{mindmap-definition-YA3MSWOX-VgEiYfay.js → mindmap-definition-YA3MSWOX-BZ77-g1t.js} +1 -1
- package/dist/assets/{pegDiagram-XKGWAZYB-9IqT8gGx.js → pegDiagram-XKGWAZYB-vlBCwMpy.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-D98pRE-t.js → pieDiagram-E7YTZNPT-DGaLzhN2.js} +1 -1
- package/dist/assets/{quadrantDiagram-AXDQQJYC-b9PwkYzL.js → quadrantDiagram-AXDQQJYC-J517wJ3s.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-Dz87hsPE.js → railroadDiagram-O6MQD6OU-MiMqTB2q.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-CkcV73dK.js → requirementDiagram-BXWQKSXE-ClFWrfsX.js} +1 -1
- package/dist/assets/{sankeyDiagram-P5KCCOFB-UBN31Yrs.js → sankeyDiagram-P5KCCOFB-BQjzvuzZ.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-CpQxd5Za.js → sequenceDiagram-WJ2MYXX4-BVI9Mtfy.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-mCsFmyzw.js → sizeCapture-INFHLROL-npWe2anw.js} +1 -1
- package/dist/assets/{stateDiagram-D77RDMKH-B0MTBN-3.js → stateDiagram-D77RDMKH-BE4pwhgm.js} +1 -1
- package/dist/assets/{stateDiagram-v2-MP3YSRHH-DzBPN39W.js → stateDiagram-v2-MP3YSRHH-PdR5r-x_.js} +1 -1
- package/dist/assets/{swimlanes-42K2YHIH-Dzydjm0e.js → swimlanes-42K2YHIH-DJMuv4Fv.js} +1 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-Cxv8b9_h.js +8 -0
- package/dist/assets/{timeline-definition-24CTP7MA-Dz0toOLu.js → timeline-definition-24CTP7MA-BLHKdXUW.js} +1 -1
- package/dist/assets/{vennDiagram-4TSXK5OY-DOWp7dkf.js → vennDiagram-4TSXK5OY-vpWJbaKf.js} +1 -1
- package/dist/assets/{wardleyDiagram-VM6X3IG4-CUxsztUB.js → wardleyDiagram-VM6X3IG4-BC1q3_Z5.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-DS96vNED.js → xychartDiagram-S5SC5T6Z--yDqjI6l.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/sw.js +1 -1
- package/dist-server/plugins/piecemaker-dossier/src/knowledge.js +61 -1
- package/dist-server/plugins/piecemaker-dossier/src/knowledge.js.map +1 -1
- package/dist-server/plugins/piecemaker-dossier/src/scan-result.js +0 -48
- package/dist-server/plugins/piecemaker-dossier/src/scan-result.js.map +1 -1
- package/dist-server/server/piecemaker/desktop-update/service.js +2 -1
- package/dist-server/server/piecemaker/desktop-update/service.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/pipeline.js +25 -29
- package/dist-server/server/piecemaker/knowledge/pipeline.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/service.js +1 -16
- package/dist-server/server/piecemaker/knowledge/service.js.map +1 -1
- package/dist-server/server/piecemaker/project-registry.js +5 -5
- package/dist-server/server/piecemaker/project-registry.js.map +1 -1
- package/package.json +1 -1
- package/server/piecemaker/anonymizer/hudsucker-fixture.cjs +1 -1
- package/server/piecemaker/anonymizer/hudsucker-proxy/src/main.rs +2 -1
- package/server/piecemaker/anonymizer/rewrite.cjs +2 -2
- package/server/piecemaker/anonymizer/service.cjs +3 -2
- package/server/piecemaker/anonymizer/sqlite-dictionary.cjs +3 -31
- package/server/piecemaker/desktop-update/service.ts +2 -1
- package/server/piecemaker/index.ts +1 -1
- package/server/piecemaker/knowledge/pipeline.ts +24 -31
- package/server/piecemaker/knowledge/service.ts +1 -14
- package/server/piecemaker/project-registry.ts +6 -6
- package/server/piecemaker/vendor/installer/bin/piecemaker.mjs +9 -162
- package/server/piecemaker/vendor/installer/lib/commandes.mjs +1 -2
- package/server/piecemaker/vendor/installer/lib/conversion-client.mjs +62 -3
- package/server/piecemaker/vendor/installer/steps/06-hooks.mjs +23 -69
- package/server/piecemaker/vendor/installer/steps/12-mcp-piecemaker.mjs +3 -3
- package/server/piecemaker/vendor/mcp/README.md +1 -1
- package/server/piecemaker/vendor/mcp/piecemaker/server.mjs +12 -75
- package/server/piecemaker/vendor/piecemaker-plugin/hooks/hooks.json +0 -40
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/compile-recherche.mjs +2 -2
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/case-folders.cjs +26 -7
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/commits.cjs +0 -28
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/hook-io.mjs +0 -13
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/institutional-terms.cjs +3 -3
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/mapping.cjs +10 -143
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/protection.cjs +1 -1
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/session-timing.cjs +0 -65
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/protect-originals.mjs +11 -2
- package/server/piecemaker/vendor/piecemaker-plugin/skills/conversion-md/SKILL.md +9 -5
- package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +2 -150
- package/server/piecemaker/vendor/websocket-server/claude-hooks.cjs +3 -0
- package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +23 -372
- package/server/piecemaker/vendor/websocket-server/renamed-originals.cjs +136 -0
- package/server/piecemaker/vendor/websocket-server/scripts/convert_and_scan_pipeline.py +115 -96
- package/dist/assets/channel-Dajzu2W1.js +0 -1
- package/dist/assets/classDiagram-ZZMXUADV-dDEP_giv.js +0 -1
- package/dist/assets/classDiagram-v2-VYDZK3BY-dDEP_giv.js +0 -1
- package/dist/assets/index-Dc9wNuS4.css +0 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-BXQpbUMD.js +0 -8
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/billing-track.mjs +0 -194
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/commit-track.mjs +0 -71
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/session-commit-worker.mjs +0 -260
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/session-commit.mjs +0 -83
|
@@ -8,11 +8,6 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
10
10
|
* piecemaker menu interactif
|
|
11
|
-
* piecemaker chronology affiche la chronologie du dossier courant
|
|
12
|
-
* piecemaker chronology write --path <pièce> --correction-json <json>
|
|
13
|
-
* crée une correction de chronologie pour une pièce
|
|
14
|
-
* piecemaker chronology edit --path <pièce> --correction-json <json>
|
|
15
|
-
* modifie une correction de chronologie existante
|
|
16
11
|
* piecemaker conversion convertit et pseudonymise les pièces manquantes
|
|
17
12
|
* piecemaker install ouvre le menu des composants
|
|
18
13
|
* piecemaker doctor diagnostic seul
|
|
@@ -33,16 +28,15 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
33
28
|
import { banner, title, log, write, blank, summary, spinner, badge, c } from '../lib/ui.mjs';
|
|
34
29
|
import { select, confirm, multiSelect, pause, nonInteractive } from '../lib/prompt.mjs';
|
|
35
30
|
import { GIT_REPO_ROOT, HOME_DIR, REPO_ROOT, commandExists, findPython } from '../lib/platform.mjs';
|
|
36
|
-
import { COMMANDS
|
|
31
|
+
import { COMMANDS } from '../lib/commandes.mjs';
|
|
37
32
|
import { loadConfig, readEnv, markStep, loadState, CONFIG_FILE } from '../lib/state.mjs';
|
|
38
33
|
import { scheduleStepResume, selectStepsToResume } from '../lib/resume-steps.mjs';
|
|
39
|
-
import { appServerPort, readLocalScanJob, startLocalScan } from '../lib/conversion-client.mjs';
|
|
34
|
+
import { adoptRunningServerPort, appServerPort, localServerReachable, readLocalScanJob, startLocalScan } from '../lib/conversion-client.mjs';
|
|
40
35
|
import { checkForUpdate, updateRepository } from '../lib/service.mjs';
|
|
41
36
|
|
|
42
37
|
const require = createRequire(import.meta.url);
|
|
43
38
|
const CLAUDE_ASSETS_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/claude-assets.cjs');
|
|
44
39
|
const CLAUDE_HOOKS_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/claude-hooks.cjs');
|
|
45
|
-
const DOCUMENT_INDEX_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/document-index.cjs');
|
|
46
40
|
const ORIGINALS_PIPELINE_MODULE = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../websocket-server/originals-pipeline.cjs');
|
|
47
41
|
const APP_CLI_LIB = path.join(GIT_REPO_ROOT, 'scripts', 'piecemaker', 'cli', 'lib');
|
|
48
42
|
|
|
@@ -129,11 +123,8 @@ function parseArgs(argv) {
|
|
|
129
123
|
check: false,
|
|
130
124
|
dryRun: false,
|
|
131
125
|
conversionDocuments: [],
|
|
132
|
-
correctionJson: null,
|
|
133
126
|
force: false,
|
|
134
|
-
chronologyAction: 'read',
|
|
135
127
|
json: false,
|
|
136
|
-
piecePath: null,
|
|
137
128
|
resumeSteps: null,
|
|
138
129
|
step: null,
|
|
139
130
|
yes: false,
|
|
@@ -142,18 +133,13 @@ function parseArgs(argv) {
|
|
|
142
133
|
for (let i = 0; i < argv.length; i++) {
|
|
143
134
|
const arg = argv[i];
|
|
144
135
|
if (!arg.startsWith('-') && !flags.command && COMMANDS.has(arg)) flags.command = arg;
|
|
145
|
-
else if (!arg.startsWith('-') && flags.command === 'chronology' && flags.chronologyAction === 'read' && CHRONOLOGY_ACTIONS.has(arg)) flags.chronologyAction = arg;
|
|
146
|
-
else if (!arg.startsWith('-') && flags.command === 'chronology' && !flags.caseTarget) flags.caseTarget = arg;
|
|
147
136
|
else if (!arg.startsWith('-') && flags.command === 'conversion') flags.conversionDocuments.push(arg);
|
|
148
137
|
else if (arg === '--all') flags.all = true;
|
|
149
|
-
else if (arg === '--action') flags.chronologyAction = argv[++i];
|
|
150
138
|
else if (arg === '--case') flags.caseTarget = argv[++i];
|
|
151
139
|
else if (arg === '--check') flags.check = true;
|
|
152
|
-
else if (arg === '--correction-json') flags.correctionJson = argv[++i];
|
|
153
140
|
else if (arg === '--dry-run') flags.dryRun = true;
|
|
154
141
|
else if (arg === '--force') flags.force = true;
|
|
155
142
|
else if (arg === '--json') flags.json = true;
|
|
156
|
-
else if (arg === '--path') flags.piecePath = argv[++i];
|
|
157
143
|
else if (arg === '--yes' || arg === '-y') flags.yes = true;
|
|
158
144
|
else if (arg === '--step') flags.step = argv[++i];
|
|
159
145
|
else if (arg === '--resume-steps') {
|
|
@@ -313,20 +299,15 @@ async function runCheck(steps, ctx) {
|
|
|
313
299
|
function printHelp() {
|
|
314
300
|
write(` ${c.bold('piecemaker')} — PieceMaker local`);
|
|
315
301
|
blank();
|
|
316
|
-
write(' chronology [read] affiche la chronologie pseudonymisée du dossier courant');
|
|
317
|
-
write(' chronology write --path <pièce> --correction-json <json> crée une correction de chronologie');
|
|
318
|
-
write(' chronology edit --path <pièce> --correction-json <json> modifie une correction existante');
|
|
319
302
|
write(' conversion [pièce…] convertit et pseudonymise les pièces manquantes ou indiquées');
|
|
320
303
|
write(' install ouvre le menu d’installation/réparation');
|
|
321
304
|
write(' doctor, check diagnostic seul, n’installe rien');
|
|
322
305
|
write(' update met à jour PieceMaker');
|
|
323
306
|
blank();
|
|
324
307
|
write(' --all installe tout sans menu');
|
|
325
|
-
write(' --case <chemin> cible un dossier enregistré (
|
|
326
|
-
write(' --path <pièce> chemin relatif de la pièce (chronology write/edit)');
|
|
327
|
-
write(' --correction-json <json> correction à appliquer (chronology write/edit)');
|
|
308
|
+
write(' --case <chemin> cible un dossier enregistré (conversion)');
|
|
328
309
|
write(' --force retraite les pièces');
|
|
329
|
-
write(' --json produit une sortie JSON sans décor (
|
|
310
|
+
write(' --json produit une sortie JSON sans décor (conversion)');
|
|
330
311
|
write(' --check diagnostic seul, n\'installe rien');
|
|
331
312
|
write(' --step <id> rejoue une seule étape');
|
|
332
313
|
write(' --resume-steps <ids> rejoue les étapes indiquées sans interaction (usage interne)');
|
|
@@ -375,135 +356,6 @@ async function installerMenu(steps, ctx, { allowBack = false } = {}) {
|
|
|
375
356
|
}
|
|
376
357
|
}
|
|
377
358
|
|
|
378
|
-
function formatChronologyText(chronology) {
|
|
379
|
-
const lines = [];
|
|
380
|
-
lines.push(`Chronologie : ${chronology.stats.documents} pièce(s), ${chronology.stats.dated} datée(s), ${chronology.stats.entities} entité(s).`);
|
|
381
|
-
lines.push('');
|
|
382
|
-
for (const doc of chronology.documents) {
|
|
383
|
-
lines.push(`${doc.dateIso || '(date manquante)'} ${doc.nature || '(nature inconnue)'} ${doc.name}`);
|
|
384
|
-
}
|
|
385
|
-
const missing = chronology.documents.filter((doc) => !doc.dateIso);
|
|
386
|
-
if (missing.length) {
|
|
387
|
-
lines.push('');
|
|
388
|
-
lines.push('Dates manquantes :');
|
|
389
|
-
for (const doc of missing) lines.push(` - ${doc.name}`);
|
|
390
|
-
}
|
|
391
|
-
return `${lines.join('\n')}\n`;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
function locateChronologyCase(flags) {
|
|
395
|
-
const { locateProjectCase } = require('../../piecemaker-plugin/scripts/lib/case-folders.cjs');
|
|
396
|
-
const located = locateProjectCase(flags.caseTarget || process.cwd());
|
|
397
|
-
if (!located) {
|
|
398
|
-
throw new Error('Lancez la commande depuis un dossier juridique enregistré ou passez --case <chemin>.');
|
|
399
|
-
}
|
|
400
|
-
return located;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
async function runChronologyReadCommand(flags) {
|
|
404
|
-
if (!fs.existsSync(DOCUMENT_INDEX_MODULE)) {
|
|
405
|
-
throw new Error('Le module de chronologie PieceMaker est introuvable.');
|
|
406
|
-
}
|
|
407
|
-
const located = locateChronologyCase(flags);
|
|
408
|
-
const { buildChronology } = require(DOCUMENT_INDEX_MODULE);
|
|
409
|
-
const chronology = await buildChronology(located.caseRoot, { deanonymizeLabels: false, includeManualDecisions: true });
|
|
410
|
-
const output = flags.json
|
|
411
|
-
? `${JSON.stringify(chronology, null, 2)}\n`
|
|
412
|
-
: formatChronologyText(chronology);
|
|
413
|
-
process.stdout.write(output);
|
|
414
|
-
return 0;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
function resolveChronologyPiecePath(caseRoot, relativePath) {
|
|
418
|
-
const relative = String(relativePath || '').replaceAll('\\', '/').replace(/^\.\//, '');
|
|
419
|
-
if (!relative) throw new Error('Chemin de pièce manquant.');
|
|
420
|
-
const absolute = path.resolve(caseRoot, ...relative.split('/'));
|
|
421
|
-
if (absolute !== caseRoot && !absolute.startsWith(`${caseRoot}${path.sep}`)) {
|
|
422
|
-
throw new Error('Pièce hors du dossier juridique.');
|
|
423
|
-
}
|
|
424
|
-
if (!fs.existsSync(absolute)) throw new Error('Pièce introuvable.');
|
|
425
|
-
return relative;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
async function runChronologyCorrectionCommand(flags) {
|
|
429
|
-
if (!fs.existsSync(DOCUMENT_INDEX_MODULE)) {
|
|
430
|
-
throw new Error('Le module de chronologie PieceMaker est introuvable.');
|
|
431
|
-
}
|
|
432
|
-
const located = locateChronologyCase(flags);
|
|
433
|
-
const relative = resolveChronologyPiecePath(located.caseRoot, flags.piecePath);
|
|
434
|
-
|
|
435
|
-
let correction;
|
|
436
|
-
try {
|
|
437
|
-
correction = JSON.parse(flags.correctionJson || '{}');
|
|
438
|
-
} catch (error) {
|
|
439
|
-
throw new Error(`Correction JSON invalide : ${error.message}`);
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
const { stateKey } = require('../../piecemaker-plugin/scripts/lib/anonymization-state.cjs');
|
|
443
|
-
const { applyDocumentIndexCorrection, readDocumentIndex, documentIndexFile } = require(DOCUMENT_INDEX_MODULE);
|
|
444
|
-
const key = stateKey(relative);
|
|
445
|
-
const existing = readDocumentIndex(located.caseRoot).overrides[key] || null;
|
|
446
|
-
|
|
447
|
-
if (flags.chronologyAction === 'write' && existing) {
|
|
448
|
-
throw new Error('Une correction existe déjà pour cette pièce ; utilisez edit_chronology pour la modifier.');
|
|
449
|
-
}
|
|
450
|
-
if (flags.chronologyAction === 'edit' && !existing) {
|
|
451
|
-
throw new Error('Aucune correction existante pour cette pièce ; utilisez write_chronology pour en créer une.');
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
const mutation = applyDocumentIndexCorrection(located.caseRoot, relative, correction);
|
|
455
|
-
|
|
456
|
-
let history;
|
|
457
|
-
try {
|
|
458
|
-
const { createCommit } = require('../../piecemaker-plugin/scripts/lib/commits.cjs');
|
|
459
|
-
history = await createCommit({
|
|
460
|
-
casesRoot: located.casesRoot,
|
|
461
|
-
caseName: located.caseName,
|
|
462
|
-
homeDir: HOME_DIR,
|
|
463
|
-
envFile: path.join(REPO_ROOT, '.env'),
|
|
464
|
-
label: flags.chronologyAction === 'write'
|
|
465
|
-
? 'Création d’une correction de chronologie'
|
|
466
|
-
: 'Modification d’une correction de chronologie',
|
|
467
|
-
description: `Mise à jour déterministe de la pièce ${mutation.documentKey.slice(0, 12).toUpperCase()}.`,
|
|
468
|
-
event: 'assistant-chronology-correction',
|
|
469
|
-
paths: [path.relative(located.caseRoot, documentIndexFile(located.caseRoot)).split(path.sep).join('/')],
|
|
470
|
-
waitForLockMs: 10_000,
|
|
471
|
-
});
|
|
472
|
-
} catch (error) {
|
|
473
|
-
history = { created: false, error: error.message };
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const result = {
|
|
477
|
-
ok: true,
|
|
478
|
-
action: flags.chronologyAction,
|
|
479
|
-
path: relative,
|
|
480
|
-
documentKey: mutation.documentKey,
|
|
481
|
-
override: mutation.override,
|
|
482
|
-
entityDecisions: mutation.entityDecisions,
|
|
483
|
-
editRevision: mutation.editRevision,
|
|
484
|
-
history: {
|
|
485
|
-
created: Boolean(history?.created),
|
|
486
|
-
hash: history?.commit || null,
|
|
487
|
-
error: history?.error || null,
|
|
488
|
-
},
|
|
489
|
-
};
|
|
490
|
-
|
|
491
|
-
if (flags.json) {
|
|
492
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
493
|
-
} else {
|
|
494
|
-
const verb = flags.chronologyAction === 'write' ? 'Correction créée' : 'Correction modifiée';
|
|
495
|
-
log.ok(`${verb} pour ${relative}.`);
|
|
496
|
-
}
|
|
497
|
-
return 0;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
async function runChronologyCommand(flags) {
|
|
501
|
-
if (flags.chronologyAction === 'write' || flags.chronologyAction === 'edit') {
|
|
502
|
-
return runChronologyCorrectionCommand(flags);
|
|
503
|
-
}
|
|
504
|
-
return runChronologyReadCommand(flags);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
359
|
function normalizedConversionRequest(value, caseRoot) {
|
|
508
360
|
const raw = String(value || '').trim();
|
|
509
361
|
if (!raw) throw new Error('Nom de pièce vide.');
|
|
@@ -570,6 +422,8 @@ async function waitForConversionJob({ folder, id }, { json = false } = {}) {
|
|
|
570
422
|
}
|
|
571
423
|
|
|
572
424
|
async function ensureServerForConversion({ json = false } = {}) {
|
|
425
|
+
await adoptRunningServerPort();
|
|
426
|
+
if (await localServerReachable()) return;
|
|
573
427
|
const servicesModule = path.join(APP_CLI_LIB, 'services.mjs');
|
|
574
428
|
if (!fs.existsSync(servicesModule)) {
|
|
575
429
|
throw new Error(`Le serveur applicatif doit être démarré par la commande « piecemaker » avant la conversion (port ${appServerPort()}).`);
|
|
@@ -625,7 +479,6 @@ async function runConversionCommand(flags) {
|
|
|
625
479
|
}
|
|
626
480
|
|
|
627
481
|
async function runOperationalCommand(command, knownUpdate = null, flags = {}) {
|
|
628
|
-
if (command === 'chronology') return runChronologyCommand(flags);
|
|
629
482
|
if (command === 'conversion') return runConversionCommand(flags);
|
|
630
483
|
if (command === 'update') {
|
|
631
484
|
const pending = knownUpdate ?? checkForUpdate();
|
|
@@ -749,20 +602,14 @@ async function main() {
|
|
|
749
602
|
return 1;
|
|
750
603
|
}
|
|
751
604
|
|
|
752
|
-
if (
|
|
605
|
+
if (flags.command !== 'conversion' && (flags.caseTarget || flags.json)) {
|
|
753
606
|
banner();
|
|
754
|
-
log.error('Les options --case et --json sont réservées
|
|
755
|
-
return 1;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
if (flags.command === 'chronology' && !CHRONOLOGY_ACTIONS.has(flags.chronologyAction)) {
|
|
759
|
-
log.error('Action inconnue : utilisez « piecemaker chronology read|write|edit ».');
|
|
607
|
+
log.error('Les options --case et --json sont réservées à la commande conversion.');
|
|
760
608
|
return 1;
|
|
761
609
|
}
|
|
762
610
|
|
|
763
611
|
// Les sorties JSON sont directement consommées par les assistants.
|
|
764
|
-
if (
|
|
765
|
-
|| (flags.command === 'conversion' && flags.json)) {
|
|
612
|
+
if (flags.command === 'conversion' && flags.json) {
|
|
766
613
|
return runOperationalCommand(flags.command, null, flags);
|
|
767
614
|
}
|
|
768
615
|
|
|
@@ -7,5 +7,4 @@
|
|
|
7
7
|
* est importable sans effet de bord.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
export const COMMANDS = new Set(['
|
|
11
|
-
export const CHRONOLOGY_ACTIONS = new Set(['read', 'write', 'edit']);
|
|
10
|
+
export const COMMANDS = new Set(['conversion', 'install', 'doctor', 'check', 'update']);
|
|
@@ -4,20 +4,79 @@
|
|
|
4
4
|
* La conversion et l'analyse PII n'ont qu'un seul point d'entrée : la route
|
|
5
5
|
* `knowledge/scan` du serveur applicatif. Le CLI en est un client, sur la
|
|
6
6
|
* boucle locale, via le montage `/api/piecemaker/local` placé avant
|
|
7
|
-
* l'authentification. Le serveur applicatif écoute en clair sur
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* l'authentification. Le serveur applicatif écoute en clair sur la boucle
|
|
8
|
+
* locale : celui qui tourne déjà (application de bureau comprise, annoncé par
|
|
9
|
+
* `local-server.json` dans le dossier de données), sinon le port du CLI
|
|
10
|
+
* (`PIECEMAKER_APP_PORT`, 3003 par défaut). Aucun certificat n'entre en jeu et
|
|
11
|
+
* la requête ne sort jamais de 127.0.0.1.
|
|
10
12
|
*/
|
|
11
13
|
|
|
14
|
+
import fs from 'node:fs';
|
|
12
15
|
import http from 'node:http';
|
|
16
|
+
import os from 'node:os';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
|
|
19
|
+
import { GIT_REPO_ROOT } from './platform.mjs';
|
|
13
20
|
|
|
14
21
|
const LOCAL_BASE = '/api/piecemaker/local';
|
|
22
|
+
const LOOPBACK_HOSTS = new Set(['127.0.0.1', 'localhost', '::1', '0.0.0.0', '::']);
|
|
15
23
|
|
|
16
24
|
export function appServerPort() {
|
|
17
25
|
const parsed = Number.parseInt(process.env.PIECEMAKER_APP_PORT || '', 10);
|
|
18
26
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : 3003;
|
|
19
27
|
}
|
|
20
28
|
|
|
29
|
+
function runningServerMarkerPath() {
|
|
30
|
+
if (process.env.CLOUDCLI_HOME) return join(process.env.CLOUDCLI_HOME, 'local-server.json');
|
|
31
|
+
try {
|
|
32
|
+
const config = JSON.parse(fs.readFileSync(join(GIT_REPO_ROOT, 'product.config.json'), 'utf8'));
|
|
33
|
+
return join(os.homedir(), config.dataDirectoryName, 'local-server.json');
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function processAlive(pid) {
|
|
40
|
+
try {
|
|
41
|
+
process.kill(pid, 0);
|
|
42
|
+
return true;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return error.code === 'EPERM';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function runningServerPort(markerPath = runningServerMarkerPath()) {
|
|
49
|
+
if (!markerPath) return null;
|
|
50
|
+
try {
|
|
51
|
+
const marker = JSON.parse(fs.readFileSync(markerPath, 'utf8'));
|
|
52
|
+
const port = Number(marker?.port);
|
|
53
|
+
const pid = Number(marker?.pid);
|
|
54
|
+
if (!Number.isInteger(port) || port <= 0 || !LOOPBACK_HOSTS.has(marker?.host)) return null;
|
|
55
|
+
if (!Number.isInteger(pid) || pid <= 0 || !processAlive(pid)) return null;
|
|
56
|
+
return port;
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function localServerReachable(port = appServerPort()) {
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
const request = http.get({ hostname: '127.0.0.1', port, path: '/api/auth/status', timeout: 2_000 }, (response) => {
|
|
65
|
+
response.resume();
|
|
66
|
+
resolve(response.statusCode < 500);
|
|
67
|
+
});
|
|
68
|
+
request.on('timeout', () => request.destroy());
|
|
69
|
+
request.on('error', () => resolve(false));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function adoptRunningServerPort({ markerPath, reachable = localServerReachable } = {}) {
|
|
74
|
+
if (process.env.PIECEMAKER_APP_PORT) return appServerPort();
|
|
75
|
+
const port = runningServerPort(markerPath);
|
|
76
|
+
if (port && await reachable(port)) process.env.PIECEMAKER_APP_PORT = String(port);
|
|
77
|
+
return appServerPort();
|
|
78
|
+
}
|
|
79
|
+
|
|
21
80
|
function requestJson({ method, path, body }) {
|
|
22
81
|
const payload = body === undefined ? null : Buffer.from(JSON.stringify(body));
|
|
23
82
|
return new Promise((resolve, reject) => {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Étape 06 — hooks Claude Code (protection,
|
|
2
|
+
* Étape 06 — hooks Claude Code (protection des pièces, recherche, documents IA).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* puis prouve que chaque script tourne proprement en lui envoyant une charge
|
|
4
|
+
* Prouve que chaque script tourne proprement en lui envoyant une charge
|
|
6
5
|
* utile synthétique sur stdin — le contrat exact qu'utilise Claude Code (voir
|
|
7
6
|
* piecemaker-plugin/scripts/lib/hook-io.mjs).
|
|
8
7
|
*
|
|
@@ -17,8 +16,7 @@ import os from 'node:os';
|
|
|
17
16
|
import path from 'node:path';
|
|
18
17
|
import { createRequire } from 'node:module';
|
|
19
18
|
import { log, spinner } from '../lib/ui.mjs';
|
|
20
|
-
import {
|
|
21
|
-
import { updateConfig } from '../lib/state.mjs';
|
|
19
|
+
import { HOME_DIR, REPO_ROOT, runCapture } from '../lib/platform.mjs';
|
|
22
20
|
|
|
23
21
|
const require = createRequire(import.meta.url);
|
|
24
22
|
const {
|
|
@@ -30,21 +28,17 @@ const {
|
|
|
30
28
|
|
|
31
29
|
export const meta = {
|
|
32
30
|
id: '06-hooks',
|
|
33
|
-
label: 'Hooks Claude Code (protection
|
|
34
|
-
description: 'Configure les garde-fous
|
|
31
|
+
label: 'Hooks Claude Code (protection des pièces)',
|
|
32
|
+
description: 'Configure les garde-fous et les hooks de recherche et de classement des documents IA',
|
|
35
33
|
};
|
|
36
34
|
|
|
37
35
|
const PLUGIN_ROOT = path.join(REPO_ROOT, 'piecemaker-plugin');
|
|
38
36
|
const SCRIPTS_DIR = path.join(PLUGIN_ROOT, 'scripts');
|
|
39
37
|
const HOOKS_JSON = path.join(PLUGIN_ROOT, 'hooks', 'hooks.json');
|
|
40
|
-
const BILLING_DIR = path.join(HOME_DIR, 'billing');
|
|
41
|
-
const SYNTHESE_DIR = path.join(BILLING_DIR, 'synthese');
|
|
42
38
|
|
|
43
39
|
const HOOK_SCRIPTS = {
|
|
44
40
|
protect: path.join(SCRIPTS_DIR, 'protect-originals.mjs'),
|
|
45
|
-
commit: path.join(SCRIPTS_DIR, 'commit-track.mjs'),
|
|
46
41
|
classify: path.join(SCRIPTS_DIR, 'classify-ai-documents.mjs'),
|
|
47
|
-
billing: path.join(SCRIPTS_DIR, 'billing-track.mjs'),
|
|
48
42
|
statusline: path.join(SCRIPTS_DIR, 'statusline.mjs'),
|
|
49
43
|
};
|
|
50
44
|
|
|
@@ -73,29 +67,12 @@ function runHookSelfTest(label, scriptPath, payload) {
|
|
|
73
67
|
return { label, ok: false, note: 'sortie stdout non-JSON — contrat de hook invalide' };
|
|
74
68
|
}
|
|
75
69
|
}
|
|
76
|
-
return { label, ok: true, note: result.stdout ? 'sortie JSON valide' : 'exit 0 (aucune sortie)' };
|
|
70
|
+
return { label, ok: true, stdout: result.stdout, note: result.stdout ? 'sortie JSON valide' : 'exit 0 (aucune sortie)' };
|
|
77
71
|
}
|
|
78
72
|
|
|
79
73
|
export async function install(ctx) {
|
|
80
|
-
log.step('Répertoires de facturation...');
|
|
81
|
-
if (!ctx.dryRun) {
|
|
82
|
-
ensureDir(BILLING_DIR);
|
|
83
|
-
ensureDir(SYNTHESE_DIR);
|
|
84
|
-
}
|
|
85
|
-
log.ok(`${BILLING_DIR}`);
|
|
86
|
-
|
|
87
74
|
if (ctx.dryRun) {
|
|
88
|
-
log.info('[simulation] configuration commits/facturation non écrite');
|
|
89
75
|
log.info('[simulation] hooks PieceMaker fusionnés directement dans ~/.claude/settings.json');
|
|
90
|
-
} else {
|
|
91
|
-
updateConfig({
|
|
92
|
-
commits: { enabled: true, timeoutMs: 8000 },
|
|
93
|
-
billing: { enabled: true },
|
|
94
|
-
});
|
|
95
|
-
log.ok('Configuration écrite dans ~/.piecemaker/config.json (commits, billing)');
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (ctx.dryRun) {
|
|
99
76
|
return { status: 'skipped', note: 'Mode simulation — hooks non vérifiés.' };
|
|
100
77
|
}
|
|
101
78
|
|
|
@@ -109,10 +86,14 @@ export async function install(ctx) {
|
|
|
109
86
|
// Un vrai dossier juridique factice, sans point de tête : les hooks
|
|
110
87
|
// ignorent les répertoires cachés, un bac de test caché ne prouverait donc
|
|
111
88
|
// rien du garde-fou. Comme seul un projet publié est un dossier juridique,
|
|
112
|
-
// on le publie le temps du test sous une source dédiée, retirée ensuite
|
|
113
|
-
|
|
89
|
+
// on le publie le temps du test sous une source dédiée, retirée ensuite,
|
|
90
|
+
// et comme anonymisé : le garde-fou n'agit que sous un bouclier vert.
|
|
91
|
+
// Les dossiers temporaires du système ne sont jamais des dossiers
|
|
92
|
+
// juridiques : le bac vit donc dans le répertoire PieceMaker.
|
|
93
|
+
fs.mkdirSync(HOME_DIR, { recursive: true });
|
|
94
|
+
testDir = fs.realpathSync(fs.mkdtempSync(path.join(HOME_DIR, 'hook-selftest-')));
|
|
114
95
|
fs.writeFileSync(path.join(testDir, 'piece-selftest.pdf'), 'PIECE DE TEST', 'utf8');
|
|
115
|
-
publishProjectSource('installer-selftest', [testDir]);
|
|
96
|
+
publishProjectSource('installer-selftest', [testDir], [testDir]);
|
|
116
97
|
selftestRegistered = true;
|
|
117
98
|
|
|
118
99
|
// 1. protect-originals.mjs — une pièce du bac de test : protégée par
|
|
@@ -127,38 +108,15 @@ export async function install(ctx) {
|
|
|
127
108
|
tool_input: { file_path: path.join(testDir, 'piece-selftest.pdf') },
|
|
128
109
|
tool_use_id: 'toolu_installer_originals_selftest',
|
|
129
110
|
});
|
|
111
|
+
if (protectedResult.ok && !/"permissionDecision"\s*:\s*"deny"/.test(protectedResult.stdout || '')) {
|
|
112
|
+
protectedResult.ok = false;
|
|
113
|
+
protectedResult.note = 'la pièce du bac de test n\'a pas été bloquée';
|
|
114
|
+
} else if (protectedResult.ok) {
|
|
115
|
+
protectedResult.note = 'pièce protégée bloquée';
|
|
116
|
+
}
|
|
130
117
|
testResults.push(protectedResult);
|
|
131
118
|
|
|
132
|
-
// 2.
|
|
133
|
-
// d'entrée/sortie sans créer de vrai commit pendant l'installation.
|
|
134
|
-
const commitResult = runHookSelfTest('commit-track.mjs', HOOK_SCRIPTS.commit, {
|
|
135
|
-
hook_event_name: 'PostToolUse',
|
|
136
|
-
session_id: 'installer-selftest',
|
|
137
|
-
cwd: REPO_ROOT,
|
|
138
|
-
transcript_path: '',
|
|
139
|
-
permission_mode: 'default',
|
|
140
|
-
tool_name: 'Edit',
|
|
141
|
-
tool_input: { file_path: path.join(REPO_ROOT, 'README.md') },
|
|
142
|
-
tool_response: { success: false },
|
|
143
|
-
tool_use_id: 'toolu_installer_commit_selftest',
|
|
144
|
-
});
|
|
145
|
-
testResults.push(commitResult);
|
|
146
|
-
|
|
147
|
-
// 3. billing-track.mjs — une vraie charge utile Stop : ajoute une ligne
|
|
148
|
-
// (clairement identifiée) au registre du mois et écrit une synthèse,
|
|
149
|
-
// ce qui prouve le chemin d'écriture de bout en bout.
|
|
150
|
-
const billingResult = runHookSelfTest('billing-track.mjs', HOOK_SCRIPTS.billing, {
|
|
151
|
-
hook_event_name: 'Stop',
|
|
152
|
-
session_id: 'installer-selftest',
|
|
153
|
-
cwd: REPO_ROOT,
|
|
154
|
-
transcript_path: path.join(testDir, 'transcript-selftest.jsonl'),
|
|
155
|
-
permission_mode: 'default',
|
|
156
|
-
last_assistant_message: 'Test d\'installation PieceMaker — vérification du hook de facturation.',
|
|
157
|
-
stop_reason: 'end_turn',
|
|
158
|
-
});
|
|
159
|
-
testResults.push(billingResult);
|
|
160
|
-
|
|
161
|
-
// 4. classify-ai-documents.mjs — un document « créé par l'IA » dans le bac
|
|
119
|
+
// 2. classify-ai-documents.mjs — un document « créé par l'IA » dans le bac
|
|
162
120
|
// de test enregistré doit ressortir classé « espace de travail » dans
|
|
163
121
|
// `.piecemaker/protection.json`, sans quoi l'IA ne pourrait pas se
|
|
164
122
|
// relire. On vérifie l'effet de bord, pas seulement le code de sortie.
|
|
@@ -201,7 +159,6 @@ export async function install(ctx) {
|
|
|
201
159
|
if (r.ok) log.ok(`${r.label} : ${r.note}`);
|
|
202
160
|
else log.error(`${r.label} : ${r.note}`);
|
|
203
161
|
}
|
|
204
|
-
log.detail(`Une ligne de test a été ajoutée à ${path.join(BILLING_DIR, `${new Date().toISOString().slice(0, 7)}.jsonl`)} (session "installer-selftest") — supprimez-la si besoin.`);
|
|
205
162
|
if (!fs.existsSync(HOOKS_JSON)) {
|
|
206
163
|
log.warn(`hooks/hooks.json introuvable dans le plugin : ${HOOKS_JSON}`);
|
|
207
164
|
}
|
|
@@ -232,12 +189,9 @@ export async function install(ctx) {
|
|
|
232
189
|
return { status: 'done', note: '' };
|
|
233
190
|
}
|
|
234
191
|
|
|
235
|
-
export async function check(
|
|
192
|
+
export async function check() {
|
|
236
193
|
const scriptsExist = Object.values(HOOK_SCRIPTS).every((p) => fs.existsSync(p));
|
|
237
194
|
const hooksJsonExists = fs.existsSync(HOOKS_JSON);
|
|
238
|
-
const dirsExist = fs.existsSync(BILLING_DIR) && fs.existsSync(SYNTHESE_DIR);
|
|
239
|
-
const cfg = ctx.config || {};
|
|
240
|
-
const configOk = Boolean(cfg.commits && cfg.billing);
|
|
241
195
|
const hooksRegistered = claudeHooksStatus(REPO_ROOT, os.homedir()).ok;
|
|
242
196
|
const statusLine = claudeStatusLineStatus(REPO_ROOT, os.homedir());
|
|
243
197
|
const statusLineOk = statusLine.ok || statusLine.conflict; // une statusLine personnelle n'est pas une anomalie
|
|
@@ -245,8 +199,8 @@ export async function check(ctx) {
|
|
|
245
199
|
if (!scriptsExist || !hooksJsonExists) {
|
|
246
200
|
return { status: 'failed', note: 'Fichiers du plugin manquants (scripts ou hooks.json) — réinstallez piecemaker-plugin/.' };
|
|
247
201
|
}
|
|
248
|
-
if (!
|
|
249
|
-
return { status: 'partial', note: 'Scripts présents mais
|
|
202
|
+
if (!hooksRegistered) {
|
|
203
|
+
return { status: 'partial', note: 'Scripts présents mais hooks non enregistrés dans Claude Code — relancez cette étape.' };
|
|
250
204
|
}
|
|
251
205
|
if (!statusLineOk) {
|
|
252
206
|
return { status: 'partial', note: `statusLine Claude Code absente ou périmée (${statusLine.reason}) — relancez cette étape.` };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Étape 12 — serveur MCP « piecemaker » (conversion
|
|
2
|
+
* Étape 12 — serveur MCP « piecemaker » (conversion).
|
|
3
3
|
*
|
|
4
4
|
* Les commandes de conversion sont aujourd'hui présentées au
|
|
5
5
|
* modèle par du texte injecté dans les templates, sans rien qui relie ce
|
|
@@ -21,8 +21,8 @@ import { REPO_ROOT, commandExists, run, runCapture } from '../lib/platform.mjs';
|
|
|
21
21
|
|
|
22
22
|
export const meta = {
|
|
23
23
|
id: '12-mcp-piecemaker',
|
|
24
|
-
label: 'Serveur MCP piecemaker (conversion
|
|
25
|
-
description: 'Enregistre dans Claude Code le serveur MCP qui expose la conversion
|
|
24
|
+
label: 'Serveur MCP piecemaker (conversion)',
|
|
25
|
+
description: 'Enregistre dans Claude Code le serveur MCP qui expose la conversion',
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
const SERVER_NAME = 'piecemaker';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# MCP PieceMaker
|
|
2
2
|
|
|
3
3
|
Point d'entrée du serveur MCP `piecemaker` (`piecemaker/server.mjs`), qui expose
|
|
4
|
-
|
|
4
|
+
l'outil `conversion` en pilotant
|
|
5
5
|
`installer/bin/piecemaker.mjs`.
|
|
6
6
|
|
|
7
7
|
- `REPO_ROOT`, calculé deux niveaux au-dessus de ce fichier, résout vers
|