@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.
Files changed (135) hide show
  1. package/dist/assets/{abnfDiagram-VCTEODGH-DEXWh3LH.js → abnfDiagram-VCTEODGH-C2JDmlZx.js} +1 -1
  2. package/dist/assets/{arc-CoTRLXKW.js → arc-XhSg5Mrj.js} +1 -1
  3. package/dist/assets/{architectureDiagram-5GKGNRK7-Cg-jO9oR.js → architectureDiagram-5GKGNRK7-DKREuXxk.js} +1 -1
  4. package/dist/assets/{blockDiagram-I7D4REHJ-ChXwQSIq.js → blockDiagram-I7D4REHJ-CNK0Tp5d.js} +1 -1
  5. package/dist/assets/{c4Diagram-7LVT6UL2-Bw2VGggd.js → c4Diagram-7LVT6UL2-C8fJzWVp.js} +1 -1
  6. package/dist/assets/channel-DO5hoFdU.js +1 -0
  7. package/dist/assets/{chunk-2Q5K7J3B-C1WdqrLP.js → chunk-2Q5K7J3B-DlE8nLJo.js} +1 -1
  8. package/dist/assets/{chunk-5VM5RSS4-BerUZBa1.js → chunk-5VM5RSS4-CSm-2TZ4.js} +1 -1
  9. package/dist/assets/{chunk-F27PBJKO-5W7ax2gB.js → chunk-F27PBJKO-CSgnXT2c.js} +1 -1
  10. package/dist/assets/{chunk-IMKFNOWR-JgDN1h4T.js → chunk-IMKFNOWR-C6bkt6C1.js} +1 -1
  11. package/dist/assets/{chunk-JWPE2WC7-ulNHnEdQ.js → chunk-JWPE2WC7-jUR52MBO.js} +1 -1
  12. package/dist/assets/{chunk-POPQ4Y6H-D4aTDC2T.js → chunk-POPQ4Y6H-D0UAL7O7.js} +1 -1
  13. package/dist/assets/{chunk-SVP7TREG-BA5zX4XF.js → chunk-SVP7TREG-C9dtOEii.js} +1 -1
  14. package/dist/assets/{chunk-TICWLB2K-DhOULVhX.js → chunk-TICWLB2K-BEzWKT39.js} +1 -1
  15. package/dist/assets/{chunk-XXDRQBXY-CkpCgrVg.js → chunk-XXDRQBXY-uD1oklVY.js} +1 -1
  16. package/dist/assets/classDiagram-ZZMXUADV-BsQtwznI.js +1 -0
  17. package/dist/assets/classDiagram-v2-VYDZK3BY-BsQtwznI.js +1 -0
  18. package/dist/assets/{cose-bilkent-JH36ORCC-0xUSfjfV.js → cose-bilkent-JH36ORCC-aGjlSdMe.js} +1 -1
  19. package/dist/assets/{cynefin-OW5HDTMX-BE6fNu2_.js → cynefin-OW5HDTMX-D3G4OYOn.js} +1 -1
  20. package/dist/assets/{cynefinDiagram-5FMLGOSQ-rFMnZ9b3.js → cynefinDiagram-5FMLGOSQ-9swRDUnu.js} +1 -1
  21. package/dist/assets/{dagre-GXQ25YYZ-C1p4ffd7.js → dagre-GXQ25YYZ-lvaAGdqY.js} +1 -1
  22. package/dist/assets/{diagram-S7CK7UJ4-BV_3Xj4O.js → diagram-S7CK7UJ4-BaZ6YIkR.js} +1 -1
  23. package/dist/assets/{diagram-UQ7AKVKN-Bb_Evkrm.js → diagram-UQ7AKVKN-COJ2Gb38.js} +1 -1
  24. package/dist/assets/{diagram-VSXAHHWV-BzgupjxD.js → diagram-VSXAHHWV-CYZEkbzP.js} +1 -1
  25. package/dist/assets/{diagram-VX7I27RA-D1c67z76.js → diagram-VX7I27RA-fFeQJ4ae.js} +1 -1
  26. package/dist/assets/{diagram-Z3DM3KII-DsJAJGKE.js → diagram-Z3DM3KII-B7knszDV.js} +1 -1
  27. package/dist/assets/{ebnfDiagram-PWID7BFC-B1ge_obq.js → ebnfDiagram-PWID7BFC-Dk0l329Y.js} +1 -1
  28. package/dist/assets/{erDiagram-RLTQ6QDP-DrV-tggw.js → erDiagram-RLTQ6QDP-CtpYxui8.js} +1 -1
  29. package/dist/assets/{flowDiagram-HODETNUW-CVzDiSQ3.js → flowDiagram-HODETNUW-aVWueRJD.js} +1 -1
  30. package/dist/assets/{ganttDiagram-EL5Y4UJY-CGRdSN9D.js → ganttDiagram-EL5Y4UJY-DfrX-B7p.js} +1 -1
  31. package/dist/assets/{gitGraphDiagram-WWUBYQGX-CAfvFXzL.js → gitGraphDiagram-WWUBYQGX-BFB1ZPF3.js} +1 -1
  32. package/dist/assets/{index-DaxH81ZJ.js → index-DqRygn9E.js} +170 -169
  33. package/dist/assets/index-Ds4HaAjz.css +1 -0
  34. package/dist/assets/{infoDiagram-27XIBGKW-DTshEkGK.js → infoDiagram-27XIBGKW-CuYkzm43.js} +1 -1
  35. package/dist/assets/{ishikawaDiagram-5VMMS53U-DkbshVxp.js → ishikawaDiagram-5VMMS53U-EMiw8Akh.js} +1 -1
  36. package/dist/assets/{journeyDiagram-3NMN7TZE-v5qE8xpn.js → journeyDiagram-3NMN7TZE-DCoLV1f8.js} +1 -1
  37. package/dist/assets/{kanban-definition-UXKFOSKX-a9CNMFLt.js → kanban-definition-UXKFOSKX-CyA4Yinu.js} +1 -1
  38. package/dist/assets/{layout-DrW4R1TH.js → layout-BlaB0grA.js} +1 -1
  39. package/dist/assets/{linear-Cs3qpXT_.js → linear-DLX3dJDH.js} +1 -1
  40. package/dist/assets/{mermaid.core-C7Ti-Fty.js → mermaid.core-Cy51CT89.js} +6 -6
  41. package/dist/assets/{mindmap-definition-YA3MSWOX-B0VDdIcG.js → mindmap-definition-YA3MSWOX-OBXjfL7I.js} +1 -1
  42. package/dist/assets/{pegDiagram-XKGWAZYB-CV1L7MjP.js → pegDiagram-XKGWAZYB-C_BJjUh1.js} +1 -1
  43. package/dist/assets/{pieDiagram-E7YTZNPT-DSCuzVTV.js → pieDiagram-E7YTZNPT-jIpbr3Fi.js} +1 -1
  44. package/dist/assets/{quadrantDiagram-AXDQQJYC-hzX-9AKo.js → quadrantDiagram-AXDQQJYC-C1A15xI5.js} +1 -1
  45. package/dist/assets/{railroadDiagram-O6MQD6OU-BbmzIqcp.js → railroadDiagram-O6MQD6OU-Rslzn1pI.js} +1 -1
  46. package/dist/assets/{requirementDiagram-BXWQKSXE-CQCRRBSL.js → requirementDiagram-BXWQKSXE-LlfURO5-.js} +1 -1
  47. package/dist/assets/{sankeyDiagram-P5KCCOFB-kiaLcW6X.js → sankeyDiagram-P5KCCOFB-B5BPF4-O.js} +1 -1
  48. package/dist/assets/{sequenceDiagram-WJ2MYXX4-Bgx8ST7Q.js → sequenceDiagram-WJ2MYXX4-orYZe9zX.js} +1 -1
  49. package/dist/assets/{sizeCapture-INFHLROL-BTjJ-ygN.js → sizeCapture-INFHLROL-Co-K5Cfb.js} +1 -1
  50. package/dist/assets/{stateDiagram-D77RDMKH-D48RR1FL.js → stateDiagram-D77RDMKH-COEx1aH2.js} +1 -1
  51. package/dist/assets/{stateDiagram-v2-MP3YSRHH-B-XwSR-z.js → stateDiagram-v2-MP3YSRHH-DaeTZvmy.js} +1 -1
  52. package/dist/assets/{swimlanes-42K2YHIH-BhE-QuEZ.js → swimlanes-42K2YHIH-BHQaDhfZ.js} +1 -1
  53. package/dist/assets/swimlanesDiagram-VR7AAH4N-BHW8q5M5.js +8 -0
  54. package/dist/assets/{timeline-definition-24CTP7MA-Cm7EUWWt.js → timeline-definition-24CTP7MA-COqCRwGX.js} +1 -1
  55. package/dist/assets/{vennDiagram-4TSXK5OY-X-nC9wZ0.js → vennDiagram-4TSXK5OY-nym5XSnr.js} +1 -1
  56. package/dist/assets/{wardleyDiagram-VM6X3IG4-D33YvEQZ.js → wardleyDiagram-VM6X3IG4-DEPPey_W.js} +1 -1
  57. package/dist/assets/{xychartDiagram-S5SC5T6Z-lziwBKsM.js → xychartDiagram-S5SC5T6Z-uSJ404kL.js} +1 -1
  58. package/dist/index.html +2 -2
  59. package/dist/sw.js +1 -1
  60. package/dist-server/server/index.js +3 -1
  61. package/dist-server/server/index.js.map +1 -1
  62. package/dist-server/server/piecemaker/index.js +7 -3
  63. package/dist-server/server/piecemaker/index.js.map +1 -1
  64. package/dist-server/server/piecemaker/knowledge/index.js +13 -6
  65. package/dist-server/server/piecemaker/knowledge/index.js.map +1 -1
  66. package/dist-server/server/piecemaker/knowledge/local-routes.js +55 -0
  67. package/dist-server/server/piecemaker/knowledge/local-routes.js.map +1 -0
  68. package/dist-server/server/piecemaker/knowledge/scan-jobs.js +3 -1
  69. package/dist-server/server/piecemaker/knowledge/scan-jobs.js.map +1 -1
  70. package/dist-server/server/piecemaker/library/index.js +14 -41
  71. package/dist-server/server/piecemaker/library/index.js.map +1 -1
  72. package/dist-server/server/piecemaker/library/store.js +11 -3
  73. package/dist-server/server/piecemaker/library/store.js.map +1 -1
  74. package/dist-server/server/piecemaker/library/workspace-installation.js +26 -3
  75. package/dist-server/server/piecemaker/library/workspace-installation.js.map +1 -1
  76. package/dist-server/server/piecemaker/timesheet/service.js +8 -7
  77. package/dist-server/server/piecemaker/timesheet/service.js.map +1 -1
  78. package/dist-server/server/piecemaker/timesheet/store.js +5 -3
  79. package/dist-server/server/piecemaker/timesheet/store.js.map +1 -1
  80. package/package.json +1 -1
  81. package/product.config.json +2 -0
  82. package/scripts/piecemaker/build-app-icon.py +88 -0
  83. package/scripts/piecemaker/cli/lib/piecemaker-anonymizer.mjs +2 -2
  84. package/scripts/piecemaker/hooks/proxy-guard.mjs +19 -54
  85. package/scripts/release/assert-piecemaker-version.mjs +25 -0
  86. package/server/index.ts +4 -1
  87. package/server/piecemaker/anonymizer/client-config.cjs +45 -162
  88. package/server/piecemaker/anonymizer/hudsucker-fixture.cjs +127 -0
  89. package/server/piecemaker/anonymizer/hudsucker-proxy/Cargo.lock +2396 -0
  90. package/server/piecemaker/anonymizer/hudsucker-proxy/Cargo.toml +14 -0
  91. package/server/piecemaker/anonymizer/hudsucker-proxy/src/main.rs +501 -0
  92. package/server/piecemaker/anonymizer/providers.cjs +14 -135
  93. package/server/piecemaker/anonymizer/rewriter-bridge.cjs +221 -0
  94. package/server/piecemaker/anonymizer/service.cjs +144 -28
  95. package/server/piecemaker/index.ts +8 -3
  96. package/server/piecemaker/knowledge/index.ts +14 -6
  97. package/server/piecemaker/knowledge/local-routes.ts +72 -0
  98. package/server/piecemaker/knowledge/scan-jobs.ts +4 -1
  99. package/server/piecemaker/library/index.ts +14 -34
  100. package/server/piecemaker/library/store.ts +11 -3
  101. package/server/piecemaker/library/workspace-installation.ts +20 -3
  102. package/server/piecemaker/timesheet/service.ts +9 -7
  103. package/server/piecemaker/timesheet/store.ts +5 -3
  104. package/server/piecemaker/vendor/installer/assets/claude-hooks/piecemaker-guard-secrets.mjs +0 -1
  105. package/server/piecemaker/vendor/installer/assets/piecemaker.icns +0 -0
  106. package/server/piecemaker/vendor/installer/assets/piecemaker.ico +0 -0
  107. package/server/piecemaker/vendor/installer/bin/piecemaker.mjs +56 -206
  108. package/server/piecemaker/vendor/installer/lib/commandes.mjs +2 -4
  109. package/server/piecemaker/vendor/installer/lib/conversion-client.mjs +74 -0
  110. package/server/piecemaker/vendor/installer/lib/service.mjs +4 -358
  111. package/server/piecemaker/vendor/installer/lib/state.mjs +0 -6
  112. package/server/piecemaker/vendor/installer/steps/03-python-gliner.mjs +4 -4
  113. package/server/piecemaker/vendor/installer/steps/09-claude-assets.mjs +0 -31
  114. package/server/piecemaker/vendor/piecemaker-plugin/scripts/statusline.mjs +3 -4
  115. package/server/piecemaker/vendor/websocket-server/admin-routes.cjs +1 -49
  116. package/server/piecemaker/vendor/websocket-server/claude-hooks.cjs +14 -12
  117. package/server/piecemaker/vendor/websocket-server/originals-pipeline.cjs +17 -476
  118. package/server/piecemaker/vendor/websocket-server/scripts/convert_and_scan_pipeline.py +2 -2
  119. package/server/piecemaker/vendor/websocket-server/scripts/mineru_improved_1.py +11 -2
  120. package/server/piecemaker/vendor/websocket-server/scripts/presidio-gliner/scanner_worker.py +13 -37
  121. package/server/piecemaker/vendor/websocket-server/scripts/requirements.txt +1 -7
  122. package/server/piecemaker/vendor/websocket-server/scripts/warmup.py +14 -85
  123. package/dist/assets/channel-DdzrPZ6Y.js +0 -1
  124. package/dist/assets/classDiagram-ZZMXUADV-Dim2o8E5.js +0 -1
  125. package/dist/assets/classDiagram-v2-VYDZK3BY-Dim2o8E5.js +0 -1
  126. package/dist/assets/index-D_Dc_nQv.css +0 -1
  127. package/dist/assets/swimlanesDiagram-VR7AAH4N-DR525d5V.js +0 -8
  128. package/server/piecemaker/anonymizer/proxy.cjs +0 -365
  129. package/server/piecemaker/vendor/installer/assets/PieceMakerApp.swift +0 -189
  130. package/server/piecemaker/vendor/installer/lib/desktop-launcher.mjs +0 -305
  131. package/server/piecemaker/vendor/installer/steps/05-certificats.mjs +0 -171
  132. package/server/piecemaker/vendor/installer/steps/14-mxc-sandbox.mjs +0 -271
  133. package/server/piecemaker/vendor/installer/steps/15-pwa-desktop.mjs +0 -64
  134. package/server/piecemaker/vendor/installer/templates/root-CLAUDE.md +0 -56
  135. package/server/piecemaker/vendor/installer/templates/workspace-CLAUDE.md +0 -52
@@ -67,7 +67,7 @@ def print_progress(phase: str, current: int, total: int) -> None:
67
67
  def start_scanner_worker() -> Optional[subprocess.Popen]:
68
68
  """Start the long-lived scanner worker subprocess.
69
69
 
70
- The worker loads GLiNER2 + spaCy models once and stays alive to process
70
+ The worker loads the GLiNER2 model once and stays alive to process
71
71
  multiple files via a JSON-line stdin/stdout protocol. Launch this at the
72
72
  start of the pipeline so model loading overlaps with Phase 1 (conversion).
73
73
 
@@ -1845,7 +1845,7 @@ def run_pipeline(resources: PipelineResources):
1845
1845
  print()
1846
1846
 
1847
1847
  # What is left to do, decided before anything runs: the scanner worker loads
1848
- # ~1.1GB of GLiNER2.5 + spaCy weights, so it must only start when at least one
1848
+ # ~1.1GB of GLiNER2.5 weights, so it must only start when at least one
1849
1849
  # file actually needs a PII scan.
1850
1850
  def markdown_path(input_file: str) -> Path:
1851
1851
  return Path(args.output) / f"{Path(input_file).stem}.md"
@@ -6,10 +6,19 @@ Supports both pipeline (direct PDF) and VLM/hybrid (image-based) modes
6
6
 
7
7
  import argparse
8
8
  import json
9
+ import os
9
10
  import subprocess
10
11
  import sys
11
12
  from pathlib import Path
12
13
 
14
+
15
+ def mineru_executable():
16
+ name = 'mineru.exe' if os.name == 'nt' else 'mineru'
17
+ sibling = Path(sys.executable).resolve().parent / name
18
+ if sibling.is_file():
19
+ return str(sibling)
20
+ return 'mineru'
21
+
13
22
  def parse_with_pipeline(pdf_path, output_dir, lang=None):
14
23
  """
15
24
  Parse PDF using pipeline backend (direct PDF processing, no image conversion needed)
@@ -29,7 +38,7 @@ def parse_with_pipeline(pdf_path, output_dir, lang=None):
29
38
 
30
39
  # Build mineru command
31
40
  cmd = [
32
- 'mineru',
41
+ mineru_executable(),
33
42
  '-p', str(pdf_path),
34
43
  '-o', str(output_dir),
35
44
  '-b', 'pipeline'
@@ -72,7 +81,7 @@ def parse_with_vlm(pdf_path, output_dir, backend='hybrid-auto-engine'):
72
81
 
73
82
  # Build mineru command
74
83
  cmd = [
75
- 'mineru',
84
+ mineru_executable(),
76
85
  '-p', str(pdf_path),
77
86
  '-o', str(output_dir),
78
87
  '-b', backend
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Long-lived scanner worker — loads GLiNER2.5 + spaCy once, processes multiple files
3
+ Long-lived scanner worker — loads GLiNER2.5 once, processes multiple files
4
4
  via a JSON-line stdin/stdout protocol.
5
5
 
6
6
  Protocol:
@@ -29,13 +29,14 @@ from typing import Dict, List, Optional
29
29
  # ---------------------------------------------------------------------------
30
30
  # Heavy imports — these are the expensive ones (~30-60s)
31
31
  # ---------------------------------------------------------------------------
32
+ import spacy
32
33
  from presidio_analyzer import (
33
34
  AnalysisExplanation,
34
35
  AnalyzerEngine,
35
36
  LocalRecognizer,
36
37
  RecognizerResult,
37
38
  )
38
- from presidio_analyzer.nlp_engine import NlpArtifacts, NlpEngineProvider
39
+ from presidio_analyzer.nlp_engine import SpacyNlpEngine
39
40
 
40
41
  try:
41
42
  from gliner2 import AutoExtractor
@@ -430,23 +431,14 @@ _analyzer_cache: Dict[str, AnalyzerEngine] = {}
430
431
  _gliner_model = None # Shared GLiNER2 model instance
431
432
 
432
433
 
433
- def _disable_unused_spacy_components(nlp_engine, language: str) -> None:
434
- """Turn off every spaCy pipe whose output nothing reads.
434
+ def _build_tokenizer_only_engine(language: str) -> SpacyNlpEngine:
435
+ """Build a presidio NLP engine that only tokenises, with no trained model."""
436
+ nlp = spacy.blank(language)
437
+ nlp.max_length = 5_000_000
435
438
 
436
- Entities come from GLiNER2; spaCy is kept only because presidio needs a tokenizer
437
- and NlpArtifacts. Failing to disable a pipe is not fatal, so this never raises.
438
- """
439
- nlp = nlp_engine.nlp.get(language)
440
- if nlp is None:
441
- return
442
-
443
- for pipe_name in list(nlp.pipe_names):
444
- try:
445
- nlp.disable_pipe(pipe_name)
446
- except Exception as exc: # noqa: BLE001
447
- _log(f"Could not disable spaCy pipe '{pipe_name}': {exc}")
448
-
449
- _log(f"spaCy [{language}] active pipes: {nlp.pipe_names or 'tokenizer only'}")
439
+ engine = SpacyNlpEngine()
440
+ engine.nlp = {language: nlp}
441
+ return engine
450
442
 
451
443
 
452
444
  def _get_or_build_analyzer(language: str) -> AnalyzerEngine:
@@ -459,25 +451,9 @@ def _get_or_build_analyzer(language: str) -> AnalyzerEngine:
459
451
  if language in _analyzer_cache:
460
452
  return _analyzer_cache[language]
461
453
 
462
- lang_models = {"fr": "fr_core_news_sm", "en": "en_core_web_sm"}
463
- model_name = lang_models.get(language, "en_core_web_sm")
464
-
465
- _log(f"Building analyzer for language: {language} (spaCy model: {model_name})")
466
-
467
- nlp_provider = NlpEngineProvider(nlp_configuration={
468
- "nlp_engine_name": "spacy",
469
- "models": [{"lang_code": language, "model_name": model_name}],
470
- })
471
- nlp_engine = nlp_provider.create_engine()
472
- nlp_engine.nlp[language].max_length = 5_000_000
473
-
474
- # presidio's SpacyNlpEngine calls spacy.load() with no `disable=`, so the whole
475
- # pipeline — tagger, morphologizer, parser, attribute_ruler, lemmatizer, ner —
476
- # runs over the document. SpacyRecognizer is then removed below, so the NER output
477
- # is thrown away and only tokenisation is used. Measured on 300k characters:
478
- # 20.6 s with the full pipeline, 0.9 s with tokenisation alone, and ~1 GB less
479
- # resident memory (which matters on an 8 GB machine).
480
- _disable_unused_spacy_components(nlp_engine, language)
454
+ _log(f"Building analyzer for language: {language}")
455
+
456
+ nlp_engine = _build_tokenizer_only_engine(language)
481
457
 
482
458
  analyzer = AnalyzerEngine(nlp_engine=nlp_engine, supported_languages=[language])
483
459
 
@@ -15,10 +15,4 @@ huggingface-hub>=0.20.0 # Required for model downloading with progress
15
15
 
16
16
  # Presidio + GLiNER integration
17
17
  presidio-analyzer>=2.2.0
18
- spacy>=3.7.0
19
- #
20
- # After installing spacy, download language models:
21
- # python -m spacy download fr_core_news_sm # French (15MB, 88% NER accuracy)
22
- # python -m spacy download en_core_web_sm # English (13MB, 85% NER accuracy)
23
- #
24
- # Or use: python warmup.py # Downloads all models automatically
18
+ spacy>=3.7.0 # Tokenizer only, via spacy.blank() — no language model needed
@@ -42,20 +42,6 @@ MODELS_CONFIG = {
42
42
  "optional": False,
43
43
  "type": "huggingface",
44
44
  },
45
- "spacy_fr": {
46
- "model_id": "fr_core_news_sm",
47
- "description": "French NLP model for spaCy",
48
- "size_mb": "~45MB",
49
- "optional": False,
50
- "type": "spacy",
51
- },
52
- "spacy_en": {
53
- "model_id": "en_core_web_sm",
54
- "description": "English NLP model for spaCy",
55
- "size_mb": "~40MB",
56
- "optional": False,
57
- "type": "spacy",
58
- },
59
45
  }
60
46
 
61
47
 
@@ -103,20 +89,6 @@ def gliner_migration_status() -> Dict:
103
89
  }
104
90
 
105
91
 
106
- def is_spacy_cached(model_id: str) -> bool:
107
- """Check if spaCy model is installed"""
108
- try:
109
- import spacy
110
-
111
- try:
112
- spacy.load(model_id)
113
- return True
114
- except OSError:
115
- return False
116
- except ImportError:
117
- return False
118
-
119
-
120
92
  def check_model_cached(model_key: str) -> bool:
121
93
  """Check if a specific model is cached"""
122
94
  config = MODELS_CONFIG.get(model_key)
@@ -125,8 +97,6 @@ def check_model_cached(model_key: str) -> bool:
125
97
 
126
98
  if config["type"] == "huggingface":
127
99
  return is_gliner2_cached(config["model_id"])
128
- elif config["type"] == "spacy":
129
- return is_spacy_cached(config["model_id"])
130
100
  return False
131
101
 
132
102
 
@@ -163,52 +133,6 @@ def download_gliner2_model(model_id: str, description: str, force: bool = False)
163
133
  return False
164
134
 
165
135
 
166
- def download_spacy_model(model_id: str, description: str) -> bool:
167
- """Download spaCy model via CLI"""
168
- try:
169
- # Check if spacy is installed
170
- try:
171
- import spacy
172
- except ImportError:
173
- log_json(
174
- f"spaCy not installed, skipping {model_id}",
175
- level="warning",
176
- model=model_id,
177
- )
178
- log_plain(f"⏭️ spaCy not installed, skipping {model_id}")
179
- return False
180
-
181
- log_json(f"Downloading spaCy model: {model_id}", model=model_id, phase="start")
182
- log_plain(f"📥 Downloading spaCy model: {model_id}...")
183
-
184
- # Download using subprocess
185
- result = subprocess.run(
186
- [sys.executable, "-m", "spacy", "download", model_id],
187
- capture_output=True,
188
- text=True,
189
- check=True,
190
- )
191
-
192
- log_json(
193
- f"Downloaded spaCy model: {model_id}", model=model_id, phase="complete"
194
- )
195
- log_plain(f"✅ Downloaded spaCy model: {model_id}")
196
- return True
197
-
198
- except subprocess.CalledProcessError as e:
199
- log_json(
200
- f"Failed to download spaCy model {model_id}: {e}",
201
- level="warning",
202
- model=model_id,
203
- )
204
- log_plain(f"⚠️ spaCy model download failed: {model_id}")
205
- return False
206
- except Exception as e:
207
- log_json(f"Error downloading {model_id}: {e}", level="error", model=model_id)
208
- log_plain(f"❌ Error: {model_id} - {e}")
209
- return False
210
-
211
-
212
136
  def download_model(model_key: str, force: bool = False) -> bool:
213
137
  """Download a specific model by key"""
214
138
  config = MODELS_CONFIG.get(model_key)
@@ -229,8 +153,6 @@ def download_model(model_key: str, force: bool = False) -> bool:
229
153
  # Download based on type
230
154
  if config["type"] == "huggingface":
231
155
  return download_gliner2_model(config["model_id"], config["description"], force=force)
232
- elif config["type"] == "spacy":
233
- return download_spacy_model(config["model_id"], config["description"])
234
156
 
235
157
  return False
236
158
 
@@ -241,19 +163,22 @@ def download_model(model_key: str, force: bool = False) -> bool:
241
163
 
242
164
 
243
165
  def check_mineru() -> bool:
244
- """Verify mineru CLI is available"""
166
+ """Verify the mineru package is importable and runnable"""
245
167
  try:
246
168
  result = subprocess.run(
247
- ["mineru", "--version"], capture_output=True, text=True, check=True
169
+ [sys.executable, "-m", "mineru.cli.client", "--version"],
170
+ capture_output=True,
171
+ text=True,
172
+ check=True,
248
173
  )
249
- log_json("MinerU CLI available", tool="mineru", available=True)
250
- log_plain("✅ MinerU CLI available")
174
+ log_json("MinerU available", tool="mineru", available=True)
175
+ log_plain("✅ MinerU available")
251
176
  return True
252
177
  except (subprocess.CalledProcessError, FileNotFoundError):
253
178
  log_json(
254
- "MinerU CLI not found", tool="mineru", available=False, level="warning"
179
+ "MinerU not installed", tool="mineru", available=False, level="warning"
255
180
  )
256
- log_plain("⚠️ MinerU CLI not found (pip install mineru)")
181
+ log_plain("⚠️ MinerU not installed (pip install 'mineru[pipeline,vlm]==2.7.6')")
257
182
  return False
258
183
 
259
184
 
@@ -392,7 +317,11 @@ def get_status() -> Dict:
392
317
 
393
318
  # Check mineru
394
319
  try:
395
- subprocess.run(["mineru", "--version"], capture_output=True, check=True)
320
+ subprocess.run(
321
+ [sys.executable, "-m", "mineru.cli.client", "--version"],
322
+ capture_output=True,
323
+ check=True,
324
+ )
396
325
  status["tools"]["mineru"] = True
397
326
  except:
398
327
  status["tools"]["mineru"] = False
@@ -1 +0,0 @@
1
- import{ah as o,ai as n}from"./mermaid.core-C7Ti-Fty.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-TICWLB2K-DhOULVhX.js";import{_ as i}from"./mermaid.core-C7Ti-Fty.js";import"./chunk-5VM5RSS4-BerUZBa1.js";import"./chunk-XXDRQBXY-CkpCgrVg.js";import"./chunk-POPQ4Y6H-D4aTDC2T.js";import"./chunk-F27PBJKO-5W7ax2gB.js";import"./index-DaxH81ZJ.js";import"./vendor-codemirror-CjW0lHR5.js";import"./vendor-react-D809iwXR.js";import"./vendor-xterm-BWUgpGtR.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-TICWLB2K-DhOULVhX.js";import{_ as i}from"./mermaid.core-C7Ti-Fty.js";import"./chunk-5VM5RSS4-BerUZBa1.js";import"./chunk-XXDRQBXY-CkpCgrVg.js";import"./chunk-POPQ4Y6H-D4aTDC2T.js";import"./chunk-F27PBJKO-5W7ax2gB.js";import"./index-DaxH81ZJ.js";import"./vendor-codemirror-CjW0lHR5.js";import"./vendor-react-D809iwXR.js";import"./vendor-xterm-BWUgpGtR.js";var c={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{c as diagram};