cli-dolibarr 3.7.2__tar.gz → 3.7.4__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 (96) hide show
  1. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/PKG-INFO +1 -1
  2. cli_dolibarr-3.7.4/cli_dolibarr/dolibarr/__init__.py +1 -0
  3. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/config.py +148 -49
  4. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr.egg-info/PKG-INFO +1 -1
  5. cli_dolibarr-3.7.2/cli_dolibarr/dolibarr/__init__.py +0 -1
  6. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/LICENSE +0 -0
  7. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/README.md +0 -0
  8. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/README.md +0 -0
  9. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/__init__.py +0 -0
  10. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/_template.py +0 -0
  11. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/accountancy.py +0 -0
  12. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/agendaevents.py +0 -0
  13. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/apibridge.py +0 -0
  14. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/bankaccounts.py +0 -0
  15. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/boms.py +0 -0
  16. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/categories.py +0 -0
  17. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/contacts.py +0 -0
  18. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/contracts.py +0 -0
  19. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/delivery.py +0 -0
  20. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/documents.py +0 -0
  21. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/donations.py +0 -0
  22. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/expensereports.py +0 -0
  23. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/interventions.py +0 -0
  24. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/invoices.py +0 -0
  25. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/knowledge.py +0 -0
  26. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/login.py +0 -0
  27. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/member_types.py +0 -0
  28. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/members.py +0 -0
  29. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/mobilehub.py +0 -0
  30. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/mobilehubapi.py +0 -0
  31. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/mos.py +0 -0
  32. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/multicurrencies.py +0 -0
  33. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/orderprocessor.py +0 -0
  34. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/orders.py +0 -0
  35. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/partnerships.py +0 -0
  36. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/pdfa.py +0 -0
  37. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/productplus.py +0 -0
  38. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/products.py +0 -0
  39. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/projects.py +0 -0
  40. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/proposals.py +0 -0
  41. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/quickprint.py +0 -0
  42. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/receptions.py +0 -0
  43. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/recruitments.py +0 -0
  44. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/salaries.py +0 -0
  45. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/schema.py +0 -0
  46. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/setup.py +0 -0
  47. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/shipments.py +0 -0
  48. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/status.py +0 -0
  49. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/stock.py +0 -0
  50. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/stockmodule.py +0 -0
  51. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/stockmovements.py +0 -0
  52. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/subscriptions.py +0 -0
  53. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/supplier_invoices.py +0 -0
  54. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/supplier_orders.py +0 -0
  55. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/supplier_proposals.py +0 -0
  56. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/supplierinvoices.py +0 -0
  57. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/supplierorders.py +0 -0
  58. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/supplierproposals.py +0 -0
  59. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/system.py +0 -0
  60. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/tasks.py +0 -0
  61. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/thirdparties.py +0 -0
  62. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/tickets.py +0 -0
  63. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/users.py +0 -0
  64. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/warehouses.py +0 -0
  65. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/webhook.py +0 -0
  66. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/workstations.py +0 -0
  67. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/commands/zapier.py +0 -0
  68. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/__init__.py +0 -0
  69. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/client.py +0 -0
  70. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/config.py +0 -0
  71. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/output.py +0 -0
  72. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/schema_agents.py +0 -0
  73. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/schema_generator.py +0 -0
  74. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/schema_manager.py +0 -0
  75. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/core/session_client.py +0 -0
  76. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/dolibarr_cli.py +0 -0
  77. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/extrafields_cache.json +0 -0
  78. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/hermes_plugin/__init__.py +0 -0
  79. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/models_supplement.json +0 -0
  80. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/schema.json +0 -0
  81. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tests/__init__.py +0 -0
  82. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tests/test_core.py +0 -0
  83. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tests/test_enrich.py +0 -0
  84. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tests/test_full_e2e.py +0 -0
  85. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tests/test_tools.py +0 -0
  86. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tools/__init__.py +0 -0
  87. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tools/executor.py +0 -0
  88. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/tools/tools_schema.py +0 -0
  89. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr/dolibarr/utils/__init__.py +0 -0
  90. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr.egg-info/SOURCES.txt +0 -0
  91. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr.egg-info/dependency_links.txt +0 -0
  92. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr.egg-info/entry_points.txt +0 -0
  93. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr.egg-info/requires.txt +0 -0
  94. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/cli_dolibarr.egg-info/top_level.txt +0 -0
  95. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/pyproject.toml +0 -0
  96. {cli_dolibarr-3.7.2 → cli_dolibarr-3.7.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-dolibarr
3
- Version: 3.7.2
3
+ Version: 3.7.4
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.7.4"
@@ -138,13 +138,41 @@ def _mask_api_key(key: str) -> str:
138
138
 
139
139
 
140
140
  def _install_hermes_plugin(url: str, api_key: str):
141
- plugin_dir = Path.home() / '.hermes' / 'plugins' / 'dolibarr'
141
+ hermes_dir = Path.home() / '.hermes'
142
+ plugin_dir = hermes_dir / 'plugins' / 'dolibarr'
142
143
  source_dir = Path(__file__).resolve().parent.parent / 'hermes_plugin'
143
144
 
144
145
  if not source_dir.is_dir():
145
146
  click.echo("Hermes plugin source not found, skipping.")
146
147
  return
147
148
 
149
+ # Ensure cli_dolibarr is importable from Hermes venv
150
+ for venv_name in ('venv', '.venv'):
151
+ venv_dir = hermes_dir / 'hermes-agent' / venv_name
152
+ venv_python = venv_dir / 'bin' / 'python3'
153
+ if venv_python.exists():
154
+ try:
155
+ import subprocess
156
+ result = subprocess.run(
157
+ [str(venv_python), '-c', 'import cli_dolibarr'],
158
+ capture_output=True, timeout=10,
159
+ )
160
+ if result.returncode != 0:
161
+ click.echo(" Installing cli-dolibarr into Hermes venv...")
162
+ pip_result = subprocess.run(
163
+ [str(venv_python), '-m', 'pip', 'install', 'cli-dolibarr'],
164
+ capture_output=True, timeout=120,
165
+ )
166
+ if pip_result.returncode == 0:
167
+ click.echo(f" ✅ Installed into {venv_dir}")
168
+ else:
169
+ click.echo(f" ⚠️ Failed. Run: {venv_dir}/bin/pip install cli-dolibarr")
170
+ else:
171
+ click.echo(" cli-dolibarr already in Hermes venv (ok)")
172
+ except Exception as e:
173
+ click.echo(f" ⚠️ Could not check Hermes venv: {e}")
174
+ break
175
+
148
176
  click.echo("")
149
177
  click.echo("Installing Hermes plugin...")
150
178
 
@@ -154,7 +182,6 @@ def _install_hermes_plugin(url: str, api_key: str):
154
182
  if src.exists():
155
183
  shutil.copy2(src, plugin_dir / f)
156
184
 
157
- hermes_dir = Path.home() / '.hermes'
158
185
  env_file = hermes_dir / '.env'
159
186
 
160
187
  env_lines = []
@@ -185,7 +212,7 @@ def _install_hermes_plugin(url: str, api_key: str):
185
212
 
186
213
 
187
214
  def _configure_hermes_toolsets(hermes_dir: Path):
188
- """Add dolibarr to delegation.default_toolsets in Hermes config.yaml."""
215
+ """Add dolibarr to toolsets and delegation.default_toolsets in Hermes config.yaml."""
189
216
  config_yaml = hermes_dir / 'config.yaml'
190
217
  if not config_yaml.exists():
191
218
  click.echo(" No Hermes config.yaml found, skipping toolset config.")
@@ -193,66 +220,138 @@ def _configure_hermes_toolsets(hermes_dir: Path):
193
220
 
194
221
  lines = config_yaml.read_text().splitlines()
195
222
 
196
- # Case A: find default_toolsets: line (indented >= 2 spaces)
197
- dt_idx = None
198
- dt_indent = None
223
+ # --- 1. Top-level toolsets (controls main agent toolset loading) ---
224
+ ts_added = _add_to_yaml_list_block(lines, 'toolsets:', 0, 'dolibarr')
225
+
226
+ # --- 2. delegation.default_toolsets (controls sub-agent toolsets) ---
227
+ dt_added = _add_to_yaml_nested_list(
228
+ lines, 'delegation:', 'default_toolsets:', 'dolibarr',
229
+ fallback_items=['- terminal', '- file', '- web', '- dolibarr'],
230
+ )
231
+
232
+ if ts_added or dt_added:
233
+ config_yaml.write_text('\n'.join(lines) + '\n')
234
+ else:
235
+ click.echo(" dolibarr already in toolsets (ok)")
236
+
237
+
238
+ def _add_to_yaml_list_block(lines: list, block_key: str, min_indent: int,
239
+ item: str) -> bool:
240
+ """Add '- item' to a top-level YAML list block like 'toolsets:'.
241
+
242
+ Returns True if modified, False if already present or not found.
243
+ """
244
+ block_idx = None
245
+ block_indent = None
246
+ for i, line in enumerate(lines):
247
+ s = line.rstrip('\n')
248
+ indent = len(s) - len(s.lstrip())
249
+ if s.strip() == block_key and indent >= min_indent:
250
+ block_idx = i
251
+ block_indent = indent
252
+ break
253
+
254
+ if block_idx is None:
255
+ return False
256
+
257
+ target = f'- {item}'
258
+
259
+ # Scan block for existing item
260
+ for i in range(block_idx + 1, len(lines)):
261
+ s = lines[i].rstrip('\n')
262
+ lead = len(s) - len(s.lstrip())
263
+ if lead <= block_indent and s.strip():
264
+ break
265
+ if s.strip() == target:
266
+ return False # already present
267
+
268
+ # Find last list item in block
269
+ last_item = block_idx
270
+ for i in range(block_idx + 1, len(lines)):
271
+ s = lines[i].rstrip('\n')
272
+ lead = len(s) - len(s.lstrip())
273
+ if lead <= block_indent and s.strip():
274
+ break
275
+ if s.strip().startswith('- '):
276
+ last_item = i
277
+
278
+ new_line = (' ' * (block_indent + 2)) + target
279
+ lines.insert(last_item + 1, new_line)
280
+ click.echo(f" ✅ Added {item} to {block_key}")
281
+ return True
282
+
283
+
284
+ def _add_to_yaml_nested_list(lines: list, parent_key: str, child_key: str,
285
+ item: str, fallback_items: list = None) -> bool:
286
+ """Add '- item' to a nested YAML list like delegation.default_toolsets.
287
+
288
+ If child block doesn't exist but parent does, insert the full block
289
+ using fallback_items. Returns True if modified.
290
+ """
291
+ target = f'- {item}'
292
+
293
+ # Find parent (e.g. 'delegation:')
294
+ parent_idx = None
199
295
  for i, line in enumerate(lines):
200
296
  s = line.rstrip('\n')
201
- if s.strip() == 'default_toolsets:' and (len(s) - len(s.lstrip())) >= 2:
202
- dt_idx = i
203
- dt_indent = len(s) - len(s.lstrip())
297
+ if s.strip() == parent_key:
298
+ parent_idx = i
299
+ break
300
+
301
+ if parent_idx is None:
302
+ click.echo(f" ⚠️ No {parent_key} section in config.yaml.")
303
+ return False
304
+
305
+ parent_indent = len(lines[parent_idx].rstrip('\n')) - len(lines[parent_idx].rstrip('\n').lstrip())
306
+
307
+ # Find child (e.g. 'default_toolsets:') inside parent
308
+ child_idx = None
309
+ child_indent = None
310
+ for i in range(parent_idx + 1, len(lines)):
311
+ s = lines[i].rstrip('\n')
312
+ indent = len(s) - len(s.lstrip())
313
+ if indent <= parent_indent and s.strip():
314
+ break # exited parent block
315
+ if s.strip() == child_key and indent >= parent_indent + 2:
316
+ child_idx = i
317
+ child_indent = indent
204
318
  break
205
319
 
206
- if dt_idx is not None:
207
- # Check if dolibarr already in this block
208
- for i in range(dt_idx + 1, len(lines)):
320
+ if child_idx is not None:
321
+ # Check if already present
322
+ for i in range(child_idx + 1, len(lines)):
209
323
  s = lines[i].rstrip('\n')
210
324
  lead = len(s) - len(s.lstrip())
211
- if lead <= dt_indent:
325
+ if lead <= child_indent and s.strip():
212
326
  break
213
- if s.strip() == '- dolibarr':
214
- click.echo(" dolibarr already in default_toolsets (ok)")
215
- return
327
+ if s.strip() == target:
328
+ return False # already present
216
329
 
217
- # Not found — find last list item in block and insert after it
218
- new_line = (' ' * (dt_indent + 2)) + '- dolibarr'
219
- last_item = dt_idx
220
- for i in range(dt_idx + 1, len(lines)):
330
+ # Find last list item and append
331
+ last_item = child_idx
332
+ for i in range(child_idx + 1, len(lines)):
221
333
  s = lines[i].rstrip('\n')
222
334
  lead = len(s) - len(s.lstrip())
223
- if lead <= dt_indent:
335
+ if lead <= child_indent and s.strip():
224
336
  break
225
337
  if s.strip().startswith('- '):
226
338
  last_item = i
227
339
 
340
+ new_line = (' ' * (child_indent + 2)) + target
228
341
  lines.insert(last_item + 1, new_line)
229
- config_yaml.write_text('\n'.join(lines) + '\n')
230
- click.echo(" ✅ Added dolibarr to delegation.default_toolsets")
231
- return
342
+ click.echo(f" ✅ Added {item} to {parent_key}.{child_key}")
343
+ return True
232
344
 
233
- # Case B: delegation: exists but no default_toolsets
234
- delegation_idx = None
235
- for i, line in enumerate(lines):
236
- if line.rstrip('\n').strip() == 'delegation:':
237
- delegation_idx = i
238
- break
239
-
240
- if delegation_idx is not None:
241
- d = lines[delegation_idx].rstrip('\n')
242
- d_indent = len(d) - len(d.lstrip())
243
- block_lines = [
244
- (' ' * (d_indent + 2)) + 'default_toolsets:',
245
- (' ' * (d_indent + 4)) + '- terminal',
246
- (' ' * (d_indent + 4)) + '- file',
247
- (' ' * (d_indent + 4)) + '- web',
248
- (' ' * (d_indent + 4)) + '- dolibarr',
345
+ # Child doesn't exist insert full block under parent
346
+ if fallback_items:
347
+ insert_lines = [
348
+ (' ' * (parent_indent + 2)) + child_key,
249
349
  ]
250
- for offset, block_line in enumerate(block_lines):
251
- lines.insert(delegation_idx + 1 + offset, block_line)
252
- config_yaml.write_text('\n'.join(lines) + '\n')
253
- click.echo(" ✅ Added delegation.default_toolsets with dolibarr")
254
- return
255
-
256
- # Case C: no delegation section at all
257
- click.echo(" ⚠️ No delegation section in config.yaml.")
258
- click.echo(" Add 'dolibarr' to delegation.default_toolsets manually.")
350
+ for fb in fallback_items:
351
+ insert_lines.append((' ' * (parent_indent + 4)) + fb)
352
+ for offset, il in enumerate(insert_lines):
353
+ lines.insert(parent_idx + 1 + offset, il)
354
+ click.echo(f" ✅ Added {parent_key}.{child_key} with {item}")
355
+ return True
356
+
357
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-dolibarr
3
- Version: 3.7.2
3
+ Version: 3.7.4
4
4
  Summary: CLI tool for Dolibarr ERP/CRM REST API management
5
5
  Author: CLI Anything
6
6
  License-Expression: MIT
@@ -1 +0,0 @@
1
- __version__ = "3.7.2"
File without changes
File without changes
File without changes