cli-dolibarr 3.32.2__tar.gz → 3.32.3__tar.gz

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 (179) hide show
  1. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/PKG-INFO +1 -1
  2. cli_dolibarr-3.32.3/cli_dolibarr/dolibarr/__init__.py +1 -0
  3. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/tiering.py +4 -1
  4. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_tiering.py +15 -0
  5. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr.egg-info/PKG-INFO +1 -1
  6. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr.egg-info/SOURCES.txt +0 -2
  7. cli_dolibarr-3.32.2/cli_dolibarr/dolibarr/__init__.py +0 -1
  8. cli_dolibarr-3.32.2/cli_dolibarr/dolibarr/tests/test_mcp_harvest_args.py +0 -84
  9. cli_dolibarr-3.32.2/cli_dolibarr/dolibarr/tests/test_mcp_usage_db.py +0 -76
  10. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/LICENSE +0 -0
  11. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/README.md +0 -0
  12. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/README.md +0 -0
  13. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/__init__.py +0 -0
  14. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/_template.py +0 -0
  15. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/accountancy.py +0 -0
  16. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/agendaevents.py +0 -0
  17. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/apibridge.py +0 -0
  18. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/bankaccounts.py +0 -0
  19. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/boms.py +0 -0
  20. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/categories.py +0 -0
  21. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/config.py +0 -0
  22. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/contacts.py +0 -0
  23. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/contracts.py +0 -0
  24. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/countries.py +0 -0
  25. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/delivery.py +0 -0
  26. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/documents.py +0 -0
  27. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/donations.py +0 -0
  28. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/expensereports.py +0 -0
  29. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/interventions.py +0 -0
  30. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/invoices.py +0 -0
  31. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/knowledge.py +0 -0
  32. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/login.py +0 -0
  33. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/member_types.py +0 -0
  34. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/members.py +0 -0
  35. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/mobilehub.py +0 -0
  36. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/mobilehubapi.py +0 -0
  37. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/mos.py +0 -0
  38. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/mprplus.py +0 -0
  39. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/multicurrencies.py +0 -0
  40. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/orderprocessor.py +0 -0
  41. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/orders.py +0 -0
  42. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/partnerships.py +0 -0
  43. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/pdfa.py +0 -0
  44. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/productplus.py +0 -0
  45. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/products.py +0 -0
  46. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/projects.py +0 -0
  47. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/proposals.py +0 -0
  48. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/quickprint.py +0 -0
  49. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/receptions.py +0 -0
  50. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/recruitments.py +0 -0
  51. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/salaries.py +0 -0
  52. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/schema.py +0 -0
  53. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/setup.py +0 -0
  54. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/shipments.py +0 -0
  55. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/status.py +0 -0
  56. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/stock.py +0 -0
  57. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/stockmodule.py +0 -0
  58. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/stockmovements.py +0 -0
  59. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/subscriptions.py +0 -0
  60. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/supplier_invoices.py +0 -0
  61. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/supplier_orders.py +0 -0
  62. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/supplier_proposals.py +0 -0
  63. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/supplierinvoices.py +0 -0
  64. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/supplierorders.py +0 -0
  65. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/supplierproposals.py +0 -0
  66. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/system.py +0 -0
  67. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/systemapi.py +0 -0
  68. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/tasks.py +0 -0
  69. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/thirdparties.py +0 -0
  70. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/tickets.py +0 -0
  71. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/tools.py +0 -0
  72. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/users.py +0 -0
  73. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/warehouses.py +0 -0
  74. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/webhook.py +0 -0
  75. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/workstations.py +0 -0
  76. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/commands/zapier.py +0 -0
  77. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/__init__.py +0 -0
  78. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/client.py +0 -0
  79. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/config.py +0 -0
  80. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/output.py +0 -0
  81. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/schema_agents.py +0 -0
  82. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/schema_audit.py +0 -0
  83. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/schema_generator.py +0 -0
  84. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/schema_manager.py +0 -0
  85. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/core/session_client.py +0 -0
  86. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/dolibarr_cli.py +0 -0
  87. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/extrafields_cache.json +0 -0
  88. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/hermes_plugin/__init__.py +0 -0
  89. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/hermes_plugin/install.sh +0 -0
  90. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/hermes_plugin/plugin.yaml +0 -0
  91. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/__init__.py +0 -0
  92. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/__main__.py +0 -0
  93. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/domains.py +0 -0
  94. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/error_guidance.py +0 -0
  95. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/field_hints.py +0 -0
  96. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/param_aliases.py +0 -0
  97. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/projections.py +0 -0
  98. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/registry.py +0 -0
  99. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/sanitizer.py +0 -0
  100. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/search_actions.py +0 -0
  101. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/server.py +0 -0
  102. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/mcp_server/validators.py +0 -0
  103. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/models_supplement.json +0 -0
  104. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/schema.json +0 -0
  105. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/__init__.py +0 -0
  106. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_audit.py +0 -0
  107. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_boms.py +0 -0
  108. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_cli.py +0 -0
  109. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_contracts.py +0 -0
  110. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_core.py +0 -0
  111. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_dispatch.py +0 -0
  112. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_documents.py +0 -0
  113. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_enrich.py +0 -0
  114. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_executor_error_handling.py +0 -0
  115. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_executor_request_body_unwrap.py +0 -0
  116. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_full_e2e.py +0 -0
  117. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_g4_body_models_probe.py +0 -0
  118. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_hermes_register.py +0 -0
  119. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_invoices.py +0 -0
  120. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_auth.py +0 -0
  121. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_error_guidance.py +0 -0
  122. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_field_hints.py +0 -0
  123. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_leak_audit.py +0 -0
  124. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_list_document_id_ref_guidance.py +0 -0
  125. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_makeorder_date_backfill.py +0 -0
  126. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_makeorder_nested_data_unwrap.py +0 -0
  127. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_param_aliases.py +0 -0
  128. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_registry.py +0 -0
  129. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_sanitizer.py +0 -0
  130. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_search_actions.py +0 -0
  131. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_server.py +0 -0
  132. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mcp_transport.py +0 -0
  133. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mobilehubapi_aidoc.py +0 -0
  134. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mobilehubapi_stockin_queued.py +0 -0
  135. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mos.py +0 -0
  136. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mprplus_endpoints.py +0 -0
  137. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_mprplus_mo_deliver.py +0 -0
  138. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_endpoints.py +0 -0
  139. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_ocr_jobs.py +0 -0
  140. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_product_stats.py +0 -0
  141. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_recon_monthly_period.py +0 -0
  142. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_reconciliation_fixes.py +0 -0
  143. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_smartupload.py +0 -0
  144. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orderprocessor_statement_email.py +0 -0
  145. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_orders.py +0 -0
  146. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_pdfa.py +0 -0
  147. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_productplus.py +0 -0
  148. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_products_purchase_prices_multicurrency.py +0 -0
  149. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_proposals.py +0 -0
  150. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_receptions.py +0 -0
  151. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_schema_generator.py +0 -0
  152. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_setup.py +0 -0
  153. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_setup_dictionary_availability.py +0 -0
  154. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_setup_dictionary_incoterms.py +0 -0
  155. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_supplier_invoices.py +0 -0
  156. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_supplier_orders.py +0 -0
  157. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_supplier_proposals.py +0 -0
  158. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_supplierinvoices.py +0 -0
  159. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_supplierorders.py +0 -0
  160. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_systemapi.py +0 -0
  161. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_thirdparty_fk_warehouse_split.py +0 -0
  162. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_tool_config.py +0 -0
  163. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_tool_filter.py +0 -0
  164. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tests/test_tools.py +0 -0
  165. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/__init__.py +0 -0
  166. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/executor.py +0 -0
  167. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/tool_config.py +0 -0
  168. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/tool_translations.json +0 -0
  169. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/tool_ui.html +0 -0
  170. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/tool_ui.py +0 -0
  171. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/tools/tools_schema.py +0 -0
  172. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/utils/__init__.py +0 -0
  173. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr/dolibarr/utils/multicurrency.py +0 -0
  174. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr.egg-info/dependency_links.txt +0 -0
  175. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr.egg-info/entry_points.txt +0 -0
  176. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr.egg-info/requires.txt +0 -0
  177. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/cli_dolibarr.egg-info/top_level.txt +0 -0
  178. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/pyproject.toml +0 -0
  179. {cli_dolibarr-3.32.2 → cli_dolibarr-3.32.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-dolibarr
3
- Version: 3.32.2
3
+ Version: 3.32.3
4
4
  Summary: CLI tool for Dolibarr ERP/CRM REST API management
5
5
  Author: CLI Anything
6
6
  License-Expression: MIT
@@ -0,0 +1 @@
1
+ __version__ = "3.32.3"
@@ -98,7 +98,10 @@ def load_index(path: Optional[Path] = None):
98
98
 
99
99
 
100
100
  def load_usage_counts(path: Optional[Path] = None) -> Dict[str, int]:
101
- """渲染/搜索用的 {动作: 调用数};种子/真源计数由 harvest 写入此处。"""
101
+ """渲染/搜索用的 {域|动作: 调用数};真源=本机 Hermes 会话统计(refresh_tiers.py 远端写入)。
102
+
103
+ 键必须带域:动作名跨 17 域不唯一(实测 11 组同名),只按动作名查会互相覆盖。
104
+ """
102
105
  p = INDEX_PATH if path is None else path
103
106
  try:
104
107
  raw = json.loads(p.read_text(encoding="utf-8"))
@@ -119,3 +119,18 @@ class RegistryTierRenderTest(unittest.TestCase):
119
119
 
120
120
  if __name__ == "__main__":
121
121
  unittest.main()
122
+
123
+
124
+ class UsageCountTest(unittest.TestCase):
125
+ """同名动作跨域不能互相覆盖(2026-09-18 实测事故回归守卫)。"""
126
+
127
+ def test_prefers_per_domain_key(self):
128
+ usage = {"erp_partners|list_thirdparty": 101, "erp_thirdparty|list_thirdparty": 1}
129
+ self.assertEqual(tiering.usage_count(usage, "erp_partners", "list_thirdparty"), 101)
130
+
131
+ def test_falls_back_to_bare_action_key(self):
132
+ self.assertEqual(
133
+ tiering.usage_count({"list_product": 5}, "erp_products", "list_product"), 5)
134
+
135
+ def test_missing_returns_zero(self):
136
+ self.assertEqual(tiering.usage_count({}, "erp_products", "list_product"), 0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-dolibarr
3
- Version: 3.32.2
3
+ Version: 3.32.3
4
4
  Summary: CLI tool for Dolibarr ERP/CRM REST API management
5
5
  Author: CLI Anything
6
6
  License-Expression: MIT
@@ -120,7 +120,6 @@ cli_dolibarr/dolibarr/tests/test_invoices.py
120
120
  cli_dolibarr/dolibarr/tests/test_mcp_auth.py
121
121
  cli_dolibarr/dolibarr/tests/test_mcp_error_guidance.py
122
122
  cli_dolibarr/dolibarr/tests/test_mcp_field_hints.py
123
- cli_dolibarr/dolibarr/tests/test_mcp_harvest_args.py
124
123
  cli_dolibarr/dolibarr/tests/test_mcp_leak_audit.py
125
124
  cli_dolibarr/dolibarr/tests/test_mcp_list_document_id_ref_guidance.py
126
125
  cli_dolibarr/dolibarr/tests/test_mcp_makeorder_date_backfill.py
@@ -132,7 +131,6 @@ cli_dolibarr/dolibarr/tests/test_mcp_search_actions.py
132
131
  cli_dolibarr/dolibarr/tests/test_mcp_server.py
133
132
  cli_dolibarr/dolibarr/tests/test_mcp_tiering.py
134
133
  cli_dolibarr/dolibarr/tests/test_mcp_transport.py
135
- cli_dolibarr/dolibarr/tests/test_mcp_usage_db.py
136
134
  cli_dolibarr/dolibarr/tests/test_mobilehubapi_aidoc.py
137
135
  cli_dolibarr/dolibarr/tests/test_mobilehubapi_stockin_queued.py
138
136
  cli_dolibarr/dolibarr/tests/test_mos.py
@@ -1 +0,0 @@
1
- __version__ = "3.32.2"
@@ -1,84 +0,0 @@
1
- """S2 harvest.py 单测:args_of 三形状 + SELF_NOISE + 播种幂等(plan S2)。"""
2
- import sqlite3
3
- import sys
4
- import unittest
5
- from pathlib import Path
6
-
7
- REPO_ROOT = str(Path(__file__).resolve().parents[3])
8
- if REPO_ROOT not in sys.path:
9
- sys.path.insert(0, REPO_ROOT)
10
-
11
- import harvest # noqa: E402
12
-
13
-
14
- class ArgsOfTest(unittest.TestCase):
15
- def test_direct_erp_tool(self):
16
- rec = {"type": "tool", "tool": "erp_products",
17
- "state": {"status": "completed",
18
- "input": {"action": "list_product"}}}
19
- self.assertEqual(("erp_products", "list_product"),
20
- harvest.args_of(rec)[:2])
21
-
22
- def test_meta_tool_call_shape(self):
23
- rec = {"type": "tool", "tool": "skill_mcp",
24
- "state": {"status": "completed",
25
- "input": {"mcp_name": "cli-dolibarr",
26
- "tool_name": "erp_system",
27
- "arguments": "{\"action\": \"list_status\"}"}}}
28
- self.assertEqual(("erp_system", "list_status"),
29
- harvest.args_of(rec)[:2])
30
-
31
- def test_openai_function_shape(self):
32
- rec = {"tool_calls": [{"function": {
33
- "name": "erp_invoices",
34
- "arguments": "{\"action\": \"list_invoice\"}"}}]}
35
- self.assertEqual(("erp_invoices", "list_invoice"),
36
- harvest.args_of(rec)[:2])
37
-
38
- def test_self_noise_and_unknown_ignored(self):
39
- self.assertIsNone(harvest.args_of(
40
- {"type": "tool", "tool": "bash",
41
- "state": {"status": "completed", "input": {}}}))
42
- self.assertIsNone(harvest.args_of({"type": "text", "text": "hi"}))
43
- self.assertIsNone(harvest.args_of("not-a-dict"))
44
-
45
- def test_incomplete_call_ignored(self):
46
- rec = {"type": "tool", "tool": "erp_products",
47
- "state": {"status": "running", "input": {}}}
48
- self.assertIsNone(harvest.args_of(rec))
49
-
50
-
51
- class SeedAndAggregateTest(unittest.TestCase):
52
- def setUp(self):
53
- import tempfile
54
- self.tmp = tempfile.TemporaryDirectory()
55
- self.db_path = str(Path(self.tmp.name) / "u.db")
56
-
57
- def tearDown(self):
58
- self.tmp.cleanup()
59
-
60
- def test_aggregate_counts_and_last_ts(self):
61
- rows = [("erp_products", "list_product", 100),
62
- ("erp_products", "list_product", 200),
63
- ("erp_products", "get_product", 150)]
64
- agg = harvest.aggregate(rows)
65
- self.assertEqual(2, agg["list_product"]["calls"])
66
- self.assertEqual(200, agg["list_product"]["last_ts"])
67
- self.assertEqual("erp_products", agg["list_product"]["domain"])
68
-
69
- def test_seed_spec_idempotent(self):
70
- import db
71
- db.init_db(self.db_path)
72
- n1 = harvest.seed_spec(db_path=self.db_path)
73
- n2 = harvest.seed_spec(db_path=self.db_path)
74
- self.assertGreaterEqual(n1, 5)
75
- self.assertEqual(n1, n2)
76
- con = sqlite3.connect(self.db_path)
77
- rows = con.execute(
78
- "SELECT count(*) FROM action_usage WHERE seeded=1").fetchone()[0]
79
- con.close()
80
- self.assertEqual(n1, rows)
81
-
82
-
83
- if __name__ == "__main__":
84
- unittest.main()
@@ -1,76 +0,0 @@
1
- """S1 台账 db.py 单测(plan S1)。运行前提:仓根 db.py 存在。"""
2
- import sqlite3
3
- import sys
4
- import unittest
5
- from pathlib import Path
6
-
7
- REPO_ROOT = str(Path(__file__).resolve().parents[3])
8
- if REPO_ROOT not in sys.path:
9
- sys.path.insert(0, REPO_ROOT)
10
-
11
- import db # noqa: E402
12
-
13
-
14
- class UsageDbTest(unittest.TestCase):
15
- def setUp(self):
16
- import tempfile
17
- self.tmp = tempfile.TemporaryDirectory()
18
- self.db_path = str(Path(self.tmp.name) / "usage.db")
19
-
20
- def tearDown(self):
21
- self.tmp.cleanup()
22
-
23
- def test_init_creates_tables(self):
24
- db.init_db(self.db_path)
25
- con = sqlite3.connect(self.db_path)
26
- names = {r[0] for r in con.execute(
27
- "SELECT name FROM sqlite_master WHERE type='table'")}
28
- con.close()
29
- self.assertIn("action_usage", names)
30
- self.assertIn("nightly_runs", names)
31
-
32
- def test_upsert_idempotent(self):
33
- db.init_db(self.db_path)
34
- row = {"action": "list_product", "domain": "erp_products",
35
- "calls": 2, "last_ts": 1700000000, "window_days": 90}
36
- db.upsert_usage([row], self.db_path)
37
- row2 = dict(row, calls=5)
38
- db.upsert_usage([row2], self.db_path)
39
- con = sqlite3.connect(self.db_path)
40
- n = con.execute("SELECT count(*) FROM action_usage").fetchone()[0]
41
- calls = con.execute(
42
- "SELECT calls FROM action_usage WHERE action='list_product'"
43
- ).fetchone()[0]
44
- con.close()
45
- self.assertEqual(1, n)
46
- self.assertEqual(5, calls)
47
-
48
- def test_get_usage_roundtrip(self):
49
- db.init_db(self.db_path)
50
- rows = [
51
- {"action": "list_product", "domain": "erp_products", "calls": 3,
52
- "last_ts": 1700000000, "window_days": 90},
53
- {"action": "list_warehouse", "domain": "erp_logistics", "calls": 1,
54
- "last_ts": 1700000100, "window_days": 90},
55
- ]
56
- db.upsert_usage(rows, self.db_path)
57
- got = db.get_usage(self.db_path)
58
- self.assertEqual(2, len(got))
59
- self.assertEqual("erp_products", got["list_product"]["domain"])
60
- self.assertEqual(3, got["list_product"]["calls"])
61
- self.assertEqual(1, got["list_warehouse"]["calls"])
62
-
63
- def test_record_run(self):
64
- db.init_db(self.db_path)
65
- db.record_run(stage="toolface_budget", status="ok", note="dry-run",
66
- path=self.db_path)
67
- con = sqlite3.connect(self.db_path)
68
- row = con.execute(
69
- "SELECT stage, status, note FROM nightly_runs "
70
- "ORDER BY id DESC LIMIT 1").fetchone()
71
- con.close()
72
- self.assertEqual(("toolface_budget", "ok", "dry-run"), tuple(row))
73
-
74
-
75
- if __name__ == "__main__":
76
- unittest.main()
File without changes
File without changes
File without changes