feat: add --json to list/modes/env-info/version and remove the workflow project type#205
feat: add --json to list/modes/env-info/version and remove the workflow project type#205wyli wants to merge 3 commits into
Conversation
Completes the F3 "--json on every read verb" surface from the agentic-CLI
design. `status` and `env-check` already emitted JSON; this adds the same
opt-in `--json` flag to the four remaining read commands so agents can parse
discovery and diagnostic output instead of scraping prose:
* `list --json` — {projects: [{name, project_type, source_folder,
language[], modes[]}]}. Includes source_folder, the one
field agents previously had to guess.
* `modes --json` — the resolved metadata.modes object plus project/language.
* `env-info --json` — full structured host report. env_info.py grows a
parallel `gather_*` data layer beside the `collect_*`
prose printers (the status.py collect/format split);
only one path runs per invocation.
* `version --json` — package/version/executable/module.
All payloads flow through a new utils/json_output.dumps that injects an
additive `schema_version` (1) as the first key; the same wrapper is
retrofitted onto the existing status/env-check JSON (additive, no field moves).
Env-var name lists and the Python-environment classification are extracted to
single-source helpers shared by the prose and JSON renderers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
WalkthroughThe CLI adds schema-versioned JSON output for version, project information, environment information, status, and system checks. Workflow metadata discovery, validation, dependency extraction, packaging, and benchmark handling are removed or restricted. ChangesCLI JSON output
Workflow metadata removal
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/holoscan_cli/commands/info.py (1)
148-158: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winNormalize
languagefor parity withlist --json.
list --jsonrunslanguagethrough_project_languages()to always emit alist[str], but themodes --jsonpayload returnsmetadata.get("language")raw — which can be a string, a list, orNone. Consumers of the new machine-readable contract then have to handle two shapes for the same field name.♻️ Reuse the existing normalizer
if getattr(args, "json", False): print( json_dumps( { "project": args.project, - "language": metadata.get("language"), + "language": _project_languages(metadata), "modes": modes, } ) ) return🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/holoscan_cli/commands/info.py` around lines 148 - 158, Update the JSON payload in the info command’s json branch to pass metadata.get("language") through the existing _project_languages() normalizer, matching the list --json contract and always emitting a list[str]. Keep the project and modes fields unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/holoscan_cli/commands/info.py`:
- Around line 148-158: Update the JSON payload in the info command’s json branch
to pass metadata.get("language") through the existing _project_languages()
normalizer, matching the list --json contract and always emitting a list[str].
Keep the project and modes fields unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4c58a10f-02a3-45cf-8d98-0a12858e7340
📒 Files selected for processing (11)
src/holoscan_cli/__main__.pysrc/holoscan_cli/commands/info.pysrc/holoscan_cli/status.pysrc/holoscan_cli/system_check.pysrc/holoscan_cli/utils/env_info.pysrc/holoscan_cli/utils/json_output.pysrc/holoscan_cli/version/version.pytests/unit/test_command_registry.pytests/unit/test_env_info.pytests/unit/test_status.pytests/unit/version/test_version.py
Mirrors holohub#1646 ("Remove Holohub Workflow Concept Entirely"), which
folded the AI Surgical Video workflow into applications and dropped the
workflow type: it has no meaningful difference from an application.
Removes the workflow project type across the CLI:
* delete metadata/workflow.schema.json (packaged via the *.schema.json glob)
* drop the "workflows" dir + "workflow" schema from METADATA_DIRECTORY_CONFIG,
gather_metadata SCHEMA_TYPES, and metadata_validator KNOWN_ENVELOPES
* drop "workflows" from the holohub root-detection and search-path dir lists,
and "workflow" from PROJECT_PREFIXES
* drop "workflow" from the benchmark-eligible project types in build (help
text, patch/restore guards, and the fatal message now say "applications")
* drop "workflow" from external_resolver's dependency-envelope keys and from
the `list` LIST_TYPES
Tests: retarget the resolver envelope test to application/benchmark and drop
workflow.schema.json from the required-package-data set.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/unit/test_external_resolver.py (1)
134-135: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winKeep regression coverage for ignored workflow metadata.
Add a case asserting that a metadata object containing only
"workflow"dependencies returns no parsed dependencies. This protects the behavior introduced by removing workflow support.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/unit/test_external_resolver.py` around lines 134 - 135, Add a parametrized regression case to test_parses_application_and_benchmark_shapes, or the surrounding external-resolver tests, with metadata containing only “workflow” dependencies; assert that parsing returns no dependencies, preserving the behavior after workflow support removal.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/holoscan_cli/commands/build.py`:
- Around line 120-122: Update the --benchmark help text in
src/holoscan_cli/commands/build.py lines 120-122 to state that it is valid for
applications and benchmarks, and update the corresponding fatal error message in
lines 252-260 to use the same accepted project types.
---
Nitpick comments:
In `@tests/unit/test_external_resolver.py`:
- Around line 134-135: Add a parametrized regression case to
test_parses_application_and_benchmark_shapes, or the surrounding
external-resolver tests, with metadata containing only “workflow” dependencies;
assert that parsing returns no dependencies, preserving the behavior after
workflow support removal.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 30ecbbb1-ef71-4816-8790-50675a3e7a9e
📒 Files selected for processing (10)
src/holoscan_cli/commands/build.pysrc/holoscan_cli/commands/info.pysrc/holoscan_cli/metadata/gather_metadata.pysrc/holoscan_cli/metadata/metadata_validator.pysrc/holoscan_cli/metadata/utils.pysrc/holoscan_cli/metadata/workflow.schema.jsonsrc/holoscan_cli/utils/external_resolver.pysrc/holoscan_cli/utils/holohub.pytests/unit/test_external_resolver.pytests/unit/test_package_data.py
💤 Files with no reviewable changes (7)
- src/holoscan_cli/metadata/workflow.schema.json
- tests/unit/test_package_data.py
- src/holoscan_cli/metadata/gather_metadata.py
- src/holoscan_cli/metadata/metadata_validator.py
- src/holoscan_cli/metadata/utils.py
- src/holoscan_cli/utils/holohub.py
- src/holoscan_cli/commands/info.py
Source fixes from review: * modes --json: normalize `language` via _project_languages() so it is always a list[str], matching the list --json contract. * build --benchmark: help text and fatal message now say "applications and benchmarks" (benchmark is an eligible type, application-only was inaccurate). Tests: pare the --json additions to one lean test per new surface — list, modes, and env-info (parseable + null handling). Drop the redundant version JSON test and the extra edge-case cases; keep the one-line schema_version assertions on the existing status/env-check JSON tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tbirdso
left a comment
There was a problem hiding this comment.
🎉 looks good! Minor questions about schema, no blockers
| return { | ||
| "version": holoscan_cli.__version__, | ||
| "package": str(Path(holoscan_cli.__file__).parent), | ||
| "environment": env["kind"], | ||
| "environment_prefix": env["prefix"], | ||
| "uninstall": env["uninstall"], | ||
| "source_override": os.environ.get("HOLOSCAN_CLI_SOURCE"), | ||
| } |
There was a problem hiding this comment.
I wonder if we have any schema or interface contract expectation for these JSON outputs, or should they be considered unstable and subject to change? Suggest documenting for developer expectations, up to you how far we should go at this point in time
| # Bump only for a breaking change (a removed or renamed field). Additive | ||
| # changes — new keys — keep the same version. | ||
| SCHEMA_VERSION = 1 |
There was a problem hiding this comment.
Is there any actual schema to help validate or is this a placeholder for now?
Two related changes to the read/discovery surface.
1.
--jsonon every read verbExtends the opt-in
--jsonflag — already onstatusandenv-check— to the four remaining read commands, so agents and scripts can parse output instead of scraping prose.list --json{projects: [{name, project_type, source_folder, language[], modes[]}]}— includessource_folder, the one field callers previously had to guessmodes <project> --jsonmetadata.modesobject plusproject/languageenv-info --jsonversion --json{package, version, executable, module}How
utils/json_output.dumps()injects an additiveschema_version(1) as the first key of every--jsonpayload. Retrofitted onto the existingstatus/env-checkJSON — additive only, no field moves/renames.env_info.pygains a parallelgather_*data layer beside thecollect_*prose printers (the same collect/format splitstatus.pyuses). Only one rendering path runs per invocation.command/statuswrapper — the exit code already carries status.2. Remove the workflow project-type concept
Mirrors nvidia-holoscan/holohub#1646 ("Remove Holohub Workflow Concept Entirely"), which folded the AI Surgical Video workflow into
applications/and dropped the type — it has no meaningful difference from an application.metadata/workflow.schema.json(packaged via the*.schema.jsonglob).workflowsdir +workflowschema fromMETADATA_DIRECTORY_CONFIG,gather_metadataSCHEMA_TYPES, andmetadata_validatorKNOWN_ENVELOPES.workflowsfrom holohub root-detection and search-path dir lists, andworkflowfromPROJECT_PREFIXES.workflowfrom the benchmark-eligible project types inbuild(help text and fatal message now say "applications and benchmarks").workflowfromexternal_resolver's dependency-envelope keys and fromlist'sLIST_TYPES.Generic-English/product-name uses ("source-project workflows", "I4H Workflows") are intentionally left.
Tests
--jsonsurface —list,modes, andenv-info(parseable output, withenv-infoalso covering null sections on a tool-less host);schema_version == 1added to the existing status/env-check JSON tests.workflow.schema.jsondropped from the required-package-data set.ruff check+ruff formatclean.🤖 Generated with Claude Code