-
Address PR review comments and CI failures (
1d733c9) -
Remove duplicate test_ls_rich_format (ruff F811 CI blocker) - Tighten test_format_json_output assertion to check exit_code and option parsing - Replace import-time assert in toon.py with GCPathError for deterministic check - Keep count header in empty toon_ls output for schema consistency - Make _write_json atomic via tmp-file + os.replace - Validate JSON root type is dict in _read_json - Centralize managed hook matching with _is_managed_hook helper - Handle 0.0 cache age as fresh data (is not None check) - Narrow broad Exception catch in _parse_resource_arg to GCP/GCPath errors - Replace /tmp paths in hook status mock data with user config paths - Update README to drop non-existent --json/--yaml shorthand docs - Add minimal contents:read permission to CI workflow
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com
-
Address PR review comments and SonarCloud hotspots (
070529c) -
Restore docstring on _resolve_scope in cli.py - Narrow except Exception to specific GCP/gcpath exceptions in path command - Fix return type hint on _truncate_metadata (Any -> Dict[str, str]) - Add docstring on serialize_resource - Replace /tmp paths in test_serializers.py to resolve SonarCloud S5443
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
Narrow broad exception catch and remove conflicting CodeQL workflow (
aae603b) -
Replace bare
except Exceptionin_resolve_target_path_prefixwith specific(GCPathError, gcp_exceptions.GoogleAPICallError)as suggested in review - Remove custom CodeQL workflow files that conflict with the repository's default CodeQL setup, causing SARIF upload failures
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
- Remove unused Path import in test_hooks
(
8226380)
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
Resolve CodeQL false positives and improve test coverage (
509df66) -
Add custom CodeQL workflow with config that excludes test paths from URL sanitization checks (fixes 5 false-positive high severity alerts) - Add 23 targeted tests for hook commands, rich format outputs, fresh cache home view, and format validation (cli.py coverage 73% → 87%) - Add codecov.yml with appropriate thresholds (patch ≥80%, project ±2%)
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
-
Resolve SonarCloud issues across cli, hooks, and tests (
5414569) -
Extract _cache_status_rich and _stats_rich to reduce cognitive complexity (S3776) - Extract _validate_stats_resource helper for stats command - Remove unused params: ctx in _show_home, level in _prepare_hierarchy_command, target_resource_name in _ls_help_lines (S1172) - Replace duplicated "gcpath hook run" literal with _GCPATH_HOOK_COMMAND constant (S1192) - Extract _check_hook_entries to reduce get_hook_status complexity (S3776) - Fix unused variables in test_serializers.py (S1481)
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Suppress CodeQL false positives in test assertions
(
8720d2c)
The in operator on strings like "example.com" triggers CodeQL rule
py/incomplete-url-substring-sanitization. These are test output assertions, not URL sanitization
code — suppress with lgtm comments.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
-
Test_ls_type_organization assertion for TOON output format (
2872c99) -
Use simple substring check instead of urlparse which fails on TOON comma-separated rows - Remove unused urlparse import to silence CodeQL false positive
- deps: Bump requests in the uv group across 1 directory
(
29b2d81)
Bumps the uv group with 1 update in the / directory: requests.
Updates requests from 2.32.5 to 2.33.0 - Release notes
--- updated-dependencies: - dependency-name: requests dependency-version: 2.33.0
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
- Add Agent Skill section to README
(
be96998)
Adds a dedicated section explaining the bundled agent skill and how to install it via bunx/npx, plus a one-liner callout in the "Why use gcpath" bullet list.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
- Add gcpath agent skill for AI agent consumption
(
30bd24f)
Adds a skills/gcpath/ directory following the Agent Skills spec (agentskills.io), enabling agents to install and use gcpath via:
bunx skills add github:tardigrde/gcpath --skill gcpath
Includes SKILL.md (when-to-use guidance, all commands with examples, common workflows, gotchas) and references/commands.md (compact flag reference per command).
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
- Rewrite README to highlight agent-native design
(
32e4bd3)
Restructure the README to lead with gcpath's agent-native qualities: read-only safety, AXI-compliant TOON output, ambient context hooks, and Agent Skill integration. Add output format comparison table and dedicated Agent Integration section with hook setup instructions.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
skill: Enrich frontmatter and trim body per Agent Skills spec (
531d4d5) -
Add allowed-tools: Bash(gcpath:) Bash(uvx gcpath:) - Add compatibility, license, and metadata fields - Trim SKILL.md from 258 to 143 lines: collapse verbose commands section into common workflows + key flags table, move full flag reference to references/commands.md with explicit load trigger - Keep gotchas inline per best-practices guidance
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
- Add AXI-compliant output with TOON format, hooks, and content-first home
(
1e10e8d)
Refactor gcpath from Rich-table-first output to AXI-compliant TOON-first output following the AXI specification (https://axi.md/).
New capabilities: - TOON format as default output (token-efficient, structured for AI agents) -
--format toon|json|yaml|rich flag replaces old --json/--yaml flags - --fields flag for
controlling output columns (replaces --long) - --full flag to expand truncated labels/tags -
Content-first home view: gcpath with no args shows live dashboard - Pre-computed aggregates:
count: N of M total on list outputs - Contextual help[] sections with next-step suggestions -
Structured errors to stdout in TOON format (no more Rich stderr markup) - Ambient context hooks:
gcpath hook install for Claude Code and Codex - gcpath hook run outputs compact session-start
dashboard - Definitive empty states: 0 resources found not empty output - All interactive
prompts removed (no more typer.confirm)
New files: - src/gcpath/toon.py — TOON encoder wrapper + AXI helpers - src/gcpath/hooks.py —
Claude Code / Codex session hook management - tests/test_hooks.py — Hook management tests
Design decisions: - tree keeps classic unicode tree output (not TOON) — agents use ls -R -
diagram keeps raw Mermaid/D2 output with --diagram-format flag - toon-format library (git
dep) handles TOON encoding
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Add new Claude Code hook format support and README badges
(
cbfa81f)
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
-
Address PR review comments and SonarCloud findings (
c756062) -
Remove unimplemented --show-labels/--show-tags from ancestors command - Deduplicate _matches_labels/_matches_tags into generic _matches_metadata - Deduplicate _format_labels/_format_tags into generic _format_metadata - Use scope_resource for tag lookups instead of always querying org root - Replace duplicated "organizations/" literal with _RESOURCE_PREFIX_ORGS constant - Sanitize user-controlled data from cache log message - Fix single-iteration loop in build_folder_ancestors (parsers.py) - Reduce cognitive complexity across cli.py, core.py, formatters.py, loaders.py, and parsers.py by extracting helper functions
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Findings
(
3be86b0)
- Update uv.lock
(
ea0a688)
https://claude.ai/code/session_01HugtU9fbaL97tbb7zaqNPL
- deps: Bump pyasn1 in the uv group across 1 directory
(
8adfd85)
Bumps the uv group with 1 update in the / directory: pyasn1.
Updates pyasn1 from 0.6.2 to 0.6.3 - Release notes -
Changelog -
Commits
--- updated-dependencies: - dependency-name: pyasn1 dependency-version: 0.6.3
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
- Add GCP labels and tags support to CLI commands
(
d428c9a)
Add opt-in support for GCP resource labels (key-value pairs) and resource tags (Tag Manager bindings) across CLI commands. Labels are fetched via an additional SQL column in Asset API queries (cheap). Tags require a separate Asset API query against TagBinding resources (expensive). Both are only fetched when explicitly requested via CLI flags.
New CLI options on ls, tree, find, ancestors: - --show-labels: display labels in output - --show-tags: display tags in output - --label key=value: filter by label (repeatable, ANDed) - --tag key=value: filter by tag (repeatable, ANDed)
Changes across the stack: - core.py: labels/tags fields on Folder and Project dataclasses - parsers.py: extract_labels() and has_labels param on parse functions - loaders.py: include_labels in SQL builders, load_tags_asset/apply_tags - cache.py: bump CACHE_VERSION to 2, serialize/deserialize labels+tags - serializers.py: include labels/tags in JSON/YAML output when non-empty - formatters.py: show labels/tags in tree view labels
https://claude.ai/code/session_01HugtU9fbaL97tbb7zaqNPL
-
Address PR review feedback — narrow exception handling and improve consistency (
d358e26) -
Narrow bare
except Exceptionin_resolve_scope()to catch onlyPermissionDenied,NotFound, andGCPathError- Moveimport fnmatchfrom local scope to top-level imports (PEP 8) - Add detailed comment explaining base_segments depth calculation - Make PermissionDenied handling consistent in_fetch_chain_link(): folders and projects now use graceful fallback like organizations
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
Reduce cognitive complexity and extract constants for SonarCloud (
819f5dd) -
Extract _fetch_chain_link() from resolve_ancestry_chain() to reduce cognitive complexity from 25 to under 15 - Extract _search_hierarchy() from find command to reduce complexity - Extract _get_node_parent_name(), _get_child_folders() in formatters to reduce build_tree_view() complexity from 18 to under 15 - Extract _node_to_dict(), _get_child_folders() in serializers to reduce serialize_tree_node() complexity from 18 to under 15 - Add _PREFIX_ORGS/_PREFIX_FOLDERS/_PREFIX_PROJECTS constants in core.py to replace duplicated string literals
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
Resolve CI failures, CodeQL alerts, and eager client initialization (
d054977) -
Add missing resolve_ancestry mock to two tests that pass a positional resource to
ls -l, which triggers _resolve_scope() → resolve_ancestry() and fails in CI without GCP credentials - Fix 4 CodeQL "Incomplete URL substring sanitization" alerts by replacing"example.com" in result.stdoutsubstring checks with exact-match alternatives (split()/list comprehension) - Lazily initialize GCP API clients in resolve_ancestry() so only the client needed for the given resource prefix triggers credential lookup
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
Resolve remaining SonarCloud issues — constants and complexity (
6257f97) -
Replace all bare "organizations/", "folders/", "projects/" string literals in core.py with _PREFIX_ORGS/_PREFIX_FOLDERS/_PREFIX_PROJECTS - Simplify _search_hierarchy() by extracting _get_resource_display_name() and _get_resource_path() helpers, using a flat candidate list with list comprehension instead of nested loops
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Use explicit equality checks to resolve CodeQL URL sanitization alerts
(
26f4896)
Replace "example.com" in result.stdout.split() with any(token == "example.com" for token in ...)
to avoid CodeQL's incomplete-url-substring-sanitization rule, which still triggers on in with
split lists.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Document find, ancestors, --type filter, -L depth limit, and structured output
(
ce92751)
Add README sections for features from PR #26 (--json/--yaml structured output) and PR #28 (find command, ancestors command, --type filter on ls/tree, -L depth limit on ls -R). Updates Quick Start and Features summary accordingly.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Add --type filter, find command, ancestors command, and -L depth limit
(
25e1ded)
Add four new features to gcpath CLI:
--type/-tfilter onlsandtreecommands (folder, project, organization) -findcommand for glob-style name search with optional type and scope filters -ancestorscommand to show full ancestry chain from resource to org root ---level/-Ldepth limit onls -Rfor recursive listing
Refactors scope resolution into shared _resolve_scope() helper to reduce duplication between ls
and find commands.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
-
Address PR review feedback — reduce duplication in serializers and CLI (
40ae2c6) -
Extract _get_dumper() helper to eliminate repeated dumper selection logic - Remove unused hierarchy and show_ids params from serialize_tree_node - Reuse serialize_resource() for project dicts instead of duplicating
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- Extract duplicated string literals to constants in conftest.py
(
ed34bc6)
Resolves SonarCloud S1192 issues for "organizations/123", "folders/1", and "folders/11" repeated in test hierarchy builder.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
-
Resolve SonarCloud duplication and unused variable issues (
aa47ef5) -
Extract shared test hierarchy builder to conftest.py (eliminates ~40-line duplication between test_cli.py and test_serializers.py) - Fix all 6 unused variable warnings in test_serializers.py
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- Add --json and --yaml structured output flags
(
949d8e3)
Add global --json and --yaml flags for machine-readable output across all commands (ls, tree, name, path). This makes gcpath composable with jq, yq, shell scripts, and CI pipelines.
- New serializers.py module for dict-building and JSON/YAML dumping - Mutually exclusive flags with clear error message - Cache status message moved to stderr to avoid polluting structured output - pyyaml>=6.0 added as dependency
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- Extract duplicated "folders/" literal to constant in loaders
(
b292a3e)
SonarCloud S1192: the string "folders/" was duplicated 5 times. Extract to module-level _FOLDER_PREFIX constant.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
- Resolve SonarCloud code quality issues
(
054bdbe)
Addresses 19 of 31 SonarCloud findings:
S1192 (CRITICAL): Extract duplicated string literals into module-level constants - Added _RESOURCE_PREFIX_PROJECTS, _RESOURCE_PREFIX_FOLDERS, _RESOURCE_PREFIX_ORGS - Added _RESOURCE_PREFIXES tuple and _REFRESH_HELP constant - Replaced all occurrences in cli.py
S1871 (MAJOR): Merge duplicate branches - formatters.py: Merged Folder/Project branches in get_display_path and _get_node_label - parsers.py: Merged hasattr/get and isinstance/dict checks in extract_value
S3358 (MAJOR): Extract nested ternaries into if/else blocks - loaders.py: Refactored folder_parent and project parent_res determination logic
S3776 (CRITICAL): Reduce cognitive complexity with helper extraction - cli.py: Extracted _try_read_cache() from _load_hierarchy() - core.py: Extracted _find_orgless_project() from get_resource_name() - loaders.py: Extracted _build_single_ancestor_chain() from fix_folder_ancestors()
S7504 (MINOR): Remove unnecessary list() call - loaders.py: Changed list(node.folders.values()) to node.folders.values()
S2737 (MINOR): Remove bare except clause - core.py: Removed no-op try/except that just re-raised
S2772 (MINOR): Remove unneeded pass - tests/test_cli.py: Replaced pass with meaningful assertion
S1481 (MINOR): Fix unused variable - tests/test_formatters.py: Changed folders to _ for unused variable
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Add coverage for extracted helper functions
(
ab315ee)
Add direct tests for: - _build_single_ancestor_chain (loaders.py) - _find_orgless_project (core.py)
- _try_read_cache (cli.py)
Coverage improved from 87% to 88%
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Add coverage for loader conditional branches and remove dead code
(
37b7f01)
Cover the refactored if/elif/else branches in load_folders_asset and load_projects_asset that handle fallback parent resolution. Remove unreachable elif/else in the last else-branch where ancestors is guaranteed non-empty.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com
-
Validate resource format and escape rich markup in stats command (
7728b16) -
Add explicit else branch for invalid resource formats (not organizations/ or folders/) with a clear "Invalid resource format" error message instead of silently loading the full hierarchy - Escape user-supplied scope label with rich.markup.escape to prevent markup injection via crafted resource name arguments - Add test_stats_invalid_scope_error test case
https://claude.ai/code/session_01JxDqkYXvoag1R6LWBV8Mtq
- deps: Bump protobuf in the uv group across 1 directory
(
176815d)
Bumps the uv group with 1 update in the / directory: protobuf.
Updates protobuf from 6.33.2 to 6.33.5 - Release
notes -
Commits
--- updated-dependencies: - dependency-name: protobuf dependency-version: 6.33.5
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
- Add stats subcommand for folder/project counts in a scope
(
9a28f93)
Adds a new stats CLI subcommand that reports the number of organizations, folders, and projects
within a given scope (organization or folder). When no scope is provided, it reports totals across
all accessible organizations. Projects are rejected as the starting scope since they are leaf
nodes.
https://claude.ai/code/session_01JxDqkYXvoag1R6LWBV8Mtq
- deps: Bump pyasn1 to 0.6.2 and urllib3 to 2.6.3
(
bd4c47c)
Fixes CVE-2026-23490 (pyasn1 OID decoder issue) and CVE-2026-21441 (urllib3 decompression-bomb bypass, High severity).
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
- Refocus README on CLI usage, add pipx install, remove roadmap
(
cb03af6)
Move Python API section to the end as a secondary use case. Add pipx as a recommended installation option alongside pip and uv. Remove the roadmap section.
https://claude.ai/code/session_01E5TmezTsqmhrkBS6HdVSL9
- deps: Bump protobuf in the uv group across 1 directory
(
a21b624)
Bumps the uv group with 1 update in the / directory: protobuf.
Updates protobuf from 6.33.2 to 6.33.5 - Release
notes -
Commits
--- updated-dependencies: - dependency-name: protobuf dependency-version: 6.33.5
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
- deps: Configure Dependabot to use pip for updates
(
322a771)
-
Add Python API documentation and library usage examples (
aa65f59) -
Add comprehensive "Python API" section to README.md covering: - Basic usage with Hierarchy.load() (both RM and Asset API modes) - Path ↔ resource name conversion methods - Lightweight single-resource lookup via Hierarchy.resolve_ancestry() - Scoped loading for large or restricted hierarchies - Error handling with GCPathError, ResourceNotFoundError, PathParsingError - API reference table for all public symbols - Update pyproject.toml description to reflect library capability - Add "Topic :: Software Development :: Libraries :: Python Modules" classifier
https://claude.ai/code/session_01M3eDcpXVjivW3zbCXnvbmx
- Make cache scope-aware so entrypoint loads are cached
(
c288a51)
The cache was completely bypassed when an entrypoint was configured because _load_hierarchy() only read/wrote cache when scope_resource was None. Now the cache stores which scope it was built for and only serves hits when the scope matches, enabling instant subsequent commands with entrypoints.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Add folder entrypoint support for folder admins without org access
(
e15c6ca)
Allow users who only have access to a folder (not the parent organization) to use ls, tree, diagram, and name commands by configuring a folder as the default entrypoint. When org loading fails and the scope is a folder, a fallback path creates a synthetic OrganizationNode and queries the Asset API directly from the folder scope.
Adds config subcommands (set-entrypoint, show, clear-entrypoint) and a global --entrypoint/-e flag.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Add missing v0.4.0 CHANGELOG entry and pin PSR to v9
(
0d35cec)
The v0.4.0 release was created by PSR v10.x (pulled via unpinned --with python-semantic-release)
which silently skipped changelog generation due to breaking template changes from v9.
- Add the v0.4.0 CHANGELOG entry manually - Pin PSR to >=9,<10 in release workflow to prevent version drift - Revert changelog config key to v9 format
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Update uv.lock
(
6cccda9)
https://claude.ai/code/session_01Jmv8XrUQSV3r83cSgHtqys
- Add diagram generation command (Mermaid & D2)
(
c2d6c70)
Add a diagram command that generates Mermaid or D2 diagrams from the GCP resource hierarchy. Works
directly from structured hierarchy data rather than parsing tree ASCII output, inspired by
tree2diagram.
Supports scoped resources, depth limiting, resource ID labels, and file output. Closes the "diagram generation" roadmap item.
https://claude.ai/code/session_01Jmv8XrUQSV3r83cSgHtqys
- Add missing mock in test_tree_user_declines_prompt
(
c7aa4c8)
The test was failing in CI environments without GCP credentials because Hierarchy.load() was being called even after the user declined the prompt. Added mock for Hierarchy.load to prevent actual client creation.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Address linting errors
(
242db12)
This commit fixes the linting errors reported by ruff.
- Refactor code into modules (v0.2.3)
(
ac156e7)
- Add local caching for GCP resource hierarchy
(
385b3be)
This commit introduces a local caching mechanism to speed up API calls when fetching the GCP
resource hierarchy. The cache is stored as a single JSON file at ~/.gcpath/cache.json.
New features include: - A gcpath cache clear command to manually clear the cache. - A
--force-refresh flag on commands that display the resource hierarchy to bypass the cache and
fetch fresh data from GCP. - User notifications in the console when a command is using cached
data.
Comprehensive unit tests have been added for the new caching functionality, and existing tests have been updated to account for the caching layer.
- Address PR feedback
(
c37ab27)
This commit addresses the feedback from the pull request:
-
Renames the
SimpleOrgclass toSerializableOrganizationfor clarity. - Refactors thecachesubcommand to be more integrated with the main Typer application. -
Implement robust caching layer with TTL and architectural improvements (
caa73c8) -
Add TTL (4-hour default) to cache expiration with UTC timestamp validation - Implement cache freshness checking and raw JSON reading without deserialization - Add CacheInfo dataclass for cache metadata inspection (age, size, freshness, resource counts) - Remove circular dependency: eliminate cache I/O from Hierarchy.load(), move orchestration to CLI - Add
cache statussubcommand showing cache state and resource counts - Refactor _load_hierarchy() as single cache orchestration point with post-load org filtering - Update tree command to use get_cache_info() for freshness checking - Show human-readable cache age on hits ("2h 15m ago") - Revert premature version bump (0.3.0 → 0.2.3) for semantic-release - Comprehensive test updates: TTL checking, cache info inspection, cache subcommands
Fixes circular dependency architecture, implements proper cache expiration, and enables cache state inspection. All 127 tests passing, lint and type checks clean.
Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
- Improve tree, ls, path subcommands (0.2.2)
(
5b59880)
- Debug logs (v0.2.1)
(
0bd2c57)
- Subcommand improvements (v0.2.0)
(
d4d2c36)
-
Add type annotation for mypy compliance (
6cd1464) -
Added List[Project] type annotation to projects variable - Created CONTRIBUTING.md with feature branch workflow - Added automated semantic versioning with GitHub Actions - Bumped version to 0.1.3
-
Mapcomposite error & optimize path command (v0.1.4) (
2437608) -
Releases with 0.x (
3cee1be) -
release: Use uv run for semantic-release to avoid PEP 668 errors (
3915394)
- Configure semantic-release to stay in 0.x.y range
(
b5e11e9)
- Asset API pagination and Project schema compatibility (v0.1.2)
(
f35edbe)
- Bump version to 0.1.1 and fix bugs
(
63ab844)
-
Core logic for GCP resource hierarchy management. - Dual mode loading: Cloud Asset API (fast bulk) and Resource Manager API (iterative). - CLI commands:
ls,tree,name(get resource name),path(get path). - Support for organizationless projects (//_prefix). - O(1) resource lookups via cached dictionaries. - Comprehensive test suite for core logic and CLI. - GitHub Actions CI workflow with automatic test, lint, type check, and coverage reporting. - Defensive API response parsing and structured error handling. - MIT License.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>