@piecemaker-legal/piecemaker 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{abnfDiagram-VCTEODGH-DF7LFtT-.js → abnfDiagram-VCTEODGH-CR3_ADBu.js} +1 -1
- package/dist/assets/{arc-xOmjWeVH.js → arc-b92imMmc.js} +1 -1
- package/dist/assets/{architectureDiagram-5GKGNRK7-CESzNPwa.js → architectureDiagram-5GKGNRK7-Dfm5Epud.js} +1 -1
- package/dist/assets/{blockDiagram-I7D4REHJ-BjdN78Ad.js → blockDiagram-I7D4REHJ-B8kLLyAv.js} +1 -1
- package/dist/assets/{c4Diagram-7LVT6UL2-BcK9EDWT.js → c4Diagram-7LVT6UL2-BWSyAAWX.js} +1 -1
- package/dist/assets/channel-BbcW_Tkh.js +1 -0
- package/dist/assets/{chunk-2Q5K7J3B-DGUN1JFP.js → chunk-2Q5K7J3B-Ci743mcC.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-BG3BBcFr.js → chunk-5VM5RSS4-SdXpal6h.js} +1 -1
- package/dist/assets/{chunk-F27PBJKO-CLIOfrF5.js → chunk-F27PBJKO-Rof94ueX.js} +1 -1
- package/dist/assets/{chunk-IMKFNOWR-D6lGkqij.js → chunk-IMKFNOWR-B3st6ECc.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BmF9vLBT.js → chunk-JWPE2WC7-alXmu5xU.js} +1 -1
- package/dist/assets/{chunk-POPQ4Y6H-C_0SR3ak.js → chunk-POPQ4Y6H-dMs1OCce.js} +1 -1
- package/dist/assets/{chunk-SVP7TREG-rT20Wfpp.js → chunk-SVP7TREG-BmM8FsmF.js} +1 -1
- package/dist/assets/{chunk-TICWLB2K-Cn2hkmcf.js → chunk-TICWLB2K-CL1LytYG.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-Dm_eP1_v.js → chunk-XXDRQBXY-7U9iRPT1.js} +1 -1
- package/dist/assets/classDiagram-ZZMXUADV-D9_YRZ7i.js +1 -0
- package/dist/assets/classDiagram-v2-VYDZK3BY-D9_YRZ7i.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-cJeeJsep.js → cose-bilkent-JH36ORCC-DFOMlhj2.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-DX2ePIXe.js → cynefin-OW5HDTMX-CDdJFd9d.js} +1 -1
- package/dist/assets/{cynefinDiagram-5FMLGOSQ-BvWXN-RR.js → cynefinDiagram-5FMLGOSQ-DPyVNrMW.js} +1 -1
- package/dist/assets/{dagre-GXQ25YYZ-CkwPRhGR.js → dagre-GXQ25YYZ-B3bpHa9D.js} +1 -1
- package/dist/assets/{diagram-S7CK7UJ4-CBGNzYyv.js → diagram-S7CK7UJ4-DeFO2rXB.js} +1 -1
- package/dist/assets/{diagram-UQ7AKVKN-CiwCU0SJ.js → diagram-UQ7AKVKN-CbdGTOVf.js} +1 -1
- package/dist/assets/{diagram-VSXAHHWV-Aekg4nTk.js → diagram-VSXAHHWV-DFfNQyMd.js} +1 -1
- package/dist/assets/{diagram-VX7I27RA-DPFP5K7r.js → diagram-VX7I27RA-DbNZ6_X3.js} +1 -1
- package/dist/assets/{diagram-Z3DM3KII-BHJkxoey.js → diagram-Z3DM3KII-B8F-ZkNJ.js} +1 -1
- package/dist/assets/{ebnfDiagram-PWID7BFC-2rV1P32T.js → ebnfDiagram-PWID7BFC-BfCCPPAP.js} +1 -1
- package/dist/assets/{erDiagram-RLTQ6QDP-C4BjyS_H.js → erDiagram-RLTQ6QDP-DcV-3Kzv.js} +1 -1
- package/dist/assets/{flowDiagram-HODETNUW-DL1TBlAG.js → flowDiagram-HODETNUW-BwSkJXCo.js} +1 -1
- package/dist/assets/{ganttDiagram-EL5Y4UJY-MKjvzCWz.js → ganttDiagram-EL5Y4UJY-BffHk77T.js} +1 -1
- package/dist/assets/{gitGraphDiagram-WWUBYQGX-CS_oTGK5.js → gitGraphDiagram-WWUBYQGX-CQ1EWa74.js} +1 -1
- package/dist/assets/{index-XOGQDqU3.js → index-BqK33gaZ.js} +120 -120
- package/dist/assets/index-D_Dc_nQv.css +1 -0
- package/dist/assets/{infoDiagram-27XIBGKW-ihUr2GjN.js → infoDiagram-27XIBGKW-DqIaBXQn.js} +1 -1
- package/dist/assets/{ishikawaDiagram-5VMMS53U-D2YAnuir.js → ishikawaDiagram-5VMMS53U-HlhsaZgv.js} +1 -1
- package/dist/assets/{journeyDiagram-3NMN7TZE-Bc2hSZGD.js → journeyDiagram-3NMN7TZE-BYO8-7rN.js} +1 -1
- package/dist/assets/{kanban-definition-UXKFOSKX-LRMGNonX.js → kanban-definition-UXKFOSKX-DXb8zHGT.js} +1 -1
- package/dist/assets/{layout-CcfWOlPV.js → layout-CREOVuEZ.js} +1 -1
- package/dist/assets/{linear-7JoS2gQO.js → linear-CVCrIRIY.js} +1 -1
- package/dist/assets/{mermaid.core-ijh_SsuN.js → mermaid.core-DFqeWtQR.js} +6 -6
- package/dist/assets/{mindmap-definition-YA3MSWOX-DCE4nzfF.js → mindmap-definition-YA3MSWOX-SUpXz333.js} +1 -1
- package/dist/assets/{pegDiagram-XKGWAZYB-SjaGa7lE.js → pegDiagram-XKGWAZYB-D-yWpve3.js} +1 -1
- package/dist/assets/{pieDiagram-E7YTZNPT-1xcRidSZ.js → pieDiagram-E7YTZNPT-BJX4Zp4Z.js} +1 -1
- package/dist/assets/{quadrantDiagram-AXDQQJYC-obHAHnYV.js → quadrantDiagram-AXDQQJYC-CHajheTu.js} +1 -1
- package/dist/assets/{railroadDiagram-O6MQD6OU-BsCVcRZb.js → railroadDiagram-O6MQD6OU-DHJWzW5A.js} +1 -1
- package/dist/assets/{requirementDiagram-BXWQKSXE-CUNkhvqb.js → requirementDiagram-BXWQKSXE-DigUIdso.js} +1 -1
- package/dist/assets/{sankeyDiagram-P5KCCOFB-DhezXMKm.js → sankeyDiagram-P5KCCOFB-CFUDDbA5.js} +1 -1
- package/dist/assets/{sequenceDiagram-WJ2MYXX4-CL9VswXH.js → sequenceDiagram-WJ2MYXX4-6tSaXfYD.js} +1 -1
- package/dist/assets/{sizeCapture-INFHLROL-t0g9jiEz.js → sizeCapture-INFHLROL-CXASEDKe.js} +1 -1
- package/dist/assets/{stateDiagram-D77RDMKH-BW-g-IOz.js → stateDiagram-D77RDMKH-DWTCAQfZ.js} +1 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-HDQF4MGA.js +1 -0
- package/dist/assets/{swimlanes-42K2YHIH-LsuyeBte.js → swimlanes-42K2YHIH-7-oz5r-e.js} +1 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-CJbgQFt8.js +8 -0
- package/dist/assets/{timeline-definition-24CTP7MA-B0cFka1R.js → timeline-definition-24CTP7MA-DVH5g4ty.js} +1 -1
- package/dist/assets/{vendor-codemirror-C5qqu4R7.js → vendor-codemirror-CjW0lHR5.js} +5 -5
- package/dist/assets/{vennDiagram-4TSXK5OY-D3HNCDR3.js → vennDiagram-4TSXK5OY-CQvY_ALZ.js} +1 -1
- package/dist/assets/{wardleyDiagram-VM6X3IG4-DJ3Co8nb.js → wardleyDiagram-VM6X3IG4-BdlTJgEc.js} +1 -1
- package/dist/assets/{xychartDiagram-S5SC5T6Z-Cz5E9New.js → xychartDiagram-S5SC5T6Z-CYn2sV77.js} +1 -1
- package/dist/favicon.png +0 -0
- package/dist/favicon.svg +1 -9
- package/dist/generate-icons.js +47 -46
- package/dist/icons/icon-128x128.png +0 -0
- package/dist/icons/icon-128x128.svg +1 -12
- package/dist/icons/icon-144x144.png +0 -0
- package/dist/icons/icon-144x144.svg +1 -12
- package/dist/icons/icon-152x152.png +0 -0
- package/dist/icons/icon-152x152.svg +1 -12
- package/dist/icons/icon-192x192.png +0 -0
- package/dist/icons/icon-192x192.svg +1 -12
- package/dist/icons/icon-384x384.png +0 -0
- package/dist/icons/icon-384x384.svg +1 -12
- package/dist/icons/icon-512x512.png +0 -0
- package/dist/icons/icon-512x512.svg +1 -12
- package/dist/icons/icon-72x72.png +0 -0
- package/dist/icons/icon-72x72.svg +1 -12
- package/dist/icons/icon-96x96.png +0 -0
- package/dist/icons/icon-96x96.svg +1 -12
- package/dist/index.html +3 -3
- package/dist/logo-128.png +0 -0
- package/dist/logo-256.png +0 -0
- package/dist/logo-32.png +0 -0
- package/dist/logo-512.png +0 -0
- package/dist/logo-64.png +0 -0
- package/dist/logo-sources/logo-black.png +0 -0
- package/dist/logo-sources/logo-white.png +0 -0
- package/dist/logo.svg +1 -17
- package/dist/sw.js +1 -1
- package/dist-server/plugins/piecemaker-dossier/src/institutional-terms.js +91 -0
- package/dist-server/plugins/piecemaker-dossier/src/institutional-terms.js.map +1 -0
- package/dist-server/plugins/piecemaker-dossier/src/knowledge.js +112 -10
- package/dist-server/plugins/piecemaker-dossier/src/knowledge.js.map +1 -1
- package/dist-server/plugins/piecemaker-dossier/src/scan-result.js +5 -1
- package/dist-server/plugins/piecemaker-dossier/src/scan-result.js.map +1 -1
- package/dist-server/server/index.js +60 -26
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/database/repositories/projects.db.js +28 -6
- package/dist-server/server/modules/database/repositories/projects.db.js.map +1 -1
- package/dist-server/server/modules/database/tests/projects.db.integration.test.js +58 -1
- package/dist-server/server/modules/database/tests/projects.db.integration.test.js.map +1 -1
- package/dist-server/server/modules/plugins/plugins.routes.js +8 -1
- package/dist-server/server/modules/plugins/plugins.routes.js.map +1 -1
- package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js +2 -0
- package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js.map +1 -1
- package/dist-server/server/piecemaker/bodacc-search.js +191 -0
- package/dist-server/server/piecemaker/bodacc-search.js.map +1 -0
- package/dist-server/server/piecemaker/company-search.js +145 -0
- package/dist-server/server/piecemaker/company-search.js.map +1 -0
- package/dist-server/server/piecemaker/company-search.test.js +18 -0
- package/dist-server/server/piecemaker/company-search.test.js.map +1 -0
- package/dist-server/server/piecemaker/index.js +6 -2
- package/dist-server/server/piecemaker/index.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/index.js +9 -4
- package/dist-server/server/piecemaker/knowledge/index.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/pipeline.js +68 -58
- package/dist-server/server/piecemaker/knowledge/pipeline.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/routes.js +2 -4
- package/dist-server/server/piecemaker/knowledge/routes.js.map +1 -1
- package/dist-server/server/piecemaker/knowledge/scan-jobs.js +91 -0
- package/dist-server/server/piecemaker/knowledge/scan-jobs.js.map +1 -0
- package/dist-server/server/piecemaker/knowledge/service.js +18 -36
- package/dist-server/server/piecemaker/knowledge/service.js.map +1 -1
- package/dist-server/server/piecemaker/library/connector-installation.js +224 -0
- package/dist-server/server/piecemaker/library/connector-installation.js.map +1 -0
- package/dist-server/server/piecemaker/library/index.js +11 -1
- package/dist-server/server/piecemaker/library/index.js.map +1 -1
- package/dist-server/server/piecemaker/library/marketplace.js +102 -43
- package/dist-server/server/piecemaker/library/marketplace.js.map +1 -1
- package/dist-server/server/piecemaker/library/migrate.js +8 -1
- package/dist-server/server/piecemaker/library/migrate.js.map +1 -1
- package/dist-server/server/piecemaker/library/provider-agents.js +50 -0
- package/dist-server/server/piecemaker/library/provider-agents.js.map +1 -0
- package/dist-server/server/piecemaker/library/provider-connectors.js +80 -0
- package/dist-server/server/piecemaker/library/provider-connectors.js.map +1 -0
- package/dist-server/server/piecemaker/library/provider-skills.js +11 -2
- package/dist-server/server/piecemaker/library/provider-skills.js.map +1 -1
- package/dist-server/server/piecemaker/library/store.js +125 -35
- package/dist-server/server/piecemaker/library/store.js.map +1 -1
- package/dist-server/server/piecemaker/library/workspace-installation.js +53 -29
- package/dist-server/server/piecemaker/library/workspace-installation.js.map +1 -1
- package/dist-server/server/piecemaker/timesheet/service.js +4 -21
- package/dist-server/server/piecemaker/timesheet/service.js.map +1 -1
- package/package.json +3 -2
- package/scripts/piecemaker/cli/install-command.mjs +35 -9
- package/scripts/piecemaker/cli/lib/config.mjs +1 -0
- package/scripts/piecemaker/cli/lib/piecemaker-anonymizer.mjs +78 -0
- package/scripts/piecemaker/cli/lib/plugins.mjs +2 -0
- package/scripts/piecemaker/cli/lib/pwa.mjs +46 -7
- package/scripts/piecemaker/cli/lib/services.mjs +65 -4
- package/scripts/piecemaker/cli/piecemaker-command.test.mjs +25 -0
- package/scripts/piecemaker/cli/piecemaker.mjs +45 -44
- package/scripts/piecemaker/cli/piecemaker.ps1 +8 -0
- package/scripts/piecemaker/cli/piecemaker.sh +6 -1
- package/server/index.ts +52 -23
- package/server/modules/database/repositories/projects.db.ts +28 -6
- package/server/modules/database/tests/projects.db.integration.test.ts +63 -1
- package/server/modules/plugins/plugins.routes.ts +8 -1
- package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +5 -0
- package/server/piecemaker/anonymizer/client-config.cjs +10 -2
- package/server/piecemaker/anonymizer/dictionary.cjs +6 -72
- package/server/piecemaker/bodacc-search.ts +205 -0
- package/server/piecemaker/company-search.test.ts +26 -0
- package/server/piecemaker/company-search.ts +183 -0
- package/server/piecemaker/index.ts +8 -2
- package/server/piecemaker/knowledge/index.ts +9 -4
- package/server/piecemaker/knowledge/pipeline.ts +89 -57
- package/server/piecemaker/knowledge/routes.ts +2 -4
- package/server/piecemaker/knowledge/scan-jobs.ts +111 -0
- package/server/piecemaker/knowledge/service.ts +18 -33
- package/server/piecemaker/library/connector-installation.ts +248 -0
- package/server/piecemaker/library/index.ts +5 -1
- package/server/piecemaker/library/marketplace.ts +104 -39
- package/server/piecemaker/library/migrate.ts +8 -1
- package/server/piecemaker/library/provider-agents.ts +49 -0
- package/server/piecemaker/library/provider-connectors.ts +89 -0
- package/server/piecemaker/library/provider-skills.ts +10 -1
- package/server/piecemaker/library/store.ts +129 -36
- package/server/piecemaker/library/workspace-installation.ts +54 -29
- package/server/piecemaker/router.cjs +2 -1
- package/server/piecemaker/timesheet/service.ts +4 -16
- package/server/piecemaker/vendor/installer/steps/03-python-gliner.mjs +0 -27
- package/server/piecemaker/vendor/installer/steps/14-mxc-sandbox.mjs +1 -1
- package/server/piecemaker/vendor/piecemaker-plugin/scripts/lib/substitution.cjs +2 -3
- package/server/piecemaker/vendor/piecemaker-plugin/skills/conversion-md/SKILL.md +3 -3
- package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +3 -10
- package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +135 -4
- package/server/piecemaker/vendor/websocket-server/process-group.cjs +95 -0
- package/server/piecemaker/vendor/websocket-server/scripts/__pycache__/scan_utils.cpython-312.pyc +0 -0
- package/server/piecemaker/vendor/websocket-server/scripts/convert_and_scan_pipeline.py +280 -149
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/model_config.cpython-312.pyc +0 -0
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/scanner_worker.cpython-312.pyc +0 -0
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/scanner_worker.py +35 -29
- package/server/piecemaker/vendor/websocket-server/scripts/requirements.txt +0 -5
- package/server/shared/types.ts +1 -0
- package/dist/assets/channel-Dz3eE5vU.js +0 -1
- package/dist/assets/classDiagram-ZZMXUADV-BC1eKV2j.js +0 -1
- package/dist/assets/classDiagram-v2-VYDZK3BY-BC1eKV2j.js +0 -1
- package/dist/assets/index-DhwJpHCq.css +0 -1
- package/dist/assets/stateDiagram-v2-MP3YSRHH-BXuT4zDG.js +0 -1
- package/dist/assets/swimlanesDiagram-VR7AAH4N-B0eYrB4U.js +0 -8
- package/server/piecemaker/vendor/websocket-server/case-instructions.cjs +0 -111
- package/server/piecemaker/vendor/websocket-server/scripts/ADDRESS_ANONYMIZATION.md +0 -216
- package/server/piecemaker/vendor/websocket-server/scripts/DEDUPLICATION_CHANGES.md +0 -134
- package/server/piecemaker/vendor/websocket-server/scripts/GLINER2_README.md +0 -138
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/AUDIT_PERF_QUALITE.md +0 -246
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/MODELE_COREML.md +0 -62
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/__pycache__/coreml_runtime.cpython-312.pyc +0 -0
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/build_coreml.py +0 -118
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/coreml_runtime.py +0 -164
- package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/presidio-gliner.py +0 -479
|
@@ -6,6 +6,7 @@ import { spawn } from 'node:child_process';
|
|
|
6
6
|
import { APP, LOG_DIR, PIECEMAKER_HOME, PORTS } from './config.mjs';
|
|
7
7
|
import { waitUntil } from './exec.mjs';
|
|
8
8
|
import { npmPath, runtimeEnv } from './node-runtime.mjs';
|
|
9
|
+
import { freePort } from './ports.mjs';
|
|
9
10
|
|
|
10
11
|
export const APP_LOG = path.join(LOG_DIR, 'application.log');
|
|
11
12
|
export const APP_PID_FILE = path.join(PIECEMAKER_HOME, 'application.pid');
|
|
@@ -32,6 +33,53 @@ export function appClientReachable() {
|
|
|
32
33
|
return httpReachable(`http://127.0.0.1:${PORTS.appClient}/`);
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
function anonymizerPort() {
|
|
37
|
+
try {
|
|
38
|
+
const port = Number.parseInt(JSON.parse(fs.readFileSync(path.join(PIECEMAKER_HOME, 'config.json'), 'utf8')).mikePiiPort, 10);
|
|
39
|
+
if (Number.isInteger(port) && port > 0) return port;
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
return PORTS.anonymizer;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function stopPid(pid) {
|
|
46
|
+
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
|
|
47
|
+
if (process.platform === 'win32') {
|
|
48
|
+
try { process.kill(pid, 'SIGTERM'); return true; } catch { return false; }
|
|
49
|
+
}
|
|
50
|
+
try { process.kill(-pid, 'SIGTERM'); return true; } catch {
|
|
51
|
+
try { process.kill(pid, 'SIGTERM'); return true; } catch { return false; }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function stopApplication() {
|
|
56
|
+
const killed = [];
|
|
57
|
+
const occupied = [];
|
|
58
|
+
try {
|
|
59
|
+
const pid = Number.parseInt(fs.readFileSync(APP_PID_FILE, 'utf8'), 10);
|
|
60
|
+
if (stopPid(pid)) killed.push(pid);
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (const port of [PORTS.appClient, PORTS.appServer, anonymizerPort()]) {
|
|
65
|
+
const result = await freePort(port);
|
|
66
|
+
killed.push(...result.killed);
|
|
67
|
+
if (!result.released) occupied.push(port);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try { fs.rmSync(APP_PID_FILE, { force: true }); } catch { }
|
|
71
|
+
return { killed: [...new Set(killed)], occupied };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function readLogTail(file, maxLines = 40) {
|
|
75
|
+
try {
|
|
76
|
+
const lines = fs.readFileSync(file, 'utf8').trimEnd().split(/\n/);
|
|
77
|
+
return lines.slice(-maxLines).join('\n');
|
|
78
|
+
} catch {
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
35
83
|
export async function startApplication(runtime, report) {
|
|
36
84
|
const alreadyRunning = await appClientReachable() && await appServerReachable();
|
|
37
85
|
if (alreadyRunning) {
|
|
@@ -61,11 +109,24 @@ export async function startApplication(runtime, report) {
|
|
|
61
109
|
fs.closeSync(logHandle);
|
|
62
110
|
}
|
|
63
111
|
|
|
64
|
-
child.unref();
|
|
65
112
|
fs.writeFileSync(APP_PID_FILE, String(child.pid), 'utf8');
|
|
66
113
|
|
|
67
|
-
const
|
|
68
|
-
|
|
114
|
+
const death = new Promise((resolve) => {
|
|
115
|
+
child.once('error', () => resolve('died'));
|
|
116
|
+
child.once('exit', () => resolve('died'));
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await Promise.race([
|
|
120
|
+
waitUntil(appServerReachable, { timeoutMs: 120_000 }),
|
|
121
|
+
death,
|
|
122
|
+
]);
|
|
123
|
+
const serverUp = await appServerReachable();
|
|
124
|
+
if (!serverUp) {
|
|
125
|
+
child.unref();
|
|
126
|
+
return { started: true, pid: child.pid, serverUp: false, clientUp: false, logTail: readLogTail(APP_LOG) };
|
|
127
|
+
}
|
|
69
128
|
|
|
70
|
-
|
|
129
|
+
const clientUp = await waitUntil(appClientReachable, { timeoutMs: 120_000 });
|
|
130
|
+
child.unref();
|
|
131
|
+
return { started: true, pid: child.pid, serverUp: true, clientUp, logTail: clientUp ? '' : readLogTail(APP_LOG) };
|
|
71
132
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import test from 'node:test';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
import { BIN_DIR } from './lib/config.mjs';
|
|
8
|
+
import { piecemakerExecutable } from './install-command.mjs';
|
|
9
|
+
|
|
10
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
test('the curl bootstrap installs the piecemaker command before launching', () => {
|
|
13
|
+
const posix = fs.readFileSync(path.join(here, 'piecemaker.sh'), 'utf8');
|
|
14
|
+
const windows = fs.readFileSync(path.join(here, 'piecemaker.ps1'), 'utf8');
|
|
15
|
+
assert.match(posix, /install-command\.mjs/);
|
|
16
|
+
assert.match(windows, /install-command\.mjs/);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('the desktop launcher binds to the installed piecemaker binary', () => {
|
|
20
|
+
const executable = piecemakerExecutable();
|
|
21
|
+
assert.equal(path.basename(executable).startsWith('piecemaker'), true);
|
|
22
|
+
if (executable !== 'piecemaker') {
|
|
23
|
+
assert.equal(executable.startsWith(BIN_DIR) || executable.includes(`${path.sep}node${path.sep}` ) || executable.includes('versions/node'), true);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { installPiecemakerCommand, piecemakerExecutable } from './install-command.mjs';
|
|
3
4
|
import { APP, APP_URL, PORTS } from './lib/config.mjs';
|
|
5
|
+
import { repairClientProxies } from './lib/piecemaker-anonymizer.mjs';
|
|
4
6
|
import { installComponents } from './lib/composants.mjs';
|
|
5
7
|
import { installPlugins } from './lib/plugins.mjs';
|
|
6
8
|
import { gitAvailable, resolveNodeRuntime } from './lib/node-runtime.mjs';
|
|
7
|
-
import { freePort } from './lib/ports.mjs';
|
|
8
9
|
import { ensureDependencies, ensureRepository, rebuildNativeModules } from './lib/repos.mjs';
|
|
9
|
-
import { APP_LOG, appClientReachable, appServerReachable, startApplication } from './lib/services.mjs';
|
|
10
|
-
import { installApplicationEntry, openApplication, verifyPwaAssets } from './lib/pwa.mjs';
|
|
10
|
+
import { APP_LOG, appClientReachable, appServerReachable, startApplication, stopApplication } from './lib/services.mjs';
|
|
11
|
+
import { applicationWindowIsOpen, installApplicationEntry, openApplication, verifyPwaAssets } from './lib/pwa.mjs';
|
|
11
12
|
import { banner, blank, c, detail, fail, ok, step, warn } from './lib/ui.mjs';
|
|
12
13
|
|
|
13
14
|
const report = { step, ok, warn, detail };
|
|
14
15
|
|
|
15
|
-
const HELP = `${c.bold('piecemaker')} — installe, met à jour et lance toute la plateforme.
|
|
16
|
+
const HELP = `${c.bold('piecemaker')} — installe, met à jour, répare et lance toute la plateforme.
|
|
16
17
|
|
|
17
|
-
piecemaker
|
|
18
|
-
piecemaker --launch-only
|
|
19
|
-
piecemaker --no-open ne pas ouvrir l application à la fin
|
|
18
|
+
piecemaker reset propre, puis installation et lancement
|
|
19
|
+
piecemaker --launch-only répare et relance seulement si l'application est arrêtée
|
|
20
20
|
piecemaker --help cette aide
|
|
21
21
|
`;
|
|
22
22
|
|
|
@@ -24,27 +24,9 @@ function parseArguments(argv) {
|
|
|
24
24
|
return {
|
|
25
25
|
help: argv.includes('--help') || argv.includes('-h'),
|
|
26
26
|
launchOnly: argv.includes('--launch-only'),
|
|
27
|
-
open: !argv.includes('--no-open'),
|
|
28
27
|
};
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
async function cleanPorts(launchOnly) {
|
|
32
|
-
step('Libération des ports');
|
|
33
|
-
const targets = launchOnly
|
|
34
|
-
? [PORTS.appServer, PORTS.appClient]
|
|
35
|
-
: [PORTS.appClient, PORTS.appServer];
|
|
36
|
-
|
|
37
|
-
for (const port of targets) {
|
|
38
|
-
const result = await freePort(port);
|
|
39
|
-
if (!result.released) {
|
|
40
|
-
warn(`port ${port} toujours occupé`);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
if (result.killed.length > 0) detail(`port ${port} libéré (${result.killed.join(', ')})`);
|
|
44
|
-
}
|
|
45
|
-
ok('Ports disponibles');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
30
|
async function synchroniseRepositories(runtime) {
|
|
49
31
|
if (!gitAvailable()) {
|
|
50
32
|
throw new Error('git est requis et introuvable.');
|
|
@@ -63,32 +45,43 @@ async function synchroniseRepositories(runtime) {
|
|
|
63
45
|
rebuildNativeModules(APP, runtime, report, ['better-sqlite3', 'node-pty']);
|
|
64
46
|
}
|
|
65
47
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
48
|
+
function printLogTail(logTail) {
|
|
49
|
+
if (!logTail) {
|
|
50
|
+
detail(`journal : ${APP_LOG}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
detail(`journal : ${APP_LOG}`);
|
|
54
|
+
for (const line of logTail.split('\n')) {
|
|
55
|
+
if (line.trim()) detail(line);
|
|
73
56
|
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function applicationIsRunning() {
|
|
60
|
+
return await appServerReachable() && await appClientReachable();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function resetAndLaunch(runtime) {
|
|
64
|
+
step('Reset de l application');
|
|
65
|
+
const stopped = await stopApplication();
|
|
66
|
+
if (stopped.killed.length) detail(`arrêtés : ${stopped.killed.join(', ')}`);
|
|
67
|
+
for (const port of stopped.occupied) warn(`port ${port} toujours occupé`);
|
|
68
|
+
ok('Processus précédents arrêtés');
|
|
74
69
|
|
|
75
70
|
const application = await startApplication(runtime, report);
|
|
76
71
|
if (application.alreadyRunning) {
|
|
77
72
|
ok(`Application déjà active — ${APP_URL}`);
|
|
78
73
|
return true;
|
|
79
74
|
}
|
|
80
|
-
|
|
81
75
|
if (!application.serverUp) {
|
|
82
76
|
fail(`Serveur applicatif injoignable sur le port ${PORTS.appServer}`);
|
|
83
|
-
|
|
77
|
+
printLogTail(application.logTail);
|
|
84
78
|
return false;
|
|
85
79
|
}
|
|
86
80
|
if (!application.clientUp) {
|
|
87
81
|
fail(`Client applicatif injoignable sur le port ${PORTS.appClient}`);
|
|
88
|
-
|
|
82
|
+
printLogTail(application.logTail);
|
|
89
83
|
return false;
|
|
90
84
|
}
|
|
91
|
-
|
|
92
85
|
ok(`Application active — serveur :${PORTS.appServer}, client ${APP_URL}`);
|
|
93
86
|
return true;
|
|
94
87
|
}
|
|
@@ -111,6 +104,7 @@ async function installPwa() {
|
|
|
111
104
|
for (const location of entry.locations || []) {
|
|
112
105
|
if (location !== entry.location) detail(`également posé : ${location}`);
|
|
113
106
|
}
|
|
107
|
+
detail(`icône liée à ${piecemakerExecutable()}`);
|
|
114
108
|
if (!entry.standalone) detail('navigateur Chromium absent : ouverture en onglet classique');
|
|
115
109
|
if (!entry.verified) warn('installation incomplète : un emplacement attendu est introuvable après coup');
|
|
116
110
|
}
|
|
@@ -127,7 +121,19 @@ async function main() {
|
|
|
127
121
|
const runtime = resolveNodeRuntime();
|
|
128
122
|
detail(`Node ${runtime.version}`);
|
|
129
123
|
|
|
130
|
-
|
|
124
|
+
step('Commande piecemaker');
|
|
125
|
+
const command = installPiecemakerCommand();
|
|
126
|
+
if (command.shims.length) ok(`installée : ${command.executable}`);
|
|
127
|
+
else warn('commande absente du PATH — relancez node scripts/piecemaker/cli/install-command.mjs');
|
|
128
|
+
|
|
129
|
+
await repairClientProxies({ appDir: APP.directory, report });
|
|
130
|
+
|
|
131
|
+
if (!options.launchOnly || !(await applicationIsRunning())) {
|
|
132
|
+
const running = await resetAndLaunch(runtime);
|
|
133
|
+
if (!running) return 1;
|
|
134
|
+
} else {
|
|
135
|
+
ok(`Application déjà active — ${APP_URL}`);
|
|
136
|
+
}
|
|
131
137
|
|
|
132
138
|
if (!options.launchOnly) {
|
|
133
139
|
await synchroniseRepositories(runtime);
|
|
@@ -135,19 +141,14 @@ async function main() {
|
|
|
135
141
|
await installPlugins(runtime, report);
|
|
136
142
|
}
|
|
137
143
|
|
|
138
|
-
|
|
139
|
-
if (!running) return 1;
|
|
140
|
-
|
|
141
|
-
if (!options.launchOnly) {
|
|
142
|
-
await installPwa();
|
|
143
|
-
}
|
|
144
|
+
await installPwa();
|
|
144
145
|
|
|
145
146
|
blank();
|
|
146
147
|
ok(`Application ${c.bold(APP_URL)}`);
|
|
147
148
|
detail('Configuration du socle : onglet Dossier › Configuration.');
|
|
148
149
|
blank();
|
|
149
150
|
|
|
150
|
-
if (options.
|
|
151
|
+
if (!options.launchOnly && !applicationWindowIsOpen()) openApplication();
|
|
151
152
|
return 0;
|
|
152
153
|
}
|
|
153
154
|
|
|
@@ -59,5 +59,13 @@ if (-not (Test-Path $EntryPath)) {
|
|
|
59
59
|
exit 1
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
$Installer = Join-Path $AppDir 'scripts\piecemaker\cli\install-command.mjs'
|
|
63
|
+
if (Test-Path $Installer) {
|
|
64
|
+
& $NodeBin $Installer
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
$BinDir = Join-Path $HOME '.piecemaker\bin'
|
|
68
|
+
$env:PATH = "$(Split-Path $NodeBin -Parent);$BinDir;$env:PATH"
|
|
69
|
+
|
|
62
70
|
& $NodeBin $EntryPath @args
|
|
63
71
|
exit $LASTEXITCODE
|
|
@@ -54,7 +54,12 @@ if [ ! -f "$APP_DIR/$ENTRY" ]; then
|
|
|
54
54
|
exit 1
|
|
55
55
|
fi
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
INSTALLER="$APP_DIR/scripts/piecemaker/cli/install-command.mjs"
|
|
58
|
+
if [ -f "$INSTALLER" ]; then
|
|
59
|
+
"$NODE_BIN" "$INSTALLER" || true
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
PATH="$(dirname "$NODE_BIN"):${HOME}/.piecemaker/bin:${PATH:-}"
|
|
58
63
|
export PATH
|
|
59
64
|
|
|
60
65
|
exec "$NODE_BIN" "$APP_DIR/$ENTRY" "$@"
|
package/server/index.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { commandsRoutes } from './modules/commands/index.js';
|
|
|
30
30
|
import { settingsRoutes } from './modules/settings/index.js';
|
|
31
31
|
import { createSystemModule } from './modules/system/index.js';
|
|
32
32
|
import { createAgentModule } from './modules/agent/index.js';
|
|
33
|
-
import { createPieceMakerRouter } from './piecemaker/index.js';
|
|
33
|
+
import { createPieceMakerRouter, stopOriginalsJobs } from './piecemaker/index.js';
|
|
34
34
|
import projectModuleRoutes from './modules/projects/projects.routes.js';
|
|
35
35
|
import notificationRoutes from './modules/notifications/notifications.routes.js';
|
|
36
36
|
import { userRoutes } from './modules/user/index.js';
|
|
@@ -378,29 +378,58 @@ async function startServer() {
|
|
|
378
378
|
});
|
|
379
379
|
});
|
|
380
380
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
381
|
+
let shutdownPromise: Promise<void> | null = null;
|
|
382
|
+
const shutdownRuntimeServices = () => {
|
|
383
|
+
if (shutdownPromise) return shutdownPromise;
|
|
384
|
+
shutdownPromise = (async () => {
|
|
385
|
+
// Stop accepting HTTP work first. Existing requests may finish while
|
|
386
|
+
// the process pipelines and background services are being drained.
|
|
387
|
+
const serverClosed = new Promise<void>((resolve, reject) => {
|
|
388
|
+
server.close((error) => {
|
|
389
|
+
if (error && getErrorCode(error) !== 'ERR_SERVER_NOT_RUNNING') reject(error);
|
|
390
|
+
else resolve();
|
|
391
|
+
});
|
|
392
|
+
}).catch((err) => {
|
|
393
|
+
console.error('[Server] Error closing HTTP server during shutdown:', getErrorMessage(err));
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
try {
|
|
397
|
+
await closeSessionsWatcher();
|
|
398
|
+
} catch (err) {
|
|
399
|
+
console.error('[Sessions] Error stopping watchers during shutdown:', getErrorMessage(err));
|
|
400
|
+
}
|
|
401
|
+
try {
|
|
402
|
+
closeScheduledMessageDispatcher();
|
|
403
|
+
} catch (err) {
|
|
404
|
+
console.error('[Scheduled messages] Error stopping dispatcher during shutdown:', getErrorMessage(err));
|
|
405
|
+
}
|
|
406
|
+
try {
|
|
407
|
+
await stopOriginalsJobs();
|
|
408
|
+
} catch (err) {
|
|
409
|
+
console.error('[PieceMaker] Error stopping pipeline jobs during shutdown:', getErrorMessage(err));
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
await browserUseService.stopAllSessions();
|
|
413
|
+
} catch (err) {
|
|
414
|
+
console.error('[Browser] Error stopping sessions during shutdown:', getErrorMessage(err));
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
await stopAllPlugins();
|
|
418
|
+
} catch (err) {
|
|
419
|
+
console.error('[Plugins] Error stopping plugins during shutdown:', getErrorMessage(err));
|
|
420
|
+
}
|
|
421
|
+
await serverClosed;
|
|
422
|
+
try {
|
|
423
|
+
await removeLocalServerMarker();
|
|
424
|
+
} catch (err) {
|
|
425
|
+
console.error('[Local Server] Error removing server marker during shutdown:', getErrorMessage(err));
|
|
426
|
+
}
|
|
427
|
+
process.exit(0);
|
|
428
|
+
})();
|
|
429
|
+
return shutdownPromise;
|
|
401
430
|
};
|
|
402
|
-
process.on('SIGTERM', () => void shutdownRuntimeServices());
|
|
403
|
-
process.on('SIGINT', () => void shutdownRuntimeServices());
|
|
431
|
+
process.on('SIGTERM', () => { void shutdownRuntimeServices(); });
|
|
432
|
+
process.on('SIGINT', () => { void shutdownRuntimeServices(); });
|
|
404
433
|
} catch (error) {
|
|
405
434
|
console.error('[ERROR] Failed to start server:', error);
|
|
406
435
|
process.exit(1);
|
|
@@ -15,6 +15,22 @@ function normalizeProjectDisplayName(projectPath: string, customProjectName: str
|
|
|
15
15
|
return directoryName || projectPath;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function ensureAnonymizationStatusTable(db: ReturnType<typeof getConnection>): void {
|
|
19
|
+
db.exec(`
|
|
20
|
+
CREATE TABLE IF NOT EXISTS piecemaker_anonymization_status (
|
|
21
|
+
project_id TEXT PRIMARY KEY NOT NULL,
|
|
22
|
+
completed_at TEXT NOT NULL,
|
|
23
|
+
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE CASCADE
|
|
24
|
+
)
|
|
25
|
+
`);
|
|
26
|
+
const mappingsExist = db.prepare(`SELECT 1 AS ok FROM sqlite_master WHERE type='table' AND name='piecemaker_mappings'`).get() as { ok: number } | undefined;
|
|
27
|
+
if (!mappingsExist) return;
|
|
28
|
+
db.prepare(`
|
|
29
|
+
INSERT OR IGNORE INTO piecemaker_anonymization_status(project_id, completed_at)
|
|
30
|
+
SELECT DISTINCT project_id, ? FROM piecemaker_mappings
|
|
31
|
+
`).run(new Date().toISOString());
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
export const projectsDb = {
|
|
19
35
|
createProjectPath(projectPath: string, customProjectName: string | null = null): CreateProjectPathResult {
|
|
20
36
|
const db = getConnection();
|
|
@@ -88,10 +104,13 @@ export const projectsDb = {
|
|
|
88
104
|
|
|
89
105
|
getProjectPaths(): ProjectRepositoryRow[] {
|
|
90
106
|
const db = getConnection();
|
|
107
|
+
ensureAnonymizationStatusTable(db);
|
|
91
108
|
return db.prepare(`
|
|
92
|
-
SELECT project_id, project_path, custom_project_name, isStarred, isArchived
|
|
93
|
-
|
|
94
|
-
|
|
109
|
+
SELECT p.project_id, p.project_path, p.custom_project_name, p.isStarred, p.isArchived,
|
|
110
|
+
CASE WHEN s.project_id IS NULL THEN 0 ELSE 1 END AS anonymization_complete
|
|
111
|
+
FROM projects p
|
|
112
|
+
LEFT JOIN piecemaker_anonymization_status s ON s.project_id = p.project_id
|
|
113
|
+
WHERE p.isArchived = 0
|
|
95
114
|
`).all() as ProjectRepositoryRow[];
|
|
96
115
|
},
|
|
97
116
|
|
|
@@ -101,10 +120,13 @@ export const projectsDb = {
|
|
|
101
120
|
*/
|
|
102
121
|
getArchivedProjectPaths(): ProjectRepositoryRow[] {
|
|
103
122
|
const db = getConnection();
|
|
123
|
+
ensureAnonymizationStatusTable(db);
|
|
104
124
|
return db.prepare(`
|
|
105
|
-
SELECT project_id, project_path, custom_project_name, isStarred, isArchived
|
|
106
|
-
|
|
107
|
-
|
|
125
|
+
SELECT p.project_id, p.project_path, p.custom_project_name, p.isStarred, p.isArchived,
|
|
126
|
+
CASE WHEN s.project_id IS NULL THEN 0 ELSE 1 END AS anonymization_complete
|
|
127
|
+
FROM projects p
|
|
128
|
+
LEFT JOIN piecemaker_anonymization_status s ON s.project_id = p.project_id
|
|
129
|
+
WHERE p.isArchived = 1
|
|
108
130
|
`).all() as ProjectRepositoryRow[];
|
|
109
131
|
},
|
|
110
132
|
|
|
@@ -4,7 +4,7 @@ import { tmpdir } from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import test from 'node:test';
|
|
6
6
|
|
|
7
|
-
import { closeConnection } from '@/modules/database/connection.js';
|
|
7
|
+
import { closeConnection, getConnection } from '@/modules/database/connection.js';
|
|
8
8
|
import { initializeDatabase } from '@/modules/database/init-db.js';
|
|
9
9
|
import { projectsDb } from '@/modules/database/repositories/projects.db.js';
|
|
10
10
|
|
|
@@ -70,3 +70,65 @@ test('projectsDb.createProjectPath returns active_conflict for active duplicates
|
|
|
70
70
|
assert.equal(conflict.project?.isArchived, 0);
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
+
|
|
74
|
+
test('projectsDb.getProjectPaths reads anonymization completion directly from SQLite', async () => {
|
|
75
|
+
await withIsolatedDatabase(() => {
|
|
76
|
+
const created = projectsDb.createProjectPath('/workspace/anonymized-project');
|
|
77
|
+
assert.ok(created.project);
|
|
78
|
+
|
|
79
|
+
projectsDb.getProjectPaths();
|
|
80
|
+
getConnection().prepare(`
|
|
81
|
+
INSERT INTO piecemaker_anonymization_status (project_id, completed_at)
|
|
82
|
+
VALUES (?, ?)
|
|
83
|
+
`).run(created.project.project_id, new Date().toISOString());
|
|
84
|
+
|
|
85
|
+
const project = projectsDb.getProjectPaths()[0];
|
|
86
|
+
assert.equal(project.anonymization_complete, 1);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('projectsDb.getProjectPaths backfills anonymization completion from existing mappings', async () => {
|
|
91
|
+
await withIsolatedDatabase(() => {
|
|
92
|
+
const created = projectsDb.createProjectPath('/workspace/legacy-scanned-project');
|
|
93
|
+
assert.ok(created.project);
|
|
94
|
+
const db = getConnection();
|
|
95
|
+
db.exec(`
|
|
96
|
+
CREATE TABLE IF NOT EXISTS piecemaker_nodes (
|
|
97
|
+
project_id TEXT NOT NULL,
|
|
98
|
+
id TEXT NOT NULL,
|
|
99
|
+
kind TEXT NOT NULL,
|
|
100
|
+
label TEXT NOT NULL,
|
|
101
|
+
search_text TEXT NOT NULL DEFAULT '',
|
|
102
|
+
aliases_json TEXT NOT NULL DEFAULT '[]',
|
|
103
|
+
data_json TEXT NOT NULL DEFAULT '{}',
|
|
104
|
+
origin TEXT NOT NULL DEFAULT 'gliner',
|
|
105
|
+
created_at TEXT NOT NULL,
|
|
106
|
+
updated_at TEXT NOT NULL,
|
|
107
|
+
PRIMARY KEY (project_id, id)
|
|
108
|
+
);
|
|
109
|
+
CREATE TABLE IF NOT EXISTS piecemaker_mappings (
|
|
110
|
+
project_id TEXT NOT NULL,
|
|
111
|
+
node_id TEXT NOT NULL,
|
|
112
|
+
real_value TEXT NOT NULL,
|
|
113
|
+
masked_value TEXT NOT NULL,
|
|
114
|
+
search_text TEXT NOT NULL DEFAULT '',
|
|
115
|
+
data_json TEXT NOT NULL DEFAULT '{}',
|
|
116
|
+
origin TEXT NOT NULL DEFAULT 'gliner',
|
|
117
|
+
created_at TEXT NOT NULL,
|
|
118
|
+
updated_at TEXT NOT NULL,
|
|
119
|
+
PRIMARY KEY (project_id, node_id, real_value)
|
|
120
|
+
);
|
|
121
|
+
`);
|
|
122
|
+
db.prepare(`
|
|
123
|
+
INSERT INTO piecemaker_nodes(project_id,id,kind,label,search_text,aliases_json,data_json,origin,created_at,updated_at)
|
|
124
|
+
VALUES (?, 'person-1', 'person', 'Alice', 'alice', '[]', '{}', 'gliner', ?, ?)
|
|
125
|
+
`).run(created.project.project_id, new Date().toISOString(), new Date().toISOString());
|
|
126
|
+
db.prepare(`
|
|
127
|
+
INSERT INTO piecemaker_mappings(project_id,node_id,real_value,masked_value,search_text,data_json,origin,created_at,updated_at)
|
|
128
|
+
VALUES (?, 'person-1', 'Alice', 'PERSONNE_PHYSIQUE_01', 'alice', '{}', 'gliner', ?, ?)
|
|
129
|
+
`).run(created.project.project_id, new Date().toISOString(), new Date().toISOString());
|
|
130
|
+
|
|
131
|
+
const project = projectsDb.getProjectPaths()[0];
|
|
132
|
+
assert.equal(project.anonymization_complete, 1);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -26,8 +26,15 @@ export function createPluginsRouter(service: ReturnType<typeof createPluginsServ
|
|
|
26
26
|
router.get('/:name/assets/*', async (req, res, next) => {
|
|
27
27
|
try {
|
|
28
28
|
const asset = service.resolveAsset(routeParameter(req.params.name), wildcardPath(req));
|
|
29
|
+
const stats = fs.statSync(asset.path);
|
|
30
|
+
const etag = `"${stats.mtimeMs.toString(16)}-${stats.size.toString(16)}"`;
|
|
29
31
|
res.setHeader('Content-Type', asset.contentType);
|
|
30
|
-
res.setHeader('
|
|
32
|
+
res.setHeader('ETag', etag);
|
|
33
|
+
res.setHeader('Cache-Control', 'private, max-age=0, must-revalidate');
|
|
34
|
+
if (req.headers['if-none-match'] === etag) {
|
|
35
|
+
res.status(304).end();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
31
38
|
const stream = fs.createReadStream(asset.path);
|
|
32
39
|
stream.on('error', next);
|
|
33
40
|
stream.pipe(res);
|
|
@@ -29,6 +29,7 @@ export type ProjectListItem = {
|
|
|
29
29
|
displayName: string;
|
|
30
30
|
fullPath: string;
|
|
31
31
|
isStarred: boolean;
|
|
32
|
+
anonymizationComplete: boolean;
|
|
32
33
|
sessions: SessionSummary[];
|
|
33
34
|
sessionMeta: {
|
|
34
35
|
hasMore: boolean;
|
|
@@ -189,6 +190,7 @@ export async function getProjectsWithSessions(
|
|
|
189
190
|
project_path: string;
|
|
190
191
|
custom_project_name?: string | null;
|
|
191
192
|
isStarred?: number;
|
|
193
|
+
anonymization_complete?: number;
|
|
192
194
|
}>;
|
|
193
195
|
const totalProjects = projectRows.length;
|
|
194
196
|
const projects: ProjectListItem[] = [];
|
|
@@ -223,6 +225,7 @@ export async function getProjectsWithSessions(
|
|
|
223
225
|
displayName,
|
|
224
226
|
fullPath: projectPath,
|
|
225
227
|
isStarred: Boolean(row.isStarred),
|
|
228
|
+
anonymizationComplete: Boolean(row.anonymization_complete),
|
|
226
229
|
sessions: sessionsPage.sessions,
|
|
227
230
|
sessionMeta: {
|
|
228
231
|
hasMore: sessionsPage.hasMore,
|
|
@@ -257,6 +260,7 @@ export async function getArchivedProjectsWithSessions(
|
|
|
257
260
|
project_path: string;
|
|
258
261
|
custom_project_name?: string | null;
|
|
259
262
|
isStarred?: number;
|
|
263
|
+
anonymization_complete?: number;
|
|
260
264
|
}>;
|
|
261
265
|
|
|
262
266
|
const archivedProjects: ArchivedProjectListItem[] = [];
|
|
@@ -275,6 +279,7 @@ export async function getArchivedProjectsWithSessions(
|
|
|
275
279
|
displayName,
|
|
276
280
|
fullPath: row.project_path,
|
|
277
281
|
isStarred: Boolean(row.isStarred),
|
|
282
|
+
anonymizationComplete: Boolean(row.anonymization_complete),
|
|
278
283
|
isArchived: true,
|
|
279
284
|
sessions: sessionsPage.sessions,
|
|
280
285
|
sessionMeta: {
|
|
@@ -138,10 +138,18 @@ function configureCodexProxy({
|
|
|
138
138
|
|
|
139
139
|
const managedTable = lines.findIndex((line) => line.trim() === `[model_providers.${CODEX_PROVIDER_ID}]`);
|
|
140
140
|
const managedStart = lines.findIndex((line) => line.trim() === CODEX_BLOCK_START);
|
|
141
|
-
|
|
142
|
-
if (managedTable >= 0 &&
|
|
141
|
+
let managedEnd = lines.findIndex((line) => line.trim() === CODEX_BLOCK_END);
|
|
142
|
+
if (managedTable >= 0 && managedStart < 0) {
|
|
143
143
|
return { configured: false, changed: false, conflict: true, file: configFile, reason: 'provider-table-conflict' };
|
|
144
144
|
}
|
|
145
|
+
if (managedStart >= 0 && managedEnd < managedStart) {
|
|
146
|
+
let end = managedTable >= managedStart ? managedTable : managedStart;
|
|
147
|
+
for (let index = end + 1; index < lines.length; index += 1) {
|
|
148
|
+
if (/^\s*\[/.test(lines[index])) break;
|
|
149
|
+
end = index;
|
|
150
|
+
}
|
|
151
|
+
managedEnd = end;
|
|
152
|
+
}
|
|
145
153
|
|
|
146
154
|
if (provider) {
|
|
147
155
|
lines[provider.index] = `model_provider = ${tomlString(CODEX_PROVIDER_ID)} # géré par PieceMaker`;
|