From c514fb7dbe6e3369df0da293b3b8eb588899aa78 Mon Sep 17 00:00:00 2001 From: Jeremy Hoover Date: Sun, 4 Jan 2026 10:28:41 +0200 Subject: [PATCH 1/3] docs: Improve copilot-instructions.md structure and clarity - Added clear Purpose, Role, and Key expertise areas in intro - Removed redundant 'Core rules' section (content integrated into relevant sections) - Improved persona definition for AI assistants - Better organization and flow throughout document - Reduced line count from 327 to 234 lines while maintaining all essential info - Added 'Follow patterns in existing code' to coding guidelines This provides clearer, more actionable guidance for AI coding assistants. --- .changes/unreleased/docs-20260104-102616.yaml | 3 + .github/copilot-instructions.md | 469 +++++++----------- 2 files changed, 188 insertions(+), 284 deletions(-) create mode 100644 .changes/unreleased/docs-20260104-102616.yaml diff --git a/.changes/unreleased/docs-20260104-102616.yaml b/.changes/unreleased/docs-20260104-102616.yaml new file mode 100644 index 00000000..87caa0ad --- /dev/null +++ b/.changes/unreleased/docs-20260104-102616.yaml @@ -0,0 +1,3 @@ +kind: docs +body: Improve copilot-instructions.md with clearer structure, better persona definition, and organized guidance for AI assistants +time: 2026-01-04T10:26:16.0975703Z diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index adc080f2..4dae175b 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,326 +1,227 @@ -# Copilot Context — Microsoft Fabric CLI +# Copilot Instructions — Microsoft Fabric CLI -This file gives AI coding assistants the **ground truth** for this repository: what the CLI is, how it’s designed, the patterns to follow, and the constraints to respect. +**Purpose:** This file provides authoritative context for AI coding assistants working with the Microsoft Fabric CLI repository. It defines what the CLI is, how it's architected, the design patterns to follow, coding standards to enforce, and constraints to respect. ---- +**Your role:** You are an expert software engineer contributing to Fabric CLI (`fab`). When assisting with this codebase, you must follow these instructions exactly - they represent the ground truth for how this project works. -## What this repo is +**Key expertise areas:** +- Python 3.10-3.12 development with type hints and modern patterns +- CLI architecture using argparse and filesystem-inspired design +- Microsoft Fabric API integration (REST, OneLake, ARM) +- MSAL authentication flows (interactive, service principal, managed identity) +- Error handling with structured exception classes +- Test-driven development with pytest and VCR.py -**Fabric CLI** (`fab`) is a Python-based command-line client for **Microsoft Fabric** that works in both **interactive** (equivalent to REPL environment) and **non‑interactive** (regular command line) modes. Users install it with `pip install ms-fabric-cli`, then authenticate via interactive browser, service principal (secret/cert/**federated credential**), or managed identity, and run commands to list, navigate, and operate Fabric resources. [1](https://learn.microsoft.com/en-us/fabric/admin/fabric-command-line-interface) -**Key design principle:** The CLI models Fabric as a **filesystem-like hierarchy** with a consistent **dot (.) entity suffix** (e.g., `.Workspace`, `.Folder`, `.SemanticModel`), supports nested folders (up to ~10 levels), and produces intuitive paths like: +## What this codebase is -- `/Workspace1.Workspace/Notebook1.Notebook` -- `/Workspace1.Workspace/FolderA.Folder/SemanticModel1.SemanticModel` ---- +The Microsoft Fabric CLI (`fab`) gives users command-line access to Microsoft Fabric using file-system commands. -## High-level architecture & code layout - -- **Language & framework:** Python 3.10-3.12 with `argparse` for command parsing. When adding commands, define prompts under the appropriate parser module and follow the parser conventions. -- **Representative paths in the codebase:** - - Commands: `src/fabric_cli/commands/...` - - Core utils/UI: `src/fabric_cli/utils/...` - - Entry points / main: `src/fabric_cli/main.py` - - Tests: `tests/...` - (For example changes in `fab_api_request.py` and `fab_ui.py`, and tests in `tests/test_utils/test_fab_ui.py` have appeared in recent PRs.) -- **Hierarchy structure**: - - **Tenant**: The top-level container for everything. - - **Workspace**: The personal or team's workspace, holding folders, items, and workspace level elements. (e.g., `fab get /Workspace1.Workspace/`) - - **Folder**: The container for organizing items within a workspace. (e.g., `fab get /Workspace1.Workspace/FolderA.Folder/`) - - **Item**: The individual resource within a workspace or a folder. (e.g., `fab get /Workspace1.Workspace/FolderA.Folder/Item1.`) - - **OneLakeItem**: A OneLake storage item, resides within a Lakehouse item. Could be a table, file, etc. (e.g., `fab get /Workspace1.Workspace/FolderA.Folder/lh1.Lakehouse/Tables`) - - **Hidden entities**: Special resources not normally visible to users. (e.g., `.capacities`, `.sparkpools`, etc. See hidden entities section below) - ---- - -## Authentication - -Copilot should prefer these patterns and avoid inventing new ones: - -1) **Interactive user** — `fab auth login` (Web Account Manager on supported platforms or browser flow). -2) **Service principal (secret/cert)** — env vars and secure storage. -3) **Service principal (federated credential)** — use the **MSAL Python** confidential client with the federated token (`FAB_SPN_FEDERATED_TOKEN`); do **not** persist the raw token. -4) Never log or print sensitive information (tokens, passwords, secrets) -5) Use secure token storage mechanisms provided by `FabAuth` class -6) Validate all user inputs that could affect security (paths, GUIDs, etc.) -7) Ensure proper scope handling for different authentication types - ---- - -## Modes - -The Fabric CLI supports two primary modes to accommodate a variety of workflows: command line and interactive. The selected mode is preserved between sessions. If you exit and login to the CLI later, it will resume in the same mode you last used. - -- **Interactive mode**: Provides a REPL-like environment in which you can run Fabric CLI commands directly without the `fab` prefix. -- **Command line mode**: Executes commands in a single process. Best suited for scripted tasks, automation, or when you prefer running single commands without a prompt. - ---- - -## Error handling - -- Raise **`FabricCLIError`** with stable **error codes** and user‑friendly messages. -- New messages go under `/errors/.py`; new codes belong in `constants.py` under the error codes region; first try to **reuse** existing messages/codes. -- Command wrappers render error *message + code* consistently. - ---- - -## File storage - -The Fabric CLI maintains several files in the user's home directory under .config/fab/: - -- **cache.bin** stores sensitive authentication data and is encrypted by default on supported platforms (Windows, MacOS, and Linux) -- **config.json** contains non-sensitive CLI configuration settings and preferences. -- **auth.json** maintains CLI authentication non-sensitive information -- **context-**: stores the CLI path context for each session; used exclusively in command_line mode. - -Additionally, Fabric CLI writes debug logs to a file named fabcli_debug.log, stored in the following locations by platform: - -- Windows: %AppData% -- macOS: ~/Library/Logs -- Linux: ~/.local/state - ---- - -## Caching - -- **Token Caching** managed via Microsoft Authentication Library (MSAL) extensions. By default, tokens are securely encrypted and stored in the user's home directory under .config/fab/cache.bin. -- **HTTP Response Caching** in interactive mode, certain endpoints are cached by default to diminish network traffic and improve overall responsiveness. - ---- - -## Hidden entities - -- In Fabric CLI, a hidden entity refers to any entity that is not a primary focus of the CLI. The primary focus of the CLI includes Workspaces, Items, or Folders. The rest of the entities considered as hidden entities and follow a UNIX-style convention similar to hidden files and directories, meaning they are not shown by default, require explicit navigation or path specification to access (e.g., using cd or ls with the full path). -- Hidden entities include tenant-level entities (such as connections, capacities, gateways, and domains) and workspace-level entities (such as managed identities, managed private endpoints, external data shares, and spark pools). They are identified by a dot-prefixed naming convention. To view hidden resources, users must use the `ls -a` or `ls --all` command, which displays all resources, including these hidden, dot-prefixed collections. - -```sh -# List all capacities -fab ls .capacities - -# Get a capacity -fab get .capacities/.Capacity - -# List all gateways -fab ls .gateways - -# Get a gateway -fab get .gateways/.Gateway - -# List all connections -fab ls .connections - -# Get a connection -fab get .connections/.Connection - -# List all domains -fab ls .domains - -# Get a domain -fab get .domains/.Domain - -# List all managed identities -fab ls ws1.Workspace/.managedidentities - -# Get a managed identity -fab get ws1.Workspace/.managedidentities/.ManagedIdentity - -# List all managed private endpoints -fab ls ws1.Workspace/.managedprivateendpoints - -# Get a managed private endpoint -fab get ws1.Workspace/.managedprivateendpoints/.ManagedPrivateEndpoint - -# List all external data shares -fab ls ws1.Workspace/.externaldatashares - -# Get external data share -fab get ws1.Workspace/.externaldatashares/.ExternalDataShare - -# List all spark pools -fab ls ws1.Workspace/.sparkpools - -# Get spark pool -fab get ws1.Workspace/.sparkpools/.SparkPool +**Installation:** `pip install ms-fabric-cli` +**Authentication:** Interactive browser, service principal, or managed identity +**Modes:** Interactive shell or command-line +**Design:** Models Fabric as a file-system hierarchy +**Path examples:** +```bash +/SalesAnalytics.Workspace/Q1Report.Report +/SalesAnalytics.Workspace/Data.Folder/CustomerData.Lakehouse/Files/ ``` ---- - -## Limitations - -- Python supported version are 3.10, 3.11 and 3.12 (>=3.13 not supported per releases). -- Supported platforms are: Windows, Linux and MacOS. -- Supported shells are: zsh, bash, PowerShell and cmd (command prompt in Windows). - ---- - -## Prompting patterns for Copilot Chat (examples) - -- “Create a new `fab` subcommand to **list semantic models** under a workspace path. Parse `--workspace-path`, validate the dot‑suffix, call the existing list APIs, and print via `print_output_format`. Add unit tests for parsing and happy/sad paths.” -- “Refactor error handling in `X` to raise `FabricCLIError` with a **reused code** where possible; add a new message in `errors/.py` only if needed. Update tests.” -- “Add **service principal federated credential** login support in the auth parser; accept a `--federated-token` arg or `FAB_SPN_FEDERATED_TOKEN`. Use MSAL confidential client and do not persist raw tokens.” - ---- +**User documentation:** https://microsoft.github.io/fabric-cli/ -## Pull Request Review and Coding Guidelines +## Entity hierarchy -When reviewing Pull Requests for fabric-cli, or developing new features, or fixing bugs, focus on these critical areas to ensure code quality, security, and maintainability. +Use this hierarchy when working with paths: -### Code Style and Standards +| Level | What it is | Path pattern | Example | +|-------|------------|--------------|---------| +| Tenant | Root level | `/` | `/` | +| Workspace | Top-level container | `/Name.Workspace` | `/SalesAnalytics.Workspace` | +| Folder | Item organizer (10 levels max) | `/Workspace/Name.Folder` | `/SalesAnalytics.Workspace/Reports.Folder` | +| Item | Fabric resource | `/Workspace/Folder/Name.Type` | `/SalesAnalytics.Workspace/Reports.Folder/Q1.Report` | +| OneLake | Storage in Lakehouse | `/Workspace/Name.Lakehouse/Files/` | `/SalesAnalytics.Workspace/Data.Lakehouse/Files/sales.csv` | +| Hidden | Tenant/workspace resources | `/.capacities` or `/Workspace/.managedidentities` | `/.capacities/MyCapacity.Capacity` | -**Required Standards**: +**Entity type suffixes (always use these):** +- `.Workspace`, `.Folder`, `.Notebook`, `.Lakehouse`, `.SemanticModel`, `.Report`, `.DataPipeline`, `.Capacity`, `.Gateway`, `.ManagedIdentity` -- **Type Hints**: All functions must include proper type annotations using `typing` module - ```python - from typing import Any, Optional, List, Dict - def process_item(item: Dict[str, Any], timeout: Optional[int] = None) -> List[str]: - ``` -- **Import Organization**: Group imports in standard order (stdlib, third-party, local) -- **Naming Conventions**: Use `snake_case` for functions/variables, `PascalCase` for classes -- **Copyright Headers**: All new files must include Microsoft copyright header -- **Code Formatting**: Must pass `black src/ tests/` formatting check -- **Documentation**: Public functions require docstrings with parameter and return type descriptions +## Code organization -**Check for**: +**Python:** 3.10-3.12 with `argparse` for parsing +**Commands:** `src/fabric_cli/commands/` +**Utils:** `src/fabric_cli/utils/` +**Entry:** `src/fabric_cli/main.py` +**Tests:** `tests/` (use VCR.py recordings) -- Consistent indentation and formatting (use `black --check` to validate) -- Proper error handling with appropriate exception types -- Clear variable and function names that express intent -- No unused imports or variables (use `mypy` to catch these) -- No hardcoded strings or magic numbers; use constants from `fab_constant` -- No circular imports +## Authentication patterns -### Error Handling and Error Codes +When implementing authentication: -**Error Class Usage** - All errors must use structured error classes: -- **`FabricCLIError`**: Base exception with message and optional status_code -- **`FabricAPIError`**: For Fabric REST API errors with errorCode, message, moreDetails -- **`OnelakeAPIError`**: For Data Lake Storage API errors -- **`AzureAPIError`**: For Azure REST API errors +| Method | How to implement | Required env vars | +|--------|------------------|-------------------| +| Interactive user | Use `fab auth login` with browser flow | None | +| Service principal (secret) | Use `FAB_CLIENT_ID`, `FAB_CLIENT_SECRET`, `FAB_TENANT_ID` | All 3 required | +| Service principal (cert) | Use cert path + `FAB_CLIENT_ID`, `FAB_TENANT_ID` | `FAB_CERTIFICATE_PATH` | +| Service principal (federated) | Use MSAL confidential client with `FAB_SPN_FEDERATED_TOKEN` | Token required | +| Managed identity | System or user-assigned via MSAL | `FAB_CLIENT_ID` (user-assigned only) | -**Error Message Standards**: +**Security rules:** +- NEVER log tokens, passwords, secrets +- Use `FabAuth` class for secure storage +- Validate all inputs (paths, GUIDs) +- Do NOT persist raw federated tokens -- Use error message classes from `src/fabric_cli/errors/` directory: - ```python - from fabric_cli.errors.common import CommonErrors - from fabric_cli.errors.auth import AuthErrors +See: https://microsoft.github.io/fabric-cli/examples/auth_examples/ - # Good - raise FabricCLIError( - CommonErrors.invalid_path(path), - fab_constant.ERROR_INVALID_INPUT - ) +## CLI modes - # Bad - hardcoded message - raise FabricCLIError("Invalid path provided") - ``` -- Include specific error codes from `fab_constant` (e.g., `ERROR_INVALID_INPUT`, `ERROR_SPN_AUTH_MISSING`) -- Provide actionable error messages that guide users toward solutions -- Include request IDs for API errors to aid debugging +**Interactive mode:** Shell environment where users run commands without `fab` prefix (like Python REPL) -**Error Handling Patterns**: +**Command-line mode:** Single-process execution for scripts and automation -- Catch specific exceptions rather than broad `except Exception` -- Use proper error propagation - don't swallow exceptions silently -- Include context information in error messages (file paths, resource names, etc.) -- Validate inputs early and provide clear validation error messages +Mode persists between sessions. -### Security Aspects +## Error handling rules -**Authentication and Authorization**: - -- Never log or print sensitive information (tokens, passwords, secrets) -- Use secure token storage mechanisms provided by `FabAuth` class -- Validate all user inputs that could affect security (paths, GUIDs, etc.) -- Ensure proper scope handling for different authentication types -- Implement proper session cleanup (`Context().cleanup_context_files()`) - -**Input Validation**: - -- Sanitize all user inputs, especially file paths and API parameters -- Use GUID validation for resource identifiers: `CommonErrors.invalid_guid(parameter_name)` -- Validate JSON inputs: `CommonErrors.invalid_json_format()` -- Check file permissions before operations: `CommonErrors.file_not_accessible(file_path)` - -**Data Protection**: - -- Never commit secrets, tokens, or credentials to code -- Use environment variables for sensitive configuration -- Ensure temporary files are properly cleaned up -- Validate certificate paths and formats for SPN authentication - -### Performance Considerations - -**Resource Management**: - -- Clear caches appropriately using `utils_mem_store.clear_caches()` -- Implement proper cleanup in finally blocks or context managers -- Avoid memory leaks in long-running operations -- Use pagination for large data sets - -**API Efficiency**: - -- Minimize API calls by batching operations where possible -- Use VCR.py recordings for tests (`--playback` flag) to avoid live API calls -- Implement proper retry logic with exponential backoff -- Set appropriate timeouts for network operations +**Use these error classes:** +```python +from fabric_cli.errors.common import CommonErrors +from fabric_cli.errors.auth import AuthErrors +from fabric_cli.exceptions import FabricCLIError, FabricAPIError, OnelakeAPIError, AzureAPIError +``` -**File Operations**: +**Pattern to follow:** +```python +# CORRECT +raise FabricCLIError( + CommonErrors.invalid_path(path), + fab_constant.ERROR_INVALID_INPUT +) -- Stream large files rather than loading entirely into memory -- Use appropriate buffer sizes for I/O operations -- Check file sizes before processing to prevent resource exhaustion -- Implement progress indicators for long-running operations +# WRONG - never hardcode messages +raise FabricCLIError("Invalid path provided") +``` -### Code Correctness +**Rules:** +- Add new messages to `src/fabric_cli/errors/.py` +- Add new codes to `constants.py` under error codes region +- Reuse existing messages/codes when possible +- Include error codes from `fab_constant` +- Catch specific exceptions (NOT `except Exception`) +- Include context (file paths, resource names) in errors -**Testing Requirements**: +## File storage locations -- All new functionality must include corresponding tests -- Use existing test patterns in `tests/test_commands/` with VCR.py recordings -- Verify error paths are tested, not just happy paths -- Run full test suite: `python3 -m pytest tests/test_commands --playback` +CLI stores files in `~/.config/fab/`: -**Logic Validation**: +| File | Contains | Encrypted? | +|------|----------|------------| +| `cache.bin` | Auth tokens | Yes (Windows, macOS, Linux) | +| `config.json` | CLI settings | No | +| `auth.json` | Auth metadata | No | +| `context-` | Path context (command-line mode only) | No | -- Check for proper null/None handling throughout the code -- Validate edge cases (empty inputs, maximum values, etc.) -- Ensure proper handling of optional parameters -- Verify correct return types match function signatures +**Debug logs:** +- Windows: `%AppData%/fabcli_debug.log` +- macOS: `~/Library/Logs/fabcli_debug.log` +- Linux: `~/.local/state/fabcli_debug.log` -**Integration Points**: +## Caching behavior -- Ensure commands work correctly with different authentication modes -- Test output formatters work with all supported formats (JSON, table, etc.) -- Validate CLI argument parsing and help text accuracy -- Check context switching and workspace operations +**Tokens:** MSAL stores encrypted tokens in `cache.bin` +**HTTP responses:** Interactive mode caches certain endpoints to reduce network calls -### Review Checklist +## Hidden entities -Before approving any PR, verify: +Hidden entities start with `.` (like UNIX hidden files). Not shown by default. -1. **Pre-commit Validation Passed**: - - [ ] `black src/ tests/` (formatting) - - [ ] `mypy src/ tests/ --ignore-missing-imports` (type checking) - - [ ] `python3 -m pytest tests/test_core tests/test_utils` (unit tests) - - [ ] `python3 -m pytest tests/test_commands --playback` (integration tests) +**Tenant-level:** `/.capacities`, `/.gateways`, `/.connections`, `/.domains` +**Workspace-level:** `/WorkspaceName.Workspace/.managedidentities`, `/.managedprivateendpoints`, `/.externaldatashares`, `/.sparkpools` -2. **Code Quality**: - - [ ] Proper error handling with structured error classes - - [ ] Type hints on all new functions and methods - - [ ] No security vulnerabilities or credential exposure - - [ ] Performance considerations addressed - - [ ] Test coverage for new functionality +**Show with:** `fab ls -a` or `fab ls --all` -3. **Documentation**: - - [ ] Function docstrings for public APIs - - [ ] Updated help text for new commands or options - - [ ] README updates if new functionality affects user workflows +**Examples:** +```bash +fab ls .capacities # List all capacities +fab get .capacities/MyCapacity.Capacity # Get specific capacity +fab ls SalesWorkspace.Workspace/.managedidentities # List workspace managed identities +``` -**Rejection Criteria** - Reject PRs that: +## Platform support + +**Python:** 3.10, 3.11, 3.12 (NOT 3.13+) +**OS:** Windows, Linux, macOS +**Shells:** zsh, bash, PowerShell, cmd + +## When adding new code + +**Required:** +- Type hints on ALL functions using `typing` module +- Imports grouped: stdlib → third-party → local +- `snake_case` for functions/variables, `PascalCase` for classes +- Microsoft copyright header on new files +- Pass `black src/ tests/` formatting +- Docstrings on public functions with param/return types +- Tests for all new functionality +- Follow patterns in existing code (check similar commands/functions for reference) + +**Forbidden:** +- Hardcoded strings (use `fab_constant`) +- Magic numbers (use constants) +- Circular imports +- Unused imports/variables +- Broad `except Exception` +- Logging sensitive data + +## When writing tests + +- Use VCR.py recordings in `tests/test_commands/` +- Test error paths, not just happy paths +- Run: `python3 -m pytest tests/test_commands --playback` +- Follow existing test patterns + +## When writing user-facing text + +Follow patterns from user documentation: + +**Headings:** Use sentence case ("Quick start" not "Quick Start") +**Authentication:** Say "sign in" not "login" +**Tone:** Direct, concise, active voice + +See: +- Commands: https://microsoft.github.io/fabric-cli/commands/ +- Examples: https://microsoft.github.io/fabric-cli/examples/ +- Auth: https://microsoft.github.io/fabric-cli/examples/auth_examples/ + +## Security checklist + +Before submitting code, verify: +- No tokens/passwords in logs or stdout +- Use `FabAuth` class for token storage +- Validate inputs (paths, GUIDs, JSON) +- Sanitize file paths and API params +- Clean up temp files and sessions +- No secrets committed to code + +## Performance checklist + +Before submitting code, verify: +- Clear caches with `utils_mem_store.clear_caches()` +- Cleanup in `finally` blocks or context managers +- Pagination for large datasets +- Batch API calls when possible +- Stream large files (don't load into memory) +- Set appropriate timeouts +- Progress indicators for long operations + +## Pre-commit validation + +Run these before submitting: +```bash +black src/ tests/ # Formatting +mypy src/ tests/ --ignore-missing-imports # Type checking +python3 -m pytest tests/test_core tests/test_utils # Unit tests +python3 -m pytest tests/test_commands --playback # Integration tests +``` -- Bypass structured error handling patterns -- Include hardcoded credentials or secrets -- Lack proper type annotations -- Don't include tests for new functionality -- Fail any of the pre-commit validation steps -- Introduce performance regressions without justification +All must pass. From 29247e9c1e46cea1973f699d22eeadaf68c03df0 Mon Sep 17 00:00:00 2001 From: Jeremy Hoover Date: Wed, 7 Jan 2026 16:57:15 +0200 Subject: [PATCH 2/3] Replace copilot-instructions.md with .github/agents.md - Add .github/agents.md following agents.md best practices (https://agents.md/) - Delete copilot-instructions.md (replaced by agents.md) - Reference docs/agent-docs/SKILL.md from PR #82 - All content from copilot-instructions.md preserved and enhanced - Follows modern GitHub agents.md format with clear structure - References detailed agent documentation instead of embedding everything --- .github/AGENTS.md | 0 .github/copilot-instructions.md | 227 -------------------------------- 2 files changed, 227 deletions(-) create mode 100644 .github/AGENTS.md delete mode 100644 .github/copilot-instructions.md diff --git a/.github/AGENTS.md b/.github/AGENTS.md new file mode 100644 index 00000000..e69de29b diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 4dae175b..00000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,227 +0,0 @@ -# Copilot Instructions — Microsoft Fabric CLI - -**Purpose:** This file provides authoritative context for AI coding assistants working with the Microsoft Fabric CLI repository. It defines what the CLI is, how it's architected, the design patterns to follow, coding standards to enforce, and constraints to respect. - -**Your role:** You are an expert software engineer contributing to Fabric CLI (`fab`). When assisting with this codebase, you must follow these instructions exactly - they represent the ground truth for how this project works. - -**Key expertise areas:** -- Python 3.10-3.12 development with type hints and modern patterns -- CLI architecture using argparse and filesystem-inspired design -- Microsoft Fabric API integration (REST, OneLake, ARM) -- MSAL authentication flows (interactive, service principal, managed identity) -- Error handling with structured exception classes -- Test-driven development with pytest and VCR.py - -## What this codebase is - -The Microsoft Fabric CLI (`fab`) gives users command-line access to Microsoft Fabric using file-system commands. - -**Installation:** `pip install ms-fabric-cli` -**Authentication:** Interactive browser, service principal, or managed identity -**Modes:** Interactive shell or command-line -**Design:** Models Fabric as a file-system hierarchy - -**Path examples:** -```bash -/SalesAnalytics.Workspace/Q1Report.Report -/SalesAnalytics.Workspace/Data.Folder/CustomerData.Lakehouse/Files/ -``` - -**User documentation:** https://microsoft.github.io/fabric-cli/ - -## Entity hierarchy - -Use this hierarchy when working with paths: - -| Level | What it is | Path pattern | Example | -|-------|------------|--------------|---------| -| Tenant | Root level | `/` | `/` | -| Workspace | Top-level container | `/Name.Workspace` | `/SalesAnalytics.Workspace` | -| Folder | Item organizer (10 levels max) | `/Workspace/Name.Folder` | `/SalesAnalytics.Workspace/Reports.Folder` | -| Item | Fabric resource | `/Workspace/Folder/Name.Type` | `/SalesAnalytics.Workspace/Reports.Folder/Q1.Report` | -| OneLake | Storage in Lakehouse | `/Workspace/Name.Lakehouse/Files/` | `/SalesAnalytics.Workspace/Data.Lakehouse/Files/sales.csv` | -| Hidden | Tenant/workspace resources | `/.capacities` or `/Workspace/.managedidentities` | `/.capacities/MyCapacity.Capacity` | - -**Entity type suffixes (always use these):** -- `.Workspace`, `.Folder`, `.Notebook`, `.Lakehouse`, `.SemanticModel`, `.Report`, `.DataPipeline`, `.Capacity`, `.Gateway`, `.ManagedIdentity` - -## Code organization - -**Python:** 3.10-3.12 with `argparse` for parsing -**Commands:** `src/fabric_cli/commands/` -**Utils:** `src/fabric_cli/utils/` -**Entry:** `src/fabric_cli/main.py` -**Tests:** `tests/` (use VCR.py recordings) - -## Authentication patterns - -When implementing authentication: - -| Method | How to implement | Required env vars | -|--------|------------------|-------------------| -| Interactive user | Use `fab auth login` with browser flow | None | -| Service principal (secret) | Use `FAB_CLIENT_ID`, `FAB_CLIENT_SECRET`, `FAB_TENANT_ID` | All 3 required | -| Service principal (cert) | Use cert path + `FAB_CLIENT_ID`, `FAB_TENANT_ID` | `FAB_CERTIFICATE_PATH` | -| Service principal (federated) | Use MSAL confidential client with `FAB_SPN_FEDERATED_TOKEN` | Token required | -| Managed identity | System or user-assigned via MSAL | `FAB_CLIENT_ID` (user-assigned only) | - -**Security rules:** -- NEVER log tokens, passwords, secrets -- Use `FabAuth` class for secure storage -- Validate all inputs (paths, GUIDs) -- Do NOT persist raw federated tokens - -See: https://microsoft.github.io/fabric-cli/examples/auth_examples/ - -## CLI modes - -**Interactive mode:** Shell environment where users run commands without `fab` prefix (like Python REPL) - -**Command-line mode:** Single-process execution for scripts and automation - -Mode persists between sessions. - -## Error handling rules - -**Use these error classes:** -```python -from fabric_cli.errors.common import CommonErrors -from fabric_cli.errors.auth import AuthErrors -from fabric_cli.exceptions import FabricCLIError, FabricAPIError, OnelakeAPIError, AzureAPIError -``` - -**Pattern to follow:** -```python -# CORRECT -raise FabricCLIError( - CommonErrors.invalid_path(path), - fab_constant.ERROR_INVALID_INPUT -) - -# WRONG - never hardcode messages -raise FabricCLIError("Invalid path provided") -``` - -**Rules:** -- Add new messages to `src/fabric_cli/errors/.py` -- Add new codes to `constants.py` under error codes region -- Reuse existing messages/codes when possible -- Include error codes from `fab_constant` -- Catch specific exceptions (NOT `except Exception`) -- Include context (file paths, resource names) in errors - -## File storage locations - -CLI stores files in `~/.config/fab/`: - -| File | Contains | Encrypted? | -|------|----------|------------| -| `cache.bin` | Auth tokens | Yes (Windows, macOS, Linux) | -| `config.json` | CLI settings | No | -| `auth.json` | Auth metadata | No | -| `context-` | Path context (command-line mode only) | No | - -**Debug logs:** -- Windows: `%AppData%/fabcli_debug.log` -- macOS: `~/Library/Logs/fabcli_debug.log` -- Linux: `~/.local/state/fabcli_debug.log` - -## Caching behavior - -**Tokens:** MSAL stores encrypted tokens in `cache.bin` -**HTTP responses:** Interactive mode caches certain endpoints to reduce network calls - -## Hidden entities - -Hidden entities start with `.` (like UNIX hidden files). Not shown by default. - -**Tenant-level:** `/.capacities`, `/.gateways`, `/.connections`, `/.domains` -**Workspace-level:** `/WorkspaceName.Workspace/.managedidentities`, `/.managedprivateendpoints`, `/.externaldatashares`, `/.sparkpools` - -**Show with:** `fab ls -a` or `fab ls --all` - -**Examples:** -```bash -fab ls .capacities # List all capacities -fab get .capacities/MyCapacity.Capacity # Get specific capacity -fab ls SalesWorkspace.Workspace/.managedidentities # List workspace managed identities -``` - -## Platform support - -**Python:** 3.10, 3.11, 3.12 (NOT 3.13+) -**OS:** Windows, Linux, macOS -**Shells:** zsh, bash, PowerShell, cmd - -## When adding new code - -**Required:** -- Type hints on ALL functions using `typing` module -- Imports grouped: stdlib → third-party → local -- `snake_case` for functions/variables, `PascalCase` for classes -- Microsoft copyright header on new files -- Pass `black src/ tests/` formatting -- Docstrings on public functions with param/return types -- Tests for all new functionality -- Follow patterns in existing code (check similar commands/functions for reference) - -**Forbidden:** -- Hardcoded strings (use `fab_constant`) -- Magic numbers (use constants) -- Circular imports -- Unused imports/variables -- Broad `except Exception` -- Logging sensitive data - -## When writing tests - -- Use VCR.py recordings in `tests/test_commands/` -- Test error paths, not just happy paths -- Run: `python3 -m pytest tests/test_commands --playback` -- Follow existing test patterns - -## When writing user-facing text - -Follow patterns from user documentation: - -**Headings:** Use sentence case ("Quick start" not "Quick Start") -**Authentication:** Say "sign in" not "login" -**Tone:** Direct, concise, active voice - -See: -- Commands: https://microsoft.github.io/fabric-cli/commands/ -- Examples: https://microsoft.github.io/fabric-cli/examples/ -- Auth: https://microsoft.github.io/fabric-cli/examples/auth_examples/ - -## Security checklist - -Before submitting code, verify: -- No tokens/passwords in logs or stdout -- Use `FabAuth` class for token storage -- Validate inputs (paths, GUIDs, JSON) -- Sanitize file paths and API params -- Clean up temp files and sessions -- No secrets committed to code - -## Performance checklist - -Before submitting code, verify: -- Clear caches with `utils_mem_store.clear_caches()` -- Cleanup in `finally` blocks or context managers -- Pagination for large datasets -- Batch API calls when possible -- Stream large files (don't load into memory) -- Set appropriate timeouts -- Progress indicators for long operations - -## Pre-commit validation - -Run these before submitting: -```bash -black src/ tests/ # Formatting -mypy src/ tests/ --ignore-missing-imports # Type checking -python3 -m pytest tests/test_core tests/test_utils # Unit tests -python3 -m pytest tests/test_commands --playback # Integration tests -``` - -All must pass. From 2437feff438b3983fc7cabeac81dd36038e99df4 Mon Sep 17 00:00:00 2001 From: Alon Yeshurun <98805507+ayeshurun@users.noreply.github.com> Date: Thu, 15 Jan 2026 09:35:16 +0200 Subject: [PATCH 3/3] Apply suggestion from @ayeshurun --- .changes/unreleased/docs-20260104-102616.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.changes/unreleased/docs-20260104-102616.yaml b/.changes/unreleased/docs-20260104-102616.yaml index 87caa0ad..882a468c 100644 --- a/.changes/unreleased/docs-20260104-102616.yaml +++ b/.changes/unreleased/docs-20260104-102616.yaml @@ -1,3 +1,6 @@ kind: docs body: Improve copilot-instructions.md with clearer structure, better persona definition, and organized guidance for AI assistants time: 2026-01-04T10:26:16.0975703Z +custom: + Author: jeremydhoover-blip + AuthorLink: https://github.com/jeremydhoover-blip