Skip to content

Port flagpls's flag-usage scanner into ldcli as flags usage#742

Draft
davidbrackbill wants to merge 1 commit into
mainfrom
db/flagpls-usage
Draft

Port flagpls's flag-usage scanner into ldcli as flags usage#742
davidbrackbill wants to merge 1 commit into
mainfrom
db/flagpls-usage

Conversation

@davidbrackbill

@davidbrackbill davidbrackbill commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Ports flagpls's AST scanner, LD API enrichment, and table renderer (internal/flagusage/{scanner,enrich,render}) into ldcli, with import paths and config/cache locations rewritten to ldcli's conventions (xdg-based cache/config under the ldcli namespace instead of flagpls's own).
  • Adds a new ldcli flags usage subcommand (cmd/flags/usage.go) that reuses ldcli's existing --access-token/--base-uri/--project flags instead of flagpls's standalone token/config-file flow.
  • Adds the go-tree-sitter dependency required by the scanner.

Stacked on top of this: #TBD (envs config integration).

Test plan

  • go build ./... and go test ./... pass, including the 3 ported test suites
  • ldcli flags usage --help renders correctly with ldcli's usage template
  • End-to-end smoke test against a real internal repo: scanner found flag references, enrichment correctly called the LD API

Claude claude@anthropic.com


Note

Medium Risk
New CLI surface and many LD API/internal monitor calls (token-bearing); logic is read-only but heuristics for “ready to remove” flags could mislead if wrong.

Overview
Adds ldcli flags usage, wiring a scan → enrich → render pipeline into the existing flags command and ldcli auth (--project, access token, base URI).

The scanner (tree-sitter) finds flag eval sites in TS/JS and Go, including wrapper factories and auto-discovery via node_modules. Enrichment pulls flag config, per-env status, batched eval summaries (and optional timeseries / unique-context “exposures”), classifies lifecycle states (e.g. orphaned refs, code-removable rollouts), and caches API responses under xdg ldcli/flagusage. Output is a terminal table or --format json.

Dependency: go-tree-sitter. Substantial ported test coverage for scanner, enrich, render, and API client behavior.

Reviewed by Cursor Bugbot for commit 032b957. Bugbot is set up for automated code reviews on this repo. Configure here.

Copies flagpls's AST scanner, LD API enrichment, and table renderer
(internal/flagusage/{scanner,enrich,render}) with import paths and
config/cache locations rewritten to ldcli's conventions (xdg cache/config
under the ldcli namespace instead of flagpls's own). Wires them up as a
new `ldcli flags usage` subcommand reusing ldcli's existing
--access-token/--base-uri/--project flags instead of flagpls's standalone
token/config-file flow.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 032b957. Configure here.

Comment thread cmd/flags/usage.go
if windowLabel == "" {
windowLabel = "7d"
}
render.Enriched(os.Stdout, details, windowLabel, splitNonEmpty(envsRaw), width)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text table omits default environments

High Severity

When --envs is omitted, enrichment still loads per-environment data via DefaultCriticalEnvs, but text rendering passes an empty environment list into render.Enriched. flagRows only prints envs from that list, so the default text table shows all-dash env rows even though JSON and the API layer have real status.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 032b957. Configure here.

Comment thread cmd/flags/usage.go
if windowLabel == "" {
windowLabel = "7d"
}
render.Enriched(os.Stdout, details, windowLabel, splitNonEmpty(envsRaw), width)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Width zero skips terminal detection

Medium Severity

The --width help says 0 auto-detects the terminal, but runUsage forwards 0 unchanged. render.Enriched treats maxWidth of 0 as unconstrained width, and render.TerminalWidth() is never called despite being added for this purpose.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 032b957. Configure here.

return err
}

cacheSet(key, result)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Response cache ignores API token

Medium Severity

Disk cache keys are derived from method, path, optional headers, and body only. The Authorization header is applied after the cache lookup and is not part of the key, so a later run with a different access token can read another identity’s cached API JSON from the shared ldcli cache directory.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 032b957. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant