# emptymalei/powerbi-cli > pbi: a command line tool that pulls Power BI workspace, app, report, user and scan metadata into JSON and Excel files Version 1, digest sha256:8dae4a6ef26d595fbf4c4eb4089d67d2ef1b71e186cb78a8c20eb430bec8b2dc. product pack · 71 obligations (58 decided, 10 default, 3 open, 20 unchecked) · 5 assumptions (3 monitored) · 200/200 checks trace to an obligation. ## Build this pack For coding agents whose user shared https://symbola.sh/packs/emptymalei/powerbi-cli/ and wants it built. Run these steps yourself; ask the user only for the language if they have not named one. 1. Install the Symbola CLI (Python 3.11+): `uv tool install symbola` (or `pipx install symbola`). Not `pip install symbolon`: that PyPI name is another project. 2. Download the pack: `symbola pull emptymalei/powerbi-cli --dest spec`. 3. Read `spec/AGENTS.md` and follow it. Build only from `spec/`: don't look for the original product's source, the registry repository (it holds holdout tests) or other builds. Packs released before the rename say `symbolon `: run `symbola ` instead. This is a product pack: `spec/PRODUCT.md` describes the whole product (its shape, surfaces and flows). Build that product, in the user's stack, with the components below as its core. Don't build a demo page around the components instead. 4. Build each component in its own folder and run its checks as you go, fixing what fails: symbola impl-init impl/auth-profiles --contract spec/components/auth-profiles/versions/1 symbola test spec/components/auth-profiles/versions/1 impl/auth-profiles In Python, define `run(input)` in `impl.py`: it takes and returns a dict, and raises `ValueError` for input the contract rejects. Pin third-party packages with `==` in `requirements.lock`. In another language, set `language = "command"` and `command = [...]` in `symbolon-impl.toml`; the program reads one JSON input per line on stdin and writes `{"output": ...}` per line. A component whose `symbolon.toml` says `driver = "cli"` is a command line: build the real program, set `command` to it, and symbola runs it once per check. 5. When every component passes, run `symbola keygen` once, then for each component `symbola attest spec/components/auth-profiles/versions/1 impl/auth-profiles -o attestations/auth-profiles.json`. On macOS, attest needs Docker running and accepts Python, Node or a static Linux binary (for Go, `GOOS=linux`); `symbola test` runs the same checks without it. You are done when every flow in `spec/PRODUCT.md` works in the product you built and attest reports PASSED for every component. Write open questions and the readings you chose in `NOTES.md`. Every command is described at https://kausalflow.github.io/symbola/cli/. Components: - `auth-profiles`: `spec/components/auth-profiles/versions/1` - `cache-keys`: `spec/components/cache-keys/versions/1` - `cached-reads`: `spec/components/cached-reads/versions/1` - `config-cache`: `spec/components/config-cache/versions/1` - `file-converters`: `spec/components/file-converters/versions/1` - `flatten`: `spec/components/flatten/versions/1` - `scan-batch`: `spec/components/scan-batch/versions/1` - `workspace-entries`: `spec/components/workspace-entries/versions/1` ## Read it online Start with https://symbola.sh/packs/emptymalei/powerbi-cli/pack.md (brief, assumptions, obligations, and links to one file per component under https://files.symbola.sh/packs/emptymalei/powerbi-cli/parts/), or download https://symbola.sh/packs/emptymalei/powerbi-cli/latest.tar.gz. ## Files - [AGENTS.md](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/AGENTS.md) - [BRIEF.md](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/BRIEF.md) - [PRODUCT.md](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/PRODUCT.md) - [assumptions/api-limits.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/assumptions/api-limits.toml) - [assumptions/api-shape.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/assumptions/api-shape.toml) - [assumptions/bearer-token.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/assumptions/bearer-token.toml) - [assumptions/keyring-optional.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/assumptions/keyring-optional.toml) - [assumptions/single-user.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/assumptions/single-user.toml) - [components/auth-profiles/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/examples.jsonl) - [components/auth-profiles/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/_oracle.py) - [components/auth-profiles/versions/1/mutants/bearer_prefix_kept.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/bearer_prefix_kept.py) - [components/auth-profiles/versions/1/mutants/delete_keeps_the_token.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/delete_keeps_the_token.py) - [components/auth-profiles/versions/1/mutants/group_profile_without_token_falls_back.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/group_profile_without_token_falls_back.py) - [components/auth-profiles/versions/1/mutants/list_marks_inverted.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/list_marks_inverted.py) - [components/auth-profiles/versions/1/mutants/new_profile_always_active.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/new_profile_always_active.py) - [components/auth-profiles/versions/1/mutants/unknown_switch_fails.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/mutants/unknown_switch_fails.py) - [components/auth-profiles/versions/1/observe.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/observe.py) - [components/auth-profiles/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/properties.py) - [components/auth-profiles/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/schema.py) - [components/auth-profiles/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/schema/input.json) - [components/auth-profiles/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/schema/output.json) - [components/auth-profiles/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/auth-profiles/versions/1/symbolon.toml) - [components/cache-keys/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/examples.jsonl) - [components/cache-keys/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/mutants/_oracle.py) - [components/cache-keys/versions/1/mutants/filter_not_saved.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/mutants/filter_not_saved.py) - [components/cache-keys/versions/1/mutants/loose_files_are_keys.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/mutants/loose_files_are_keys.py) - [components/cache-keys/versions/1/mutants/user_key_not_slugged.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/mutants/user_key_not_slugged.py) - [components/cache-keys/versions/1/mutants/version_with_fraction.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/mutants/version_with_fraction.py) - [components/cache-keys/versions/1/mutants/versions_oldest_first.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/mutants/versions_oldest_first.py) - [components/cache-keys/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/properties.py) - [components/cache-keys/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/schema.py) - [components/cache-keys/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/schema/input.json) - [components/cache-keys/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/schema/output.json) - [components/cache-keys/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cache-keys/versions/1/symbolon.toml) - [components/cached-reads/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/examples.jsonl) - [components/cached-reads/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/mutants/_oracle.py) - [components/cached-reads/versions/1/mutants/disabled_cache_still_read.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/mutants/disabled_cache_still_read.py) - [components/cached-reads/versions/1/mutants/notice_names_the_folder.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/mutants/notice_names_the_folder.py) - [components/cached-reads/versions/1/mutants/older_version_when_latest_unreadable.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/mutants/older_version_when_latest_unreadable.py) - [components/cached-reads/versions/1/mutants/relative_folder_ignores_default_output_folder.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/mutants/relative_folder_ignores_default_output_folder.py) - [components/cached-reads/versions/1/mutants/use_cache_miss_is_silent.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/mutants/use_cache_miss_is_silent.py) - [components/cached-reads/versions/1/observe.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/observe.py) - [components/cached-reads/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/properties.py) - [components/cached-reads/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/schema.py) - [components/cached-reads/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/schema/input.json) - [components/cached-reads/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/schema/output.json) - [components/cached-reads/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/cached-reads/versions/1/symbolon.toml) - [components/config-cache/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/examples.jsonl) - [components/config-cache/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/_oracle.py) - [components/config-cache/versions/1/mutants/clear_version_without_key_clears_all.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/clear_version_without_key_clears_all.py) - [components/config-cache/versions/1/mutants/cloud_folder_made_local.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/cloud_folder_made_local.py) - [components/config-cache/versions/1/mutants/false_without_warning.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/false_without_warning.py) - [components/config-cache/versions/1/mutants/list_ignores_the_newest_first_order.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/list_ignores_the_newest_first_order.py) - [components/config-cache/versions/1/mutants/missing_bundle_accepted.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/missing_bundle_accepted.py) - [components/config-cache/versions/1/mutants/other_keys_dropped.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/mutants/other_keys_dropped.py) - [components/config-cache/versions/1/observe.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/observe.py) - [components/config-cache/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/properties.py) - [components/config-cache/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/schema.py) - [components/config-cache/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/schema/input.json) - [components/config-cache/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/schema/output.json) - [components/config-cache/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/config-cache/versions/1/symbolon.toml) - [components/file-converters/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/examples.jsonl) - [components/file-converters/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/mutants/_oracle.py) - [components/file-converters/versions/1/mutants/excel_target_with_extension_accepted.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/mutants/excel_target_with_extension_accepted.py) - [components/file-converters/versions/1/mutants/format_convert_checks_the_extension.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/mutants/format_convert_checks_the_extension.py) - [components/file-converters/versions/1/mutants/no_token_needed_for_empty_source.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/mutants/no_token_needed_for_empty_source.py) - [components/file-converters/versions/1/mutants/not_an_object_gives_empty_list.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/mutants/not_an_object_gives_empty_list.py) - [components/file-converters/versions/1/observe.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/observe.py) - [components/file-converters/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/properties.py) - [components/file-converters/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/schema.py) - [components/file-converters/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/schema/input.json) - [components/file-converters/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/schema/output.json) - [components/file-converters/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/file-converters/versions/1/symbolon.toml) - [components/flatten/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/examples.jsonl) - [components/flatten/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/mutants/_oracle.py) - [components/flatten/versions/1/mutants/children_not_prefixed.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/mutants/children_not_prefixed.py) - [components/flatten/versions/1/mutants/empty_sheets_dropped.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/mutants/empty_sheets_dropped.py) - [components/flatten/versions/1/mutants/parent_fields_not_repeated.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/mutants/parent_fields_not_repeated.py) - [components/flatten/versions/1/mutants/report_fields_dropped.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/mutants/report_fields_dropped.py) - [components/flatten/versions/1/mutants/workspace_sheet_gets_a_row_per_child.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/mutants/workspace_sheet_gets_a_row_per_child.py) - [components/flatten/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/properties.py) - [components/flatten/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/schema.py) - [components/flatten/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/schema/input.json) - [components/flatten/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/schema/output.json) - [components/flatten/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/flatten/versions/1/symbolon.toml) - [components/scan-batch/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/examples.jsonl) - [components/scan-batch/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/mutants/_oracle.py) - [components/scan-batch/versions/1/mutants/integers_count_as_booleans.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/mutants/integers_count_as_booleans.py) - [components/scan-batch/versions/1/mutants/interval_may_be_zero.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/mutants/interval_may_be_zero.py) - [components/scan-batch/versions/1/mutants/stops_at_the_first_failure.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/mutants/stops_at_the_first_failure.py) - [components/scan-batch/versions/1/mutants/target_folder_checked_after_flags.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/mutants/target_folder_checked_after_flags.py) - [components/scan-batch/versions/1/observe.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/observe.py) - [components/scan-batch/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/properties.py) - [components/scan-batch/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/schema.py) - [components/scan-batch/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/schema/input.json) - [components/scan-batch/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/schema/output.json) - [components/scan-batch/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/scan-batch/versions/1/symbolon.toml) - [components/workspace-entries/versions/1/examples.jsonl](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/examples.jsonl) - [components/workspace-entries/versions/1/mutants/_oracle.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/mutants/_oracle.py) - [components/workspace-entries/versions/1/mutants/bad_entries_skipped.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/mutants/bad_entries_skipped.py) - [components/workspace-entries/versions/1/mutants/file_stem_without_the_id.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/mutants/file_stem_without_the_id.py) - [components/workspace-entries/versions/1/mutants/label_is_the_id.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/mutants/label_is_the_id.py) - [components/workspace-entries/versions/1/mutants/single_string_accepted.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/mutants/single_string_accepted.py) - [components/workspace-entries/versions/1/mutants/slug_with_underscores.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/mutants/slug_with_underscores.py) - [components/workspace-entries/versions/1/properties.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/properties.py) - [components/workspace-entries/versions/1/schema.py](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/schema.py) - [components/workspace-entries/versions/1/schema/input.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/schema/input.json) - [components/workspace-entries/versions/1/schema/output.json](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/schema/output.json) - [components/workspace-entries/versions/1/symbolon.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/components/workspace-entries/versions/1/symbolon.toml) - [obligations.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/obligations.toml) - [symbolon-pack.toml](https://files.symbola.sh/packs/emptymalei/powerbi-cli/files/symbolon-pack.toml)