# v0.36.0

- Update `ct az resource list` to include `properties` field
- Update `ct tf reflow` to have `--full` (guards principal stuff) and `--keep-trash` (deletes obsolte files otherwise) flags
- Add `ct az cognitive-services account list` command
- Add `ct az cognitive-services account deployment list` command
- Update `copy_azurerm_backend_menu` to support ctrl+r reloading
- Update `ct tf reflow` to avoid deleting files that are comment-only
- Update `ct tf reflow` to better co-locate `import` and `moved` blocks with their `to` origin
- Update `ct tf reflow` to add `--single file [filename]` behaviour
- Update `ct tf reflow` to fix whitespace idempotency issue
- Update `ct tf reflow` to bail if duplicate block labels are detected
- Better diagnostic logging for `ct rest` and `ct az pim activate entra`
- Add `ct az ad role definition|assignment browse|list` commands
- Update `hicory-resolver` dependency
- Update `rustls-webpki` dependency
- Update `ct tf source add-imports` to have better subnet support
- Add `ct az role operation browse|list` command
- Add `ct az ad user show {}` command
- Add `ct az ad oauth2-permission-grant list|create|update|browse` command
- Update `ct az devops repo list` command to make `--project {}` optional 
- Revamp REST behaviour to no longer spawn another process

# v0.35.1

- Fix ambiguous type causing compile issues

# v0.35.0

- Change `ct az devops agent pool list` to hide `is_hosted` pools unless `--all` specified
- Revamp `ct pick` command to have `ct pick stdin` and `ct pick fs` subcommands
    - `--many` replaced with `--single` as many is now default
    - Changed default query engine to Liquid
- Add `ct az devops license-entitlement user summary` command
- Move `ct az group` to `ct az resource-group` with `ct az rg` alias
- Add `--tenant {alias or id or 'default'}` optional flag to many commands, e.g., `ct az resource-group list --tenant 123`, `ct az subsription list --tenant 321`
- Flatten and remove all prelude modules
- Add tenant id everywhere
- Remove `ResourceGroup::subscription_id` field
- Add `ResourceGroup::subscription_name` field
- Add `ResourceGroup::tenant_id` field
- Rename Entra user files and types
    - `UserListRequest` -> `EntraUserListRequest`
    - `fetch_all_users` -> `fetch_all_entra_users`
- Disable logging colours when not in terminal (when being piped)
- Add other_mails property to `EntraUser`
- Fix concurrent write to timestamp text file for command caching
- Add `ct az tenant login|list|discover|alias|add|sho|forget|help` commands
- Add `ct az public-ip list|show` command
- Add `ct az application-gateway list|show|show-backend-health` command
- Add `--headers` flag to `ct rest` command
- Consolidate rest stuff in `cloud_terrastodon_credentials` crate
- Rename `LocationName` to `AzureLocationName`
- Rename `AccessToken` to `AzureAccessToken`
- Add `ct outage investigate` command
- Add `ct az network-interface list|show` command
- Add `ct az private-endpoint list|show` command
- Add `ct az app-service list|show` command
- Add `ct az sp show` command
- Add `ct az policy set-definition list|browse|show` command
- Add `ct az policy assignment list|browse|show` command
- Add `ct az policy definition show` command
- Add `ct az policy definition list --name {} --param-name {}` args
- Add `ct az policy assignment list --name {}` arg
- Add `ct az policy set-definition list --name {}` arg
- Add tenant id field to azure batch request objects
- Add better caller tracking for batch request async invoke fns
- Add better caller tracking for command with validation async run fns

# v0.34.0

- Add `ct az role assignment create` command
- Add `ct az find <query>` command to search resources
- Add `ct az resource list|browse|show` commands
- Add `ct nslookup <query>` command
- Add `ct az role definition find <action>` command
    - Example `ct az role definition find Microsoft.ContainerInstance/containerGroups/containers/exec/action`
- Migrate to stable rust, nightly is no longer required :D
- Fix `AzureDevOpsAgentPoolArgument::matches` implementation correctness
- Add new Azure regions and Tenant-level properties

# v0.33.0

- Rename `fetch_azure_devops_license_entitlements` to `fetch_azure_devops_user_license_entitlements`
- Rename `update_azure_devops_license_entitlement` to `update_azure_devops_user_license_entitlement`
- Rename `AzureDevOpsLicenseEntitlement` to `AzureDevOpsUserLicenseEntitlement`
- Rework Azure DevOps license entitlement CLI layout:
  - Old: `ct az devops user update` (and TUI variant) and `ct az devops license-entitlement list`
  - New:
    - `ct az devops license-entitlement user list`
    - `ct az devops license-entitlement user update`
    - `ct az devops license-entitlement user update-tui`
    - `ct az devops license-entitlement user show --user-devops-id {}`
    - `ct az devops license-entitlement user show --user-email {}`
    - `ct az devops license-entitlement group list`
- Rename `AzureDevOpsLicenseKind` to `AzureDevOpsLicenseType`, add stronger typing
- Fix Microsoft graph helper failing to deserialize error bodies
- Add cache key support to Microsoft graph helper
- Add `ct az devops license-entitlement user revoke --user-devops-id {}`
- Add `ct az devops license-entitlement user revoke --user-email {}`
- Add `ct az ad group member add --group-id {} --member-id {}` and supporting aspects
- Add `ct az ad group member remove --group-id {} --member-id {}` and supporting aspects
- Change `--log-file` to append instead of truncate
- Add `--log-level` alias for `--log-filter`
- Rename `User` to `EntraUser`
- Rename `UserId` to `EntraUserId`
- Rename `Group` to `EntraGroup`
- Rename `GroupId` to `EntraGroupId`
- Rename `ServicePrincipal` to `EntraServicePrincipal`
- Rename `ServicePrincipalId` to `EntraServicePrincipalId`
- Add `ct az subscription list` command
- Add `tags` field to `Subscription` type
- Add `ct terraform show plan.json|apply.tfplan` to show names for the object IDs being changed in `azuread_group` members and owners
- Add `Get-Clipboard | ct extract-uuid -` command to extract UUIDs from text
- Add missing `pub` on `EntraGroup.description`
- Add missing fields to `EntraGroup`
- Add `VirtualMachine` and supporting types
- Add `ct az vm list` command
- Add `ct az vm browse` command
- Add `fetch_azure_devops_agent_pools` fn
- Add `ct az devops agent pool list` command
- Add `ct az devops agent pool entitlement list` command
- Add `ct az devops agent pool summary` command
- Change `ct az devops ...` commands to take `--project {}` instead of it being a positional parameter
- Remove `AzureDevOpsProjectName::new` in favour of `AzureDevOpsProjectName::try_new` to ensure name is validated
- Relax type bounds on `trait CacheInvalidatableIntoFuture`
- Revamp `CacheInvalidatableIntoFuture` trait

# v0.32.0

- Alias `devops` as child of `ct az` command
- Add `ct az devops project list` command
- Rename `get_azure_devops_access_token` to `fetch_azure_devops_personal_access_token`
- Rename `get_azure_devops_pat` to `get_azure_devops_personal_access_token_from_credential_manager`
- Add `ct az devops agent package show-newest` command
- Rename `fetch_azure_devops_groups` to `fetch_azure_devops_groups_for_project`
- Make role definition browse command reloadable
- Fix entra pim role assignments not using cache
- Cache `az ad signed-in-user show`
- Add `--log-filter {}` global cli arg
- Update `--log-file` tracing config to include timestamp and exclude file and line
- Update `ct az devops audit` to include test plan license usage analysis
- Update fetcher fn cache keys to fix uniqueness
- Add `ct az ad user list` and `ct az ad user browse` commands
- Add `ct az ad sp list` and `ct az ad sp browse` commands
- Add reload support to PIM activation dialogs
- Add WIP `ct tf apply` command which identifies required and missing permissions from proposed changes in Terraform plans
- Add azure audit for resources which have tag keys that the parent have but where the values do not match the parent
- Make request structs fields pub
- Add `ct az devops user update` command
- Add `ct az devops user update tui` command

# v0.31.0

- Add `ct tf reflow` command to rewrite directories containing HCL in an opinionated way.
- Add `ct az vm publisher list|browse` command
- Add `ct az vm publisher offer list` command
- Add `ct az vm publisher offer sku list` command
- Add `ct az vm publisher offer sku version list` command
- PickerTui now selects first row on text change
- Change `--json` global arg to now be `--log-file FILE`
- Add `--mode lines` and `--mode auto` to `ct pick` command
- Change `PickerTui` to no longer be generic over `<T>`, instead the `pick` and `pick_many` fns own the generic
- Fix `ct pick` using stdout instead of stderr when restoring from Ratatui
- Fix `ct pick` default query not being valid after changing default engine to `jmes-path`
- Add `ct pick --engine liquid` for using [liquid](https://github.com/cobalt-org/liquid-rust)
- Add `fn pick_*_reloadable` to `PickerTui` to enable easy ctrl+r support for refreshing the list of choices
- Add `CacheKey` struct to replace `CacheBehaviour` enum
- Remove `CommandBuilder::use_cache_dir` in favor of `CommandBuilder::use_cache_behaviour`
- Add `CacheKey::new` to default to `Duration::MAX`
- Replace `CommandBuilder::use_cache_behaviour` with `CommandBuilder::use_cache` and `CommandBuilder::cache`
- Introduce `CacheableCommand` trait, updating the response of most `fetch` functions

# v0.30.0

- Add `LocationName::BelgiumCentral`, see [Microsoft's LinkedIn post](https://www.linkedin.com/posts/microsoft_big-news-the-belgian-microsoft-cloud-region-activity)
- Add missing `GovernanceRoleAssignmentStatus::Accepted` variant
- Remove extraneous "seconds" suffix after humantime display in `ParallelFallibleWorkQueue::join` logging
- Add `fetch_all_tenant_licenses`
- Fix `TFProviderVersionConstraintClause` parsing to trim whitespace around operator
- Make `PickerTui#pick_inner` public
- Add CLI command: `cloud_terrastodon pick`
- Add CLI command: `cloud_terrastodon azure role definition list` with `--actions` and `--data-actions` filter, sorted by principal-of-least-privilege
- Add CLI command: `cloud_terrastodon azure role definition browse`
- Add CLI command: `cloud_terrastodon azure role assignment list`
- Add CLI command: `cloud_terrastodon azure role assignment browse`
- Add `ServiceGroup` and supporting types
- Add `RoleAssignmentId::ServiceGroupScoped` variant
- Rework `CommandBuilder::file_arg` to allow for generic path rewriting during canonicalization
- Fix `PickerTui` [performance problems using stderr](https://blog.orhun.dev/stdout-vs-stderr/)

# v0.29.0

- Rename `fetch_groups` to `fetch_all_groups`
- Add `--json` flag to write logs to a `.jsonl` file
- Add debug warning when picker tui elements contain `\t`
- Fix choice alignment in "copy azurerm backend" action
- Introduce compute sku and vm image structs and helper fetcher functions
- Fix picker TUI multiline support
- Fix picker TUI ctrl+c support
- Make app exit happily on ctrl+c or esc on main menu
- Add `azure audit` and `azure-dev-ops audit` commands
- Remove dependency on `validator` crate in favour of just using `eyre` for context
- Add `create import block for role assignment` action
- Add `AzureDevOpsLicenseEntitlementLicense` variant for `Msdn-Eligible`, add Other variant
- Revamp `cloud_terrastodon_command` tracing
- Revamp internal CLI structure
    - add `cloud_terrastodon.exe az group list`
    - add `cloud_terrastodon.exe az group browse`
    - add `cloud_terrastodon.exe az policy definition list`
    - add `cloud_terrastodon.exe az policy definition browse`
    - add `cloud_terrastodon.exe az tag for-cleanup`
- Add ctrl+backspace support to picker tui
    - Existing textarea widget has alt+backspace hotkey but I prefer ctrl+backspace .-.
- Add `cloud_terrastodon.exe az pim activate` commands
- Rename `HCL` to `Hcl` in structs and stuff
- `CodeReference` changed to introduce new `LocationWithinFile` struct
- Refactored import and data block stuff
- Introduce "cloud_terrastodon terraform src add-imports" to generate import blocks from source code

# v0.28.0

- Switch from using `fzf` to `PickerTui` everywhere
- Update `PickerTui` return types for `pick_one` and `pick_many` to return `PickResult<T>`
- Add `PickerTui::from` for better type inference
- Remove `fzf` module containing `pick` and `pick_many` in favour of `PickerTui`

# v0.27.0

- Added `KeyVaultSecretId` type
- Added `KeyVaultSecretVersionId` type
- Update `KeyVaultSecret` to use new `KeyVaultSecretId` type
- Impl `Ord` for `KeyVaultId`
- Added browse storage accounts action
- Add `GovernanceRoleAssignmentMemberType::Direct` variant
- Add `PrincipalCollection` type and change `fetch_all_principals` to return it
- Add `UnifiedRoleDefinition` and `UnifiedRoleAssignment` types for Entra RBAC
- Move `AccessToken` type from `cloud_terrastodon_credentials` to `cloud_terrastodon_azure_types`
- Add jwt decoding to `cloud_terrastodon_credentials` (TODO: fix fn return instead of just printing)
- Published `cloud_terrastodon` crate to re-export other `cloud_terrastodon_*` crates

# v0.26.0

- Add `fetch_all_key_vaults` fn
- Add `KeyVault` and `KeyVaultId` and `KeyVaultProperties` and `KeyVaultName` types
- Remove storage account duplicate properties already exposed by the id
- Rename PIM role assignment stuff to `GovernanceRoleAssignment`

# v0.25.0

- Revert virtual network address space back to `Ipv4Network`
- Revamp fetch_all_policy_assignments to use resource graph

# v0.24.0

- Fix command cache busting
- Add `AzureDevOpsDefaultOrganizationUrlTui` to `cloud_terrastodon_azure_devops`
- Add `MessageBoxTui` to `cloud_terrastodon_user_input`
- Add `cloud_terrastodon_credentials` crate for exploration into using our own REST client instead of `az rest` and `az devops invoke` due to auth being annoying
- Fix route table deserialization using new `AddressPrefix` type

# v0.23.0

- Tracing now outputs to stderr
- Add `impl FromStr for StorageAccountId`
- Add `AzureDevOpsOrganizationUrl` parameter to azure devops functions

# v0.22.0

- Add `PickerTui` to `cloud_terrastodon_user_input`

# v0.21.0

- Fix conditional access policy struct where included/excluded applications aren't always UUIDs

# v0.20.0

- Add `fetch_azure_devops_user_license_entitlements()` function to retrieve Azure DevOps user entitlements
- Add "Invalid combination of arguments" to list of fixable errors for GenerateConfigOutHelper
- Add `get_azure_devops_user_onboarding_statuses(user_emails)` function
- Reduce log level for fetch helpers to DEBUG from INFO
- Updated dependencies via `cargo update`

# v0.19.0

- `cloud_terrastodon clean` no longer shows warnings for directories not present
- Add `--debug` argument always for azure CLI commands

# v0.18.0

- Add stronger types for azure devops service endpoint
- Add cache bust when failed to find default azure devops project or organization
- Add automatic no_space conversion for command cache keys

# v0.17.0

- Add conditional access policy stuff
- Introduce variants for RoleDefinitionId
- Add virtual network peering and name types

# v0.16.1

- Fix subnet properties route table reference using `RouteTable`, now is `RouteTableId`

# v0.16.0

- Fix subnet types to not use optionals
- Fix subnet `addressPrefixes` and `addressPrefix` variant deserializing
- Fix subnet id constructors and serialization
- Remove interior mutability from Name types to prevent subverting validation after construction
- Make tags deserialize into `HashMap` instead of `Optional<HashMap>`
- Fix subnet properties route table reference to use RouteTableId instead of String

# v0.15.0

- Add `cloud_terrastodon terraform audit --recursive` command
- Add virtual network and subnetwork and route table types

# v0.14.0

- Add azure devops groups and teams and membership helpers for each
- Add `browse azure devops projects` command
- Add `browse azure devops teams` command

# v0.13.0

- Change `Subscription { name: String }` to `Subscription { name: SubscriptionName }`
- Change `ResourceGroup { name: String }` to `ResourceGroup { name: ResourceGroupName }`
- Add `ScopeImplKind::StorageAccount` support in `name_lookup_helper::fetch_names_for`

# v0.12.0

- Fix trait bounds on `ResourceGroupId::try_new` to allow passing `&str`
- Fix trait bounds on `StorageAccountId::try_new` to allow passing `&str`
- Fix trait bounds on `SubscriptionId::try_new` to allow passing `&str`
- Added `impl TryFrom<&str> for ResourceGroupName`
- Added `impl TryFrom<&str> for StorageAccountName`
- Added `impl TryFrom<&str> for SubscriptionName`
- Added `impl TryFrom<&str> for StorageAccountBlobContainerName`

# v0.11.0

- Impl `Arbitrary` for ResourceGroupId
- Impl `Arbitrary` for StorageAccountId
- Add `StorageAccountId::new` and `StorageAccountId::try_new`
- Add `ResourceGroupId::try_new`
- Add `SubscriptionId::try_new`

# v0.10.0

- Rename `HasScope::scope(&self)` to `AsScope::as_scope(&self)`
- Rename `Scope::as_scope(&self)` to `Scope::as_scope_impl(&self)`
- Change `Resource::id` from `CompactString` to `ScopeImpl`
- Change `RoleAssignment::scope` from `CompactString` to `ScopeImpl`
- Change `ScopeImpl::try_from_expanded` to return `Result<Self, Infallible>`
- Add `impl<T> From<T> for ScopeImpl where T: AsRef<str>`
- Add `fetch_storage_account_blob_container_names(id: &StorageAccountId) -> HashSet<StorageAccountBlobContainerName>`

# v0.9.0

- The Great Big ID Rework - instead of storing simple strings to the resource, I fully parse the ID into its components.
- Fix policy import builder
- Fix name sanitization when reflowing Terraform workspaces
- Truncate command output when displaying errors, only shows first and last 500 lines

# v0.8.0

- Remove `_core` suffix from crates
- Separate resoure types to separate crate to maximize cache hits
- Flatten repository structure
- Add `ct terraform import` command
- Published `cloud_terrastodon_*` crates to crates.io

# v0.7.1

- Fix invalid assumption from role eligibility schedule ID parsing, should fix ct pim activate for azurerm

# v0.7.0

- Progress on cloud_terrastodon dump-everything to export devops projects and resource groups
- static analysis of terraform required provider version

# v0.6.0

- Add oauth2 scope management
- Fix errors when used with account in tenant with no management groups
- Add query option to fzfargs
- Use mutex to prevent multiple sign-ins when auth failed in concurrent requests
- Add bulk user id lookup

# v0.5.0

- Add security group and role assignment imports to `write-all-imports`
- Add interactive option for running `write-all-imports`
- Fix deduplication logic when writing tf files
- Fix unknown scopes getting interpreted as my test type
- Fix group imports dynamic_membership conflicting with generated member list

# v0.4.0

- Fix PIM role activation happening twice when two role assignments present for the same role
- Add wizard for generating import blocks
- Add `tf plan` action
- Remove default attributes when processing generated HCL

# v0.3.0

- Fix policy remediation not providing scope leading to 0 resources being remediated
- Add `cloud_terrastodon copy-results ./whatever` command

# v0.2.0

- Fix terminal colours in default terminal opened when double clicking the exe
    - https://stackoverflow.com/questions/78741673/colors-not-working-on-default-terminal-for-release-rust-exe/78741674#78741674
- Add app icon
- Clean up non-interactive usage scenarios (see: `cloud_terrastodon --help`)
- Linux (Ubuntu) working
- First GitHub release

# v0.1.1

- Fix "Justification:" prompt not showing when activating PIM roles