bc-cli 0.1.3__tar.gz → 0.2.0__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 (182) hide show
  1. {bc_cli-0.1.3 → bc_cli-0.2.0}/.gitignore +1 -0
  2. {bc_cli-0.1.3 → bc_cli-0.2.0}/AGENTS.md +102 -0
  3. {bc_cli-0.1.3 → bc_cli-0.2.0}/CHANGELOG.md +49 -0
  4. {bc_cli-0.1.3 → bc_cli-0.2.0}/PKG-INFO +15 -25
  5. {bc_cli-0.1.3 → bc_cli-0.2.0}/README.md +9 -9
  6. bc_cli-0.2.0/docs/authentication.md +104 -0
  7. bc_cli-0.2.0/docs/business-central-admin-setup.md +121 -0
  8. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/command-reference.md +13 -4
  9. bc_cli-0.2.0/docs/configuration.md +202 -0
  10. bc_cli-0.2.0/docs/getting-started.md +112 -0
  11. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/mcp-server.md +2 -2
  12. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/saved-queries.md +3 -3
  13. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/write-operations.md +41 -3
  14. {bc_cli-0.1.3 → bc_cli-0.2.0}/pyproject.toml +8 -12
  15. bc_cli-0.2.0/src/bcli/_version.py +18 -0
  16. bc_cli-0.2.0/src/bcli/audit/__init__.py +27 -0
  17. bc_cli-0.2.0/src/bcli/audit/_factory.py +74 -0
  18. bc_cli-0.2.0/src/bcli/audit/_protocol.py +126 -0
  19. bc_cli-0.2.0/src/bcli/audit/_redact.py +60 -0
  20. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/_browser.py +1 -1
  21. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/_secure_io.py +3 -3
  22. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/client/_async.py +6 -19
  23. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/config/_model.py +44 -26
  24. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/registry/_importers.py +54 -2
  25. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/registry/_schema.py +11 -0
  26. bc_cli-0.2.0/src/bcli_cli/_audit_wrap.py +153 -0
  27. bc_cli-0.2.0/src/bcli_cli/_dry_run.py +124 -0
  28. bc_cli-0.2.0/src/bcli_cli/_url_resolve.py +57 -0
  29. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/attach_cmd.py +52 -17
  30. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/auth_cmd.py +22 -22
  31. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/config_cmd.py +97 -19
  32. bc_cli-0.2.0/src/bcli_cli/commands/delete_cmd.py +76 -0
  33. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/endpoint_cmd.py +3 -0
  34. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/get_cmd.py +3 -3
  35. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/patch_cmd.py +31 -9
  36. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/post_cmd.py +26 -9
  37. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_mcp/_runner.py +2 -2
  38. bc_cli-0.2.0/tests/test_audit/test_factory.py +71 -0
  39. bc_cli-0.2.0/tests/test_audit/test_redact.py +87 -0
  40. bc_cli-0.2.0/tests/test_audit/test_sink.py +134 -0
  41. bc_cli-0.2.0/tests/test_cli/test_audit_wrap.py +288 -0
  42. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_config_cmd.py +72 -0
  43. bc_cli-0.2.0/tests/test_cli/test_dry_run.py +227 -0
  44. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_config/test_config.py +20 -0
  45. bc_cli-0.2.0/tests/test_registry/test_caution.py +99 -0
  46. bc_cli-0.2.0/tests/test_workflow/__init__.py +0 -0
  47. {bc_cli-0.1.3 → bc_cli-0.2.0}/uv.lock +11 -40
  48. bc_cli-0.1.3/docs/authentication.md +0 -194
  49. bc_cli-0.1.3/docs/configuration.md +0 -118
  50. bc_cli-0.1.3/docs/getting-started.md +0 -117
  51. bc_cli-0.1.3/src/bcli/_version.py +0 -1
  52. bc_cli-0.1.3/src/bcli/auth/_workos.py +0 -313
  53. bc_cli-0.1.3/src/bcli_cli/commands/delete_cmd.py +0 -52
  54. bc_cli-0.1.3/tests/test_auth/test_workos_cache.py +0 -93
  55. bc_cli-0.1.3/tests/test_auth/test_workos_callback_state.py +0 -284
  56. {bc_cli-0.1.3 → bc_cli-0.2.0}/.env.example +0 -0
  57. {bc_cli-0.1.3 → bc_cli-0.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  58. {bc_cli-0.1.3 → bc_cli-0.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  59. {bc_cli-0.1.3 → bc_cli-0.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  60. {bc_cli-0.1.3 → bc_cli-0.2.0}/.github/workflows/publish.yml +0 -0
  61. {bc_cli-0.1.3 → bc_cli-0.2.0}/.github/workflows/tests.yml +0 -0
  62. {bc_cli-0.1.3 → bc_cli-0.2.0}/CODE_OF_CONDUCT.md +0 -0
  63. {bc_cli-0.1.3 → bc_cli-0.2.0}/CONTRIBUTING.md +0 -0
  64. {bc_cli-0.1.3 → bc_cli-0.2.0}/LICENSE +0 -0
  65. {bc_cli-0.1.3 → bc_cli-0.2.0}/NOTICE +0 -0
  66. {bc_cli-0.1.3 → bc_cli-0.2.0}/SECURITY.md +0 -0
  67. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/batch-operations.md +0 -0
  68. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/contributing.md +0 -0
  69. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/custom-apis.md +0 -0
  70. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/demo-setup.md +0 -0
  71. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/multi-company.md +0 -0
  72. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/querying.md +0 -0
  73. {bc_cli-0.1.3 → bc_cli-0.2.0}/docs/sdk-usage.md +0 -0
  74. {bc_cli-0.1.3 → bc_cli-0.2.0}/examples/ap-monthly-review.yaml +0 -0
  75. {bc_cli-0.1.3 → bc_cli-0.2.0}/examples/attach-purchase-invoice-pdf.yaml +0 -0
  76. {bc_cli-0.1.3 → bc_cli-0.2.0}/examples/create-purchase-invoice.yaml +0 -0
  77. {bc_cli-0.1.3 → bc_cli-0.2.0}/examples/month-end-cronus.yaml +0 -0
  78. {bc_cli-0.1.3 → bc_cli-0.2.0}/examples/queries/sample.yaml +0 -0
  79. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/__init__.py +0 -0
  80. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/_url.py +0 -0
  81. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/__init__.py +0 -0
  82. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/_base.py +0 -0
  83. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/_credentials.py +0 -0
  84. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/_device_code.py +0 -0
  85. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/auth/_token_cache.py +0 -0
  86. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/client/__init__.py +0 -0
  87. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/client/_safety.py +0 -0
  88. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/client/_sync.py +0 -0
  89. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/client/_transport.py +0 -0
  90. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/config/__init__.py +0 -0
  91. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/config/_defaults.py +0 -0
  92. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/config/_loader.py +0 -0
  93. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/errors.py +0 -0
  94. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/__init__.py +0 -0
  95. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/_auth.py +0 -0
  96. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/_bridge.py +0 -0
  97. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/_client.py +0 -0
  98. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/_generic.py +0 -0
  99. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/_polaris.py +0 -0
  100. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/etl/_stampers.py +0 -0
  101. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/odata/__init__.py +0 -0
  102. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/odata/_escape.py +0 -0
  103. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/odata/_filter_fields.py +0 -0
  104. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/odata/_pagination.py +0 -0
  105. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/odata/_query.py +0 -0
  106. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/odata/_response.py +0 -0
  107. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/py.typed +0 -0
  108. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/registry/__init__.py +0 -0
  109. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/registry/_registry.py +0 -0
  110. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/registry/standard_v2.json +0 -0
  111. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/telemetry/__init__.py +0 -0
  112. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/telemetry/_azure_monitor.py +0 -0
  113. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/telemetry/_factory.py +0 -0
  114. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/telemetry/_protocol.py +0 -0
  115. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/telemetry/events.py +0 -0
  116. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/workflow/__init__.py +0 -0
  117. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/workflow/_loader.py +0 -0
  118. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/workflow/_models.py +0 -0
  119. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli/workflow/_resolver.py +0 -0
  120. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/__init__.py +0 -0
  121. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/_safety.py +0 -0
  122. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/_state.py +0 -0
  123. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/app.py +0 -0
  124. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/__init__.py +0 -0
  125. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/batch_cmd.py +0 -0
  126. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/company_cmd.py +0 -0
  127. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/context_cmd.py +0 -0
  128. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/env_cmd.py +0 -0
  129. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/etl_cmd.py +0 -0
  130. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/query_cmd.py +0 -0
  131. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/registry_cmd.py +0 -0
  132. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/commands/test_cmd.py +0 -0
  133. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/output/__init__.py +0 -0
  134. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/output/_display.py +0 -0
  135. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_cli/output/_formatters.py +0 -0
  136. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_mcp/__init__.py +0 -0
  137. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_mcp/__main__.py +0 -0
  138. {bc_cli-0.1.3 → bc_cli-0.2.0}/src/bcli_mcp/_server.py +0 -0
  139. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/conftest.py +0 -0
  140. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/fixtures/sample_postman_collection.json +0 -0
  141. {bc_cli-0.1.3/tests/test_auth → bc_cli-0.2.0/tests/test_audit}/__init__.py +0 -0
  142. {bc_cli-0.1.3/tests/test_cli → bc_cli-0.2.0/tests/test_auth}/__init__.py +0 -0
  143. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_auth/test_browser_auth.py +0 -0
  144. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_auth/test_secure_io.py +0 -0
  145. {bc_cli-0.1.3/tests/test_client → bc_cli-0.2.0/tests/test_cli}/__init__.py +0 -0
  146. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_batch_safety.py +0 -0
  147. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_company_cmd.py +0 -0
  148. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_output_format.py +0 -0
  149. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_query_cmd.py +0 -0
  150. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_safety.py +0 -0
  151. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_cli/test_state.py +0 -0
  152. {bc_cli-0.1.3/tests/test_config → bc_cli-0.2.0/tests/test_client}/__init__.py +0 -0
  153. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_client/test_resolve_url.py +0 -0
  154. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_client/test_safety.py +0 -0
  155. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_client/test_transport.py +0 -0
  156. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_client/test_upload_attachment.py +0 -0
  157. {bc_cli-0.1.3/tests/test_etl → bc_cli-0.2.0/tests/test_config}/__init__.py +0 -0
  158. {bc_cli-0.1.3/tests/test_mcp → bc_cli-0.2.0/tests/test_etl}/__init__.py +0 -0
  159. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_etl/test_bridge.py +0 -0
  160. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_etl/test_generic.py +0 -0
  161. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_etl/test_stampers.py +0 -0
  162. {bc_cli-0.1.3/tests/test_odata → bc_cli-0.2.0/tests/test_mcp}/__init__.py +0 -0
  163. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_mcp/test_runner.py +0 -0
  164. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_mcp/test_server_tools.py +0 -0
  165. {bc_cli-0.1.3/tests/test_registry → bc_cli-0.2.0/tests/test_odata}/__init__.py +0 -0
  166. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_odata/test_escape.py +0 -0
  167. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_odata/test_filter_fields.py +0 -0
  168. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_odata/test_query.py +0 -0
  169. {bc_cli-0.1.3/tests/test_telemetry → bc_cli-0.2.0/tests/test_registry}/__init__.py +0 -0
  170. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_registry/test_importers.py +0 -0
  171. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_registry/test_metadata_fields.py +0 -0
  172. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_registry/test_registry.py +0 -0
  173. {bc_cli-0.1.3/tests/test_url → bc_cli-0.2.0/tests/test_telemetry}/__init__.py +0 -0
  174. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_telemetry/test_events.py +0 -0
  175. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_telemetry/test_sink.py +0 -0
  176. {bc_cli-0.1.3/tests/test_workflow → bc_cli-0.2.0/tests/test_url}/__init__.py +0 -0
  177. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_url/test_origin_allowlist.py +0 -0
  178. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_url/test_url_builder.py +0 -0
  179. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_workflow/test_batch_integration.py +0 -0
  180. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_workflow/test_loader.py +0 -0
  181. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_workflow/test_models.py +0 -0
  182. {bc_cli-0.1.3 → bc_cli-0.2.0}/tests/test_workflow/test_resolver.py +0 -0
@@ -32,3 +32,4 @@ TRASH-FILES.md
32
32
  PRD-*.md
33
33
  TODOS.md
34
34
  bcapi_cli_prd.md
35
+ .planning/
@@ -29,6 +29,47 @@ Use `-e` / `--env` only when the user explicitly asks you to hit a
29
29
  Same for `--company` / `-c`: only pass it when switching off the
30
30
  profile's default company.
31
31
 
32
+ The endpoint **registry** does the same job for the API route. When you
33
+ write `bcli get fixedAssets`, the registry already knows the
34
+ publisher / group / version for `fixedAssets` and builds the URL for
35
+ you. You do **not** need `--publisher … --group … --version …` — those
36
+ are escape hatches for the rare case where an admin hasn't imported the
37
+ endpoint yet, and they're hidden from `--help` for that reason. If
38
+ `bcli get <name>` errors with `RegistryError`, the fix is to import the
39
+ endpoint into the registry, not to pass override flags.
40
+
41
+ ---
42
+
43
+ ## Don't write this — minimal command, please
44
+
45
+ The single biggest tell that an agent is over-pattern-matching:
46
+ redundant flags that the profile + registry already supply.
47
+
48
+ ```bash
49
+ # ❌ Don't write this:
50
+ bcli -c LLC get fixedAssets --publisher beautech --group finance --version v1.5 --all -f json
51
+
52
+ # ✅ Write this:
53
+ bcli -c LLC get fixedAssets
54
+ ```
55
+
56
+ Why each flag was wrong:
57
+
58
+ - `--publisher beautech --group finance --version v1.5` — the
59
+ registry resolves these automatically. Only pass them if the
60
+ endpoint isn't in the registry (and even then, prefer importing it).
61
+ - `--all` — pulls **every** page. Most asks need `--top 5` or no
62
+ pagination flag at all. Use `--all` only when the user explicitly
63
+ asks for a full export.
64
+ - `-f json` — bcli already auto-detects agents (`CLAUDECODE=1`,
65
+ `BCLI_AGENT=1`, or non-TTY stdout) and emits markdown. Pass `-f
66
+ json` only when you actually need to feed the result into `jq` or
67
+ another tool call.
68
+
69
+ Rule of thumb: **start with the shortest command that names the
70
+ action** (`bcli get fixedAssets`), then add flags one at a time only
71
+ when the user's question demands them.
72
+
32
73
  ---
33
74
 
34
75
  ## Endpoint discovery — don't guess names
@@ -120,6 +161,67 @@ user, don't loop.
120
161
 
121
162
  ---
122
163
 
164
+ ## Dry-run before writes
165
+
166
+ Before any `post` / `patch` / `delete` / `attach upload`, run with `--dry-run`
167
+ and `-f json` to get a structured preview the user can sanity-check:
168
+
169
+ ```bash
170
+ bcli --dry-run -f json post customers --data '{"displayName": "Test"}'
171
+ ```
172
+
173
+ The response is a JSON envelope:
174
+
175
+ ```json
176
+ {
177
+ "dry_run": true,
178
+ "method": "POST",
179
+ "endpoint": "customers",
180
+ "resolved_url": "https://.../api/v2.0/companies(<id>)/customers",
181
+ "profile": "dev",
182
+ "environment": "Sandbox",
183
+ "company_id": "<id>",
184
+ "body": {"displayName": "Test"}
185
+ }
186
+ ```
187
+
188
+ `PATCH` and `DELETE` envelopes also include `record_id`. The shape is stable —
189
+ field names won't change. Use it to:
190
+
191
+ * Show the user the resolved URL + body before they approve a real write.
192
+ * Catch typos in the endpoint name before any HTTP call goes out.
193
+ * Verify the right environment / company is targeted.
194
+
195
+ ## Caution levels for write endpoints
196
+
197
+ Every endpoint exposes a `caution` level (`low` / `medium` / `high`) via
198
+ `bcli endpoint info` and the `list_endpoints` MCP tool. Endpoints whose name
199
+ contains a mutation verb (`post`, `release`, `cancel`, `void`, `reverse`,
200
+ `apply`, `unapply`) are flagged `high` automatically. Treat `high` as: "do
201
+ not write without explicit user confirmation, even if the user previously
202
+ authorised a similar action." Examples:
203
+
204
+ * `customers` → `low` (CRUD on a master-data record)
205
+ * `salesInvoicePost` → `high` (irreversibly posts an invoice)
206
+ * `customerLedgerEntryApply` → `high` (modifies posted ledger state)
207
+
208
+ ## Audit log location
209
+
210
+ When the user has `[audit] enabled = true` in `~/.config/bcli/config.toml`,
211
+ every write you trigger appends a JSON line to
212
+ `~/.config/bcli/audit/<profile>.jsonl` (or whatever the user configured).
213
+ Each entry includes `outcome` (`completed` / `failed` / `dry_run`),
214
+ `correlation_id` (BC's `x-ms-correlation-request-id`), `latency_ms`, and the
215
+ redacted request body. Useful for:
216
+
217
+ * Showing the user "here's what just happened" after a multi-step task.
218
+ * Grepping for the BC correlation ID when debugging a 500 the user reported.
219
+ * Reconciling intent (`dry_run` entries) against actual writes.
220
+
221
+ You don't need to enable the log yourself — it's the user's choice. If they
222
+ ask "did that POST go through?" the audit log is the canonical answer when it's
223
+ on, and the CLI exit code is the answer when it's off.
224
+
123
225
  ## When you have an MCP server
124
226
 
125
227
  If the user has mounted `bcli-mcp` (see [`docs/mcp-server.md`](docs/mcp-server.md)),
@@ -7,8 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.0] — 2026-05-06
11
+
12
+ ### Added
13
+
14
+ - **Structured `--dry-run` output** — write commands (`post`, `patch`,
15
+ `delete`, `attach upload`) now emit a stable JSON envelope on stdout
16
+ when `--format json` / `ndjson` / `raw` is selected. Includes
17
+ `dry_run`, `method`, `endpoint`, `resolved_url`, `profile`,
18
+ `environment`, `company_id`, `body`, and `record_id` (when applicable).
19
+ Agents can parse the envelope before deciding whether to proceed. The
20
+ human format keeps the same yellow rich panel on stderr but is now
21
+ augmented with the resolved URL and profile context. See
22
+ `docs/write-operations.md`.
23
+ - **Opt-in audit log** — new `[audit]` config section persists every
24
+ write to a per-profile JSONL file. Each entry captures the resolved
25
+ URL, response status, BC `correlation_id`, latency, redacted request
26
+ body, and outcome (`completed` / `failed` / `dry_run`). Bounded disk
27
+ usage via single-backup rotation. SDK (`AsyncBCClient`) does NOT
28
+ auto-emit; this is a CLI-layer ergonomic on top of BC permission sets.
29
+ See `docs/configuration.md#audit-log`.
30
+ - **Endpoint `caution` flag** — `EndpointMetadata` now carries a
31
+ `caution: low | medium | high` level. Importers populate it
32
+ automatically from a verb-name heuristic (entities containing `post`,
33
+ `release`, `cancel`, `void`, `reverse`, `apply`, `unapply` are flagged
34
+ `high`). Surfaced in `bcli endpoint info` and the `list_endpoints` MCP
35
+ tool so agents can require explicit user confirmation before mutating
36
+ posted/closed records.
37
+ - New `AGENTS.md` recipes for dry-run-first writes, caution-level
38
+ interpretation, and audit-log location.
39
+
40
+ ## [0.1.5] — 2026-05-05
41
+
10
42
  ### Added
11
43
 
44
+ - **Business Central admin setup guide** — new
45
+ `docs/business-central-admin-setup.md` walks a zero-knowledge user
46
+ through Entra app registration, localhost redirect setup, delegated BC
47
+ permissions, admin consent, BC user permission sets, first `bcli
48
+ config init`, and verification.
12
49
  - **`bcli-mcp` preview server** — an MCP (Model Context Protocol) server
13
50
  that lets Claude Desktop and other MCP clients drive bcli. Four
14
51
  read-only tools: `query`, `list_endpoints`, `describe_endpoint`,
@@ -18,12 +55,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
18
55
 
19
56
  ### Changed
20
57
 
58
+ - `bcli config init` now defaults to browser PKCE auth for local humans
59
+ and agents. New `--automation` and `--headless` shortcuts create
60
+ client-credentials and device-code profiles respectively.
61
+ - CLI runtime dependencies now ship with the base `bc-cli` install, so
62
+ `pip install bc-cli` and `uv tool install bc-cli` provide a working
63
+ `bcli` command without requiring an extra.
21
64
  - `bcli company list` accepts `--format` (`json`, `markdown`, `csv`,
22
65
  `ndjson`, `table`). Stable JSON shape:
23
66
  `[{"id", "name", "alias", "is_default"}]`.
24
67
  - `bcli endpoint list` and `bcli endpoint info` accept `--format json`.
25
68
  Stable JSON shapes documented inline in each command's help text.
26
69
 
70
+ ### Removed
71
+
72
+ - Removed WorkOS AuthKit support. Browser PKCE is now the delegated auth
73
+ path, Business Central remains the permission boundary, and
74
+ client-credentials profiles cover automation.
75
+
27
76
  ## [0.1.2] — 2026-04-29
28
77
 
29
78
  Security release. Closes four findings from a strix.ai run against the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bc-cli
3
- Version: 0.1.3
3
+ Version: 0.2.0
4
4
  Summary: Python SDK and CLI for Microsoft Dynamics 365 Business Central APIs
5
5
  Project-URL: Homepage, https://github.com/igor-ctrl/bcli
6
6
  Project-URL: Repository, https://github.com/igor-ctrl/bcli
@@ -23,35 +23,25 @@ Classifier: Topic :: Office/Business :: Financial :: Accounting
23
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
24
  Requires-Python: >=3.11
25
25
  Requires-Dist: httpx>=0.27
26
+ Requires-Dist: keyring>=25.0
26
27
  Requires-Dist: msal>=1.28
27
28
  Requires-Dist: pydantic>=2.0
29
+ Requires-Dist: pyyaml>=6.0
30
+ Requires-Dist: rich>=13.0
28
31
  Requires-Dist: tomlkit>=0.13
32
+ Requires-Dist: typer>=0.12
29
33
  Provides-Extra: cli
30
- Requires-Dist: keyring>=25.0; extra == 'cli'
31
- Requires-Dist: pyyaml>=6.0; extra == 'cli'
32
- Requires-Dist: rich>=13.0; extra == 'cli'
33
- Requires-Dist: typer>=0.12; extra == 'cli'
34
- Requires-Dist: workos>=5.0; extra == 'cli'
35
34
  Provides-Extra: dev
36
- Requires-Dist: keyring>=25.0; extra == 'dev'
35
+ Requires-Dist: dlt[filesystem,parquet,s3]>=1.0; extra == 'dev'
37
36
  Requires-Dist: mcp>=1.0; extra == 'dev'
38
37
  Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
39
38
  Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
40
39
  Requires-Dist: pytest>=8.0; extra == 'dev'
41
- Requires-Dist: pyyaml>=6.0; extra == 'dev'
42
- Requires-Dist: rich>=13.0; extra == 'dev'
43
40
  Requires-Dist: ruff>=0.5; extra == 'dev'
44
- Requires-Dist: typer>=0.12; extra == 'dev'
45
- Requires-Dist: workos>=5.0; extra == 'dev'
46
41
  Provides-Extra: etl
47
42
  Requires-Dist: dlt[filesystem,parquet,s3]>=1.0; extra == 'etl'
48
43
  Provides-Extra: mcp
49
- Requires-Dist: keyring>=25.0; extra == 'mcp'
50
44
  Requires-Dist: mcp>=1.0; extra == 'mcp'
51
- Requires-Dist: pyyaml>=6.0; extra == 'mcp'
52
- Requires-Dist: rich>=13.0; extra == 'mcp'
53
- Requires-Dist: typer>=0.12; extra == 'mcp'
54
- Requires-Dist: workos>=5.0; extra == 'mcp'
55
45
  Provides-Extra: polaris
56
46
  Requires-Dist: dlt[filesystem,parquet,s3]>=1.0; extra == 'polaris'
57
47
  Requires-Dist: pyarrow>=16.0; extra == 'polaris'
@@ -67,7 +57,9 @@ Description-Content-Type: text/markdown
67
57
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
68
58
  [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue.svg)](pyproject.toml)
69
59
 
70
- A Python SDK and CLI for Microsoft Dynamics 365 Business Central APIs, with a built-in [dlt](https://dlthub.com) source for ETL backup pipelines.
60
+ A Python SDK and CLI for Microsoft Dynamics 365 Business Central APIs, with
61
+ agent-friendly endpoint discovery, browser auth, custom API registries, and a
62
+ built-in [dlt](https://dlthub.com) source for ETL backup pipelines.
71
63
 
72
64
  > **Status: Alpha (0.1.x).** Public surface may change before 1.0. Track
73
65
  > [CHANGELOG.md](CHANGELOG.md) for breaking changes. Independent project
@@ -112,7 +104,7 @@ pip install bc-cli
112
104
  # or
113
105
  uv tool install bc-cli
114
106
 
115
- # Configure (interactive discovers companies automatically)
107
+ # Configure with browser auth (no client secret)
116
108
  bcli config init
117
109
 
118
110
  # Query standard APIs immediately
@@ -135,7 +127,7 @@ bcli get myCustomEntities --top 5
135
127
  - **Multi-company** — Assign aliases to companies and query across all entities
136
128
  - **OData query builder** — `--filter`, `--select`, `--expand`, `--orderby`, `--top`, `--skip` on every query
137
129
  - **Multiple output formats** — table, JSON, CSV, NDJSON for pipeline use
138
- - **Secure auth** — OS keychain integration (macOS Keychain, Windows Credential Manager), token caching, client credentials + device code flows
130
+ - **Secure auth** — Browser PKCE by default, OS keychain support for automation secrets, token caching, client credentials + device code fallback
139
131
  - **Write safety** — SafeContext gate prevents wrong-environment writes, enforces draft status on financial documents
140
132
  - **Programmatic auth** — Pass credentials directly for MCP servers, Airflow DAGs, and containers (no config files required)
141
133
  - **Batch operations** — Execute sequences of API calls from YAML files
@@ -196,17 +188,14 @@ Requires Python 3.11+.
196
188
  > documented.
197
189
 
198
190
  ```bash
199
- # SDK only (for libraries, MCP servers, Airflow DAGs)
191
+ # CLI + SDK
200
192
  pip install bc-cli
201
193
 
202
- # SDK + CLI
203
- pip install "bc-cli[cli]"
204
-
205
194
  # SDK + ETL (dlt source for backup pipelines)
206
195
  pip install "bc-cli[etl]"
207
196
 
208
197
  # Everything
209
- pip install "bc-cli[cli,etl]"
198
+ pip install "bc-cli[etl,mcp,telemetry]"
210
199
 
211
200
  # Via uv (recommended)
212
201
  uv tool install bc-cli
@@ -222,8 +211,9 @@ pip install -e ".[dev,etl]"
222
211
  | Guide | Description |
223
212
  |-------|-------------|
224
213
  | [Getting Started](docs/getting-started.md) | First-time setup, authentication, your first query |
214
+ | [Business Central Admin Setup](docs/business-central-admin-setup.md) | Entra app registration and BC permissions from scratch |
225
215
  | [Configuration](docs/configuration.md) | Profiles, environments, config file format |
226
- | [Authentication](docs/authentication.md) | Client credentials, device code, OS keychain |
216
+ | [Authentication](docs/authentication.md) | Browser auth, client credentials, device code fallback |
227
217
  | [Querying Data](docs/querying.md) | GET, OData filters, pagination, output formats |
228
218
  | [Write Operations](docs/write-operations.md) | POST, PATCH, DELETE |
229
219
  | [Custom APIs](docs/custom-apis.md) | Importing from Postman, JSON, or $metadata |
@@ -5,7 +5,9 @@
5
5
  [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
6
6
  [![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue.svg)](pyproject.toml)
7
7
 
8
- A Python SDK and CLI for Microsoft Dynamics 365 Business Central APIs, with a built-in [dlt](https://dlthub.com) source for ETL backup pipelines.
8
+ A Python SDK and CLI for Microsoft Dynamics 365 Business Central APIs, with
9
+ agent-friendly endpoint discovery, browser auth, custom API registries, and a
10
+ built-in [dlt](https://dlthub.com) source for ETL backup pipelines.
9
11
 
10
12
  > **Status: Alpha (0.1.x).** Public surface may change before 1.0. Track
11
13
  > [CHANGELOG.md](CHANGELOG.md) for breaking changes. Independent project
@@ -50,7 +52,7 @@ pip install bc-cli
50
52
  # or
51
53
  uv tool install bc-cli
52
54
 
53
- # Configure (interactive discovers companies automatically)
55
+ # Configure with browser auth (no client secret)
54
56
  bcli config init
55
57
 
56
58
  # Query standard APIs immediately
@@ -73,7 +75,7 @@ bcli get myCustomEntities --top 5
73
75
  - **Multi-company** — Assign aliases to companies and query across all entities
74
76
  - **OData query builder** — `--filter`, `--select`, `--expand`, `--orderby`, `--top`, `--skip` on every query
75
77
  - **Multiple output formats** — table, JSON, CSV, NDJSON for pipeline use
76
- - **Secure auth** — OS keychain integration (macOS Keychain, Windows Credential Manager), token caching, client credentials + device code flows
78
+ - **Secure auth** — Browser PKCE by default, OS keychain support for automation secrets, token caching, client credentials + device code fallback
77
79
  - **Write safety** — SafeContext gate prevents wrong-environment writes, enforces draft status on financial documents
78
80
  - **Programmatic auth** — Pass credentials directly for MCP servers, Airflow DAGs, and containers (no config files required)
79
81
  - **Batch operations** — Execute sequences of API calls from YAML files
@@ -134,17 +136,14 @@ Requires Python 3.11+.
134
136
  > documented.
135
137
 
136
138
  ```bash
137
- # SDK only (for libraries, MCP servers, Airflow DAGs)
139
+ # CLI + SDK
138
140
  pip install bc-cli
139
141
 
140
- # SDK + CLI
141
- pip install "bc-cli[cli]"
142
-
143
142
  # SDK + ETL (dlt source for backup pipelines)
144
143
  pip install "bc-cli[etl]"
145
144
 
146
145
  # Everything
147
- pip install "bc-cli[cli,etl]"
146
+ pip install "bc-cli[etl,mcp,telemetry]"
148
147
 
149
148
  # Via uv (recommended)
150
149
  uv tool install bc-cli
@@ -160,8 +159,9 @@ pip install -e ".[dev,etl]"
160
159
  | Guide | Description |
161
160
  |-------|-------------|
162
161
  | [Getting Started](docs/getting-started.md) | First-time setup, authentication, your first query |
162
+ | [Business Central Admin Setup](docs/business-central-admin-setup.md) | Entra app registration and BC permissions from scratch |
163
163
  | [Configuration](docs/configuration.md) | Profiles, environments, config file format |
164
- | [Authentication](docs/authentication.md) | Client credentials, device code, OS keychain |
164
+ | [Authentication](docs/authentication.md) | Browser auth, client credentials, device code fallback |
165
165
  | [Querying Data](docs/querying.md) | GET, OData filters, pagination, output formats |
166
166
  | [Write Operations](docs/write-operations.md) | POST, PATCH, DELETE |
167
167
  | [Custom APIs](docs/custom-apis.md) | Importing from Postman, JSON, or $metadata |
@@ -0,0 +1,104 @@
1
+ # Authentication
2
+
3
+ bcli supports three Business Central online authentication methods:
4
+
5
+ | Method | Flow | Use case |
6
+ |--------|------|----------|
7
+ | `browser` | Authorization code with PKCE | Default for local humans and AI agents |
8
+ | `client_credentials` | App permissions | CI/CD, servers, scheduled jobs |
9
+ | `device_code` | Delegated device code | SSH/headless fallback |
10
+
11
+ For a full zero-knowledge Entra ID and Business Central setup, start with
12
+ [Business Central Admin Setup](business-central-admin-setup.md).
13
+
14
+ ## Browser Auth (Recommended)
15
+
16
+ Browser auth is the default for `bcli config init`. It opens the user's browser,
17
+ uses PKCE, needs no client secret, and Business Central enforces the signed-in
18
+ user's permission sets.
19
+
20
+ ```bash
21
+ bcli config init
22
+ bcli auth login
23
+ bcli get customers --top 5
24
+ ```
25
+
26
+ The Entra app registration must be a public/native client with delegated
27
+ Business Central permissions and a localhost redirect URI. See
28
+ [Business Central Admin Setup](business-central-admin-setup.md) for the portal
29
+ steps.
30
+
31
+ Useful login options:
32
+
33
+ ```bash
34
+ # Fresh browser session, useful when switching accounts
35
+ bcli auth login --method browser --incognito
36
+
37
+ # Explicit browser profile setup
38
+ bcli config init --auth browser
39
+ ```
40
+
41
+ ## Client Credentials
42
+
43
+ Use client credentials only for automation: CI/CD, background jobs, servers, and
44
+ scheduled exports. This path uses application permissions and a client secret,
45
+ so it should be set up deliberately.
46
+
47
+ ```bash
48
+ bcli config init --automation
49
+ bcli auth store-secret
50
+ bcli get customers --top 5
51
+ ```
52
+
53
+ bcli never stores client secrets in config files. It resolves secrets in this
54
+ order:
55
+
56
+ 1. OS keychain: macOS Keychain, Windows Credential Manager, or equivalent.
57
+ 2. The configured `client_secret_env` environment variable.
58
+ 3. Generic fallback env vars: `BCLI_SECRET` or `BCLI_CLIENT_SECRET`.
59
+
60
+ In CI, use environment variables:
61
+
62
+ ```yaml
63
+ env:
64
+ BCLI_SECRET: ${{ secrets.BC_CLIENT_SECRET }}
65
+
66
+ steps:
67
+ - run: bcli get customers --top 1 -f json -q
68
+ ```
69
+
70
+ No `bcli auth login` is required when a valid secret is available; bcli acquires
71
+ tokens automatically.
72
+
73
+ ## Device Code
74
+
75
+ Device code is a fallback for hosts where a localhost browser callback is not
76
+ practical, such as SSH sessions or locked-down remote machines.
77
+
78
+ ```bash
79
+ bcli config init --headless
80
+ bcli auth login --method device
81
+ ```
82
+
83
+ The terminal prints a URL and code. Open the URL in any browser, enter the code,
84
+ and bcli caches the resulting delegated token.
85
+
86
+ ## Token Cache
87
+
88
+ After authentication, bcli caches access tokens at
89
+ `~/.config/bcli/tokens.json`. Tokens are reused until shortly before expiry.
90
+
91
+ ```bash
92
+ bcli auth status
93
+ bcli auth logout
94
+ ```
95
+
96
+ ## Common Failures
97
+
98
+ | Symptom | Likely cause | Fix |
99
+ |---------|--------------|-----|
100
+ | Redirect URI mismatch | Entra app lacks localhost redirect URI | Add `http://localhost` as a mobile/desktop redirect URI |
101
+ | Consent required | Tenant admin has not granted API consent | Grant admin consent for Business Central delegated permissions |
102
+ | 403 Forbidden | User lacks BC permission set for that page/company | Assign the user the required Business Central permissions |
103
+ | Wrong tenant/account | Browser reused an existing Microsoft session | Re-run with `--incognito` |
104
+ | Secret missing | Automation profile cannot find `BCLI_SECRET` or keychain secret | Run `bcli auth store-secret` or set the env var |
@@ -0,0 +1,121 @@
1
+ # Business Central Admin Setup
2
+
3
+ This guide is for users who do not already have an Entra app registration or
4
+ Business Central API permissions ready for bcli.
5
+
6
+ ## Recommended Local Setup: Browser Auth
7
+
8
+ Use this path for humans and local AI agents. It needs no client secret.
9
+
10
+ ### 1. Create An Entra App Registration
11
+
12
+ 1. Open the Microsoft Entra admin center.
13
+ 2. Go to **Identity** -> **Applications** -> **App registrations**.
14
+ 3. Select **New registration**.
15
+ 4. Name it something clear, such as `bcli-local`.
16
+ 5. Choose the supported account type for your tenant.
17
+ 6. Register the app.
18
+ 7. Copy the **Application (client) ID** and **Directory (tenant) ID**.
19
+
20
+ ### 2. Configure Browser Redirect
21
+
22
+ 1. Open the app registration.
23
+ 2. Go to **Authentication**.
24
+ 3. Add a platform: **Mobile and desktop applications**.
25
+ 4. Add redirect URI: `http://localhost`.
26
+ 5. Save.
27
+
28
+ bcli binds an available localhost port at login time. Entra accepts localhost
29
+ redirects for native clients without requiring one fixed port.
30
+
31
+ ### 3. Add Business Central API Permission
32
+
33
+ 1. Open **API permissions**.
34
+ 2. Select **Add a permission**.
35
+ 3. Choose **Dynamics 365 Business Central**.
36
+ 4. Choose **Delegated permissions**.
37
+ 5. Add the Business Central delegated permission your tenant requires, commonly
38
+ `user_impersonation` or `Financials.ReadWrite.All`.
39
+ 6. Grant admin consent if your tenant requires it.
40
+
41
+ ### 4. Assign Business Central Permissions
42
+
43
+ The browser token carries the signed-in user. Business Central still decides
44
+ what that user can see or change.
45
+
46
+ 1. Open Business Central.
47
+ 2. Search for **Users**.
48
+ 3. Open the user who will run bcli.
49
+ 4. Assign the required permission sets for the companies and pages they need.
50
+ 5. Start read-only when possible, then add write permissions deliberately.
51
+
52
+ ### 5. Configure bcli
53
+
54
+ ```bash
55
+ bcli config init
56
+ ```
57
+
58
+ Use:
59
+
60
+ - Tenant ID: the Directory tenant ID from Entra.
61
+ - Environment: `Production`, `Sandbox`, or your BC environment name.
62
+ - Client ID: the Application client ID from Entra.
63
+ - Auth method: browser auth is the default.
64
+
65
+ When bcli asks to authenticate, accept. It opens a browser, completes Microsoft
66
+ sign-in, discovers companies, and lets you choose a default company.
67
+
68
+ ### 6. Verify
69
+
70
+ ```bash
71
+ bcli test connection
72
+ bcli get customers --top 5
73
+ ```
74
+
75
+ If this fails with `403 Forbidden`, authentication worked but Business Central
76
+ permissions are missing for that user.
77
+
78
+ ## Automation Setup: Client Credentials
79
+
80
+ Use this path for CI/CD, servers, and scheduled jobs.
81
+
82
+ ### 1. Create Or Reuse A Confidential App
83
+
84
+ Create an Entra app registration for automation and add Business Central
85
+ **application** permissions. Generate a client secret or certificate according
86
+ to your organization's policy.
87
+
88
+ ### 2. Grant Consent And BC Access
89
+
90
+ Grant admin consent for the application permission. In Business Central, ensure
91
+ the application identity has the required API access and permission sets for the
92
+ target companies.
93
+
94
+ ### 3. Configure bcli
95
+
96
+ ```bash
97
+ bcli config init --automation
98
+ bcli auth store-secret
99
+ ```
100
+
101
+ For CI, store the secret in your pipeline secret manager and expose it as
102
+ `BCLI_SECRET` or the `client_secret_env` name you chose during setup.
103
+
104
+ ## Headless Fallback: Device Code
105
+
106
+ Use device code only when browser callback auth cannot work, such as SSH hosts.
107
+
108
+ ```bash
109
+ bcli config init --headless
110
+ bcli auth login --method device
111
+ ```
112
+
113
+ ## Troubleshooting
114
+
115
+ | Error | Meaning | Fix |
116
+ |-------|---------|-----|
117
+ | Redirect URI mismatch | Entra does not allow the localhost callback | Add `http://localhost` under Mobile and desktop applications |
118
+ | Consent required | Tenant policy blocks unconsented API permissions | Ask an admin to grant consent |
119
+ | 403 Forbidden | BC rejected the user or app authorization | Assign the right BC permission sets and company access |
120
+ | Wrong account | Browser reused another Microsoft login | Run `bcli auth login --incognito` |
121
+ | Secret missing | Automation profile cannot find a secret | Run `bcli auth store-secret` or set the configured env var |
@@ -26,12 +26,23 @@ bcli [global-options] <command> [command-options]
26
26
 
27
27
  ### config init
28
28
 
29
- Interactive setup wizard. Discovers companies automatically.
29
+ Interactive setup wizard. Defaults to browser auth and discovers companies
30
+ automatically.
30
31
 
31
32
  ```bash
32
33
  bcli config init
34
+ bcli config init --automation
35
+ bcli config init --headless
33
36
  ```
34
37
 
38
+ | Option | Description |
39
+ |--------|-------------|
40
+ | `--auth <method>` | `browser`, `client-credentials`, or `device-code` |
41
+ | `--automation` | Shortcut for client credentials |
42
+ | `--headless` | Shortcut for device code |
43
+ | `--scoped` | Hide standard APIs; only imported endpoints are visible |
44
+ | `--import <file>` | Import custom endpoints after profile creation |
45
+
35
46
  ### config show
36
47
 
37
48
  Print resolved configuration (secrets redacted).
@@ -77,14 +88,12 @@ bcli auth login [--method <method>] [--incognito]
77
88
 
78
89
  | Option | Short | Description |
79
90
  |--------|-------|-------------|
80
- | `--method <method>` | `-m` | `workos`, `browser`, `device`, or `client_credentials` (default: profile's `auth_method`) |
91
+ | `--method <method>` | `-m` | `browser`, `device`, or `client_credentials` (default: profile's `auth_method`) |
81
92
  | `--incognito` | `-i` | Open the browser in incognito/private mode — useful for logging in as a different user |
82
93
 
83
94
  Examples:
84
95
  ```bash
85
96
  bcli auth login # uses profile's auth_method
86
- bcli auth login --method workos # WorkOS SSO → role-based BC access
87
- bcli auth login --method workos -i # incognito — log in as a different user
88
97
  bcli auth login --method browser # browser OAuth (user's BC permissions, PKCE)
89
98
  bcli auth login --method device # device code flow
90
99
  bcli auth login --method client_credentials # service-to-service