Releases: tardigrde/gcpath
v0.11.0
v0.11.0 (2026-04-28)
Bug Fixes
-
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
Chores
- 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
updated-dependencies:
- dependency-name: requests dependency-version: 2.33.0
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
Documentation
- 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
Features
- 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
Detailed Changes: v0.10.0...v0.11.0
v0.10.0
v0.10.0 (2026-03-29)
Bug Fixes
-
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)
Chores
- 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
updated-dependencies:
- dependency-name: pyasn1 dependency-version: 0.6.3
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
Features
- 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
Detailed Changes: v0.9.0...v0.10.0
v0.9.0
v0.9.0 (2026-03-19)
Bug Fixes
-
Address PR review feedback — narrow exception handling and improve consistency (
d358e26) -
Narrow bare
except Exceptionin_resolve_scope()to catch only
PermissionDenied,NotFound, andGCPathError -
Move
import 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 tols -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
Documentation
- 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
Features
- 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 filtersancestorscommand 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
Detailed Changes: v0.8.0...v0.9.0
v0.8.0
v0.8.0 (2026-03-17)
Bug Fixes
-
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
Features
- 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
Detailed Changes: v0.7.1...v0.8.0
v0.7.1
v0.7.1 (2026-03-17)
Bug Fixes
- 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
Testing
- 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
Detailed Changes: v0.7.0...v0.7.1
v0.7.0
v0.7.0 (2026-03-09)
Bug Fixes
-
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
Chores
- 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
updated-dependencies:
- dependency-name: protobuf dependency-version: 6.33.5
dependency-type: indirect
dependency-group: uv ...
Signed-off-by: dependabot[bot] support@github.com
Features
- 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
Detailed Changes: v0.6.1...v0.7.0
v0.6.1
v0.6.1 (2026-03-07)
Bug Fixes
- 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
Documentation
- 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
Detailed Changes: v0.6.0...v0.6.1
v0.6.0
v0.6.0 (2026-03-07)
Chores
- 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
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)
Features
-
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
Detailed Changes: v0.5.1...v0.6.0
v0.5.1
v0.5.1 (2026-02-17)
Bug Fixes
- 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
Detailed Changes: v0.5.0...v0.5.1
v0.5.0
v0.5.0 (2026-02-16)
Features
- 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
Detailed Changes: v0.4.1...v0.5.0