Skip to content

[AISOS-2507] forge version with json option - #343

Open
forgeSmith-bot wants to merge 9 commits into
forge-sdlc:mainfrom
forgeSmith-bot:forge/aisos-2507
Open

forgeSmith-bot wants to merge 9 commits into
forge-sdlc:mainfrom
forgeSmith-bot:forge/aisos-2507

Conversation

@forgeSmith-bot

@forgeSmith-bot forgeSmith-bot commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

This pull request extends the Forge CLI with a JSON output option for the version subcommand and implements strict stdout/stderr stream isolation for clean diagnostic and payload logging. By routing all logging and auxiliary messages exclusively to stderr and outputting structured JSON to stdout, automated tooling and integrations can reliably parse command results without diagnostic pollution. These enhancements are backed by unit and integration tests, including subprocess stream separation checks and comprehensive documentation updates.

Changes

CLI Parser & Command Implementation

  • Extended CLI parser in src/forge/cli.py: Added an optional --json flag to the version subcommand parser.
  • Updated cmd_version: Implemented conditional logic to serialize package version metadata to compact JSON ({"version": <version>}) and print it with a single trailing newline when --json is supplied, while preserving original plain-text formatting otherwise.
  • Configured src/forge/__main__.py: Added package entrypoint to enable python -m forge execution.

Logging Stream Separation

  • Isolated stdout stream in setup_logging in src/forge/cli.py: Cleared pre-existing logging handlers registered on the root logger, and attached a new StreamHandler pointing exclusively to sys.stderr.
  • Rerouted auxiliary loggers: Ensured any console handlers or standard stream handlers in auxiliary loggers default strictly to sys.stderr to prevent log leakage into sys.stdout.

Testing & Infrastructure

  • Expanded CLI version tests in tests/unit/test_cli_version.py: Added unit tests utilizing pytest's capsys to verify stream isolation, compact JSON formatting, parser routing, and plain-text fallbacks.
  • Implemented subprocess-level integration tests: Added test scenarios verifying stream routing and separation under actual subprocess execution (python -m forge version).
  • Fixed pre-existing test blocker: Mocked ContainerRunner in test_implement_work.py to prevent environment-specific podman availability issues and added static type annotations.

Documentation

  • Updated docs/developer-guide.md: Documented plain-text vs. JSON output for the version command and clarified stderr logging rules.
  • Updated CLAUDE.md: Added guides for version JSON output and module execution.

Implementation Notes

  • To prevent diagnostic output from corrupting stdout streams, we clear pre-existing handlers on the root logger and configure loggers to use sys.stderr. This guarantees that stdout only ever contains the requested command payloads (such as plain-text version or JSON-serialized versions).
  • Added type annotations across the modified testing file (tests/unit/test_cli_version.py) to conform with PEP-484 and strict mypy analyses used in continuous integration.

Testing

  • Unit Testing: Verified parser configuration, default/json logic paths, and logger setup in tests/unit/test_cli_version.py using pytest.
  • Stream-Isolation Testing: Confirmed strict separation of stdout (payload) and stderr (logs) using pytest's capsys fixture.
  • Integration Testing: Verified subprocess stream separation for multiple python -m forge invocations using subprocess.run inside automated test scenarios.
  • Static Analysis: Verified that all changes pass strict mypy type checking and ruff formatting/linting rules.

Related Tickets


Generated by Forge SDLC Orchestrator

Auto-Review Notes

The following review criteria could not be resolved after all retry attempts.
Human reviewers should pay particular attention to these areas.

implement_work — AISOS-2512

Skill: implement-task | Retries: 2/2 exhausted

Verdict could not be parsed

implement_work — AISOS-2515

Skill: implement-task | Retries: 2/2 exhausted

Verdict could not be parsed

Forge added 9 commits September 15, 2026 12:05
…li.py to support --json

Detailed description:
- Extended the 'version' subcommand argument parser with the optional '--json' flag.
- Updated 'cmd_version' function to serialize the package version to compact JSON format when the flag is specified.
- Configured 'setup_logging' to direct basic logging output explicitly to sys.stderr, isolating output payload streams from diagnostic logs.
- Added comprehensive unit tests validating option parsing, compact JSON formatting, and stream isolation.

Closes: AISOS-2510
…rser routing

Detailed description:
- Added comprehensive unit and integration tests to tests/unit/test_cli_version.py.
- Verified parser routing behavior and JSON payload outputs.
- Covered edge cases where 'json' attribute is absent or explicitly False on argparse Namespace.
- Added end-to-end stream isolation tests using main() to guarantee stdout/stderr isolation.

Closes: AISOS-2512
…xclusively to sys.stderr in src/forge/cli.py

Detailed description:
- Updated setup_logging in src/forge/cli.py to clear root logger's handlers first to prevent stdout logging pollution.
- Configured a StreamHandler(sys.stderr) with custom level and the standard formatter format on the root logger.
- Added comprehensive unit tests test_setup_logging_clears_handlers_and_routes_to_stderr in tests/unit/test_cli_version.py to verify clearing, routing, leveling, and formatting.

Closes: AISOS-2513
…xclusively to sys.stderr

Detailed description:
- Updated setup_logging in src/forge/cli.py to route all CLI logs to sys.stderr and prevent stdout logging pollution.
- Cleared pre-existing logging handlers registered on the root logger, and attached a new logging.StreamHandler(sys.stderr).
- Added logic to explicitly redirect any standard console StreamHandlers pointing to sys.stdout in auxiliary loggers to sys.stderr, or remove them if propagate is True.
- Expanded tests in tests/unit/test_cli_version.py to verify that auxiliary loggers and stdout stream handlers are correctly rerouted to stderr.

Closes: AISOS-2513
…it/test_cli_version.py

Detailed description:
- Added test_default_version_stream_isolation to execute main(['version']) and verify stdout contains exactly 'Forge v<version>' while stderr remains empty.
- Added test_verbose_version_stream_isolation to execute main(['-v', 'version']) and assert that stdout has only the version payload, while stderr captures verbose logging messages.
- Added test_verbose_json_version_stream_isolation to verify that main(['-v', 'version', '--json']) prints a clean, parseable JSON payload on stdout and all auxiliary logs on stderr.
- Ensured correct setup/teardown of root logger handlers and log levels within each test to avoid test contamination or environment pollution.

Closes: AISOS-2514
…lation tests

Detailed description:
- Added comprehensive type annotations to all test functions in tests/unit/test_cli_version.py to ensure complete compliance with mypy strict type checking.
- Verified and optimized tests verifying stdout/stderr separation when executing standard version and verbose/json version command options.
- Ran formatting, linting, and tests to guarantee everything passes perfectly.

Closes: AISOS-2514
…uting tests

Detailed description:
- Created src/forge/__main__.py as the module entry point, which invokes the CLI main entrypoint, allowing python -m forge commands to be fully functional.
- Added test_subprocess_version_plain_text, test_subprocess_version_verbose_plain_text, and test_subprocess_version_verbose_json to tests/unit/test_cli_version.py to execute the CLI package via python -m forge in an actual subprocess, capturing stdout/stderr and asserting stream isolation.

Closes: AISOS-2515
…cking ContainerRunner

Detailed description:
- Mocked ContainerRunner in test_implements_resolved_task_and_marks_normalized_work_complete. This prevents podman-not-available errors when running unit tests in environments without a full podman installation.
- Added type annotations to local test helpers and mock definitions to pass strict PEP-484 mypy static type analysis.

Closes: AISOS-2507-review
Detailed description:
- Updated the Forge Version Command section in docs/developer-guide.md to detail plain-text output, --json formatted output, and module-level invocation.
- Corrected the Worker logs section in docs/developer-guide.md to indicate that logs route strictly to stderr to prevent stdout payload contamination.
- Added version JSON and module execution commands to CLAUDE.md.

Closes: AISOS-2507-docs
@forgeSmith-bot

Copy link
Copy Markdown
Collaborator Author

🤖 Reviewing a Forge pull request

To send code feedback to Forge, open Files changed, select Review changes, and submit a Request changes review. Forge will address the review feedback automatically and push updates to this pull request.

Regular comments are ignored by the review workflow. Use them for conversation or the Forge commands below:

  • /forge rebase - Merge the base branch (e.g. main) into this PR branch, with conflicts resolved by AI.
  • /forge skip-gate <name> - Skip a named CI check (substring match) for this PR. This setting persists across subsequent pushes.
  • /forge unskip-gate <name> - Remove a previously set CI check skip.

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