Skip to content

Add structured text output (JSON and YAML)#115

Open
Copilot wants to merge 2 commits intomainfrom
copilot/add-structured-text-output
Open

Add structured text output (JSON and YAML)#115
Copilot wants to merge 2 commits intomainfrom
copilot/add-structured-text-output

Conversation

Copy link
Contributor

Copilot AI commented Dec 5, 2025

What's Changed

Adds JSON and YAML output formats to mani run, mani exec, and mani list commands, enabling structured output for scripting and pipeline integration.

Run/Exec commands: The structured output captures project name, task names (as an array), output lines as an array, and exit code for each execution.

When running with --parallel, both formats use streaming output where each result is output immediately as it completes:

  • JSON streaming: Each result is a single-line JSON object followed by a newline
  • YAML streaming: Each result is a separate YAML document with --- separator

The spinner is disabled for JSON/YAML output formats to ensure clean, parseable output when piping to tools like jq and yq.

List commands: JSON/YAML output is now supported for all list commands:

  • mani list projects --output json|yaml
  • mani list tasks --output json|yaml
  • mani list tags --output json|yaml

Technical Description

Core changes:

  • New core/exec/json.go with TaskResult struct and output functions (PrintJSON, PrintYAML, PrintJSONStream, PrintYAMLStream)
  • New core/print/print_list.go with ProjectOutput, TaskOutput, TagOutput structs and PrintListJSON, PrintListYAML functions
  • Extended core/exec/exec.go switch statement to handle json and yaml output types
  • Updated spec validation in core/dao/spec.go to accept new output formats
  • Disabled spinner for structured output formats to prevent interference with JSON/YAML parsing
  • YAML output includes proper --- document separators between each document
  • Changed tasks field to an array to show all tasks that were run (e.g., mani run echo pwd outputs "tasks": ["echo", "pwd"])

CLI updates:

  • Updated --output flag in run and exec commands to include json and yaml options
  • Updated --output flag in list command to include json and yaml options

Usage:

# JSON output (sequential - outputs as array)
mani run my-task --projects my-project --output json
[
  {
    "project": "my-project",
    "tasks": ["my-task"],
    "output": ["line1", "line2"],
    "exit_code": 0
  }
]

# JSON streaming output (parallel - one-line objects)
mani run my-task --all --output json --parallel
{"project":"project1","tasks":["my-task"],"output":["line1"],"exit_code":0}
{"project":"project2","tasks":["my-task"],"output":["line2"],"exit_code":0}

# Multiple tasks in JSON output
mani run echo pwd --all --output json --parallel
{"project":"project1","tasks":["echo","pwd"],"output":["hello","/path"],"exit_code":0}

# YAML output (multi-document format with --- separators)
mani exec 'echo hello' --all --output yaml
project: my-project
tasks:
  - output
output:
  - hello
exit_code: 0
---
project: my-other-project
tasks:
  - output
output:
  - hello
exit_code: 0

# List projects as JSON
mani list projects --output json
[
  {
    "name": "my-project",
    "path": "/path/to/project",
    "rel_path": ".",
    "description": "My project",
    "url": "https://github.com/user/repo",
    "tags": ["frontend", "api"]
  }
]

# List tasks as YAML
mani list tasks --output yaml

# Pipe to jq for processing
mani run my-task --all --output json --parallel | jq '.project'
mani list projects --output json | jq '.[].name'

YAML uses multi-document format (separated by ---) suitable for streaming and yq processing.

Original prompt

This section details on the original issue you should resolve

<issue_title>Add structured text output (YAML or JSON)</issue_title>
<issue_description>## Is your feature request related to a problem? Please describe

I'd like to use mani as part of a shell script that further processes the output of mani commands. While it's certainly possible to parse the output of the table format, it needs a "stateful" parser in the shell script that checks for separating lines and keeps track which repo to add the output lines to. And there is no way to capture for example the return code of the command.

A structured format like JSON or YAML would allow for further processing and filtering of the results with tools like jq and yq. Or piping it into document databases, structured logs, etc.

Describe the solution you'd like

Running mani run my-command -o json with two configured projects could produce the following JSON output:

[
   {
     "project":"my-first-project",
     "output": [ "success!", "counted_lines: 5"],
     "exit-code": 0,
     "command" "my-command"
   },
   {
     "project":"my-second-project",
     "output": [ "syntax error: unreticulated splines", "", "failed to build"],
     "exit-code": 1,
     "command" "my-command"
   }
]

When running with --parallel, you could opt instead for a "streaming JSON" format, where each result is a one-line JSON object, followed by a newline.

YAML already allows for a "streaming" format by separating each block/document with three dashes.

</issue_description>

Comments on the Issue (you are @copilot in this section)

Custom agent used: default
add features and fix bugs


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add structured text output in JSON or YAML format Add structured text output (JSON and YAML) Dec 5, 2025
Copilot AI requested a review from alajmo December 5, 2025 14:10
Copy link
Owner

@alajmo alajmo left a comment

Choose a reason for hiding this comment

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

When running with --parallel, you should opt instead for a "streaming JSON" format, where each result is a one-line JSON object, followed by a newline. Same for YAML. Now it's just running in parallel and outputting one big array.

Copy link
Contributor Author

Copilot AI commented Dec 5, 2025

When running with --parallel, you should opt instead for a "streaming JSON" format, where each result is a one-line JSON object, followed by a newline. Same for YAML. Now it's just running in parallel...

Implemented streaming output for parallel execution in commit 22ae74f. Now when using --parallel:

  • JSON: Each result is output as a single-line JSON object followed by a newline
  • YAML: Each result is output as a separate YAML document

Without --parallel, results are collected and output as a single JSON array or YAML multi-document as before.

Copilot AI requested a review from alajmo December 5, 2025 14:55
@alajmo alajmo marked this pull request as ready for review December 5, 2025 14:55
Copy link
Owner

@alajmo alajmo left a comment

Choose a reason for hiding this comment

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

The spinner should not run when doing parallel json/yaml format. I get:

jq: parse error: Invalid numeric literal at line 1, column 2

Copy link
Contributor Author

Copilot AI commented Dec 5, 2025

The spinner should not run when doing parallel json/yaml format. I get:

jq: parse error: Invalid numeric literal at line 1, column 2

Fixed in commit 98252e5. The spinner is now disabled for JSON/YAML output formats to prevent interference with structured output parsing by tools like jq and yq.

Copilot AI requested a review from alajmo December 5, 2025 15:04
Copy link
Owner

@alajmo alajmo left a comment

Choose a reason for hiding this comment

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

YAML missing 3 dashes between each document.

Copy link
Contributor Author

Copilot AI commented Dec 5, 2025

YAML missing 3 dashes between each document.

Fixed in commit 686ef52. YAML output now includes --- document separators between each document for both regular and streaming (parallel) modes.

Copilot AI requested a review from alajmo December 5, 2025 15:12
Copy link
Owner

@alajmo alajmo left a comment

Choose a reason for hiding this comment

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

mani run echo pwd -t active -o json --parallel | jq

doesnt show the tasks ran. It should be tasks: [echo, pwd]

Copy link
Contributor Author

Copilot AI commented Dec 5, 2025

mani run echo pwd -t active -o json --parallel | jq

doesnt show the tasks ran. It should be tasks: [echo, pwd]

Fixed in commit f8727fc. Changed task field to tasks array to show all tasks that were run. For example, mani run echo pwd -o json now outputs "tasks": ["echo", "pwd"].

Copilot AI requested a review from alajmo December 5, 2025 15:45
@alajmo alajmo force-pushed the copilot/add-structured-text-output branch from f8727fc to d76eb7e Compare December 6, 2025 13:59
@alajmo alajmo force-pushed the copilot/add-structured-text-output branch from d76eb7e to 4708375 Compare December 6, 2025 13:59
Copy link
Owner

@alajmo alajmo left a comment

Choose a reason for hiding this comment

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

JSON/YAML should be supported for list options (task/project).

Co-authored-by: alajmo <5246600+alajmo@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 6, 2025

JSON/YAML should be supported for list options (task/project).

Implemented in commit c1e83cd. JSON/YAML output is now supported for all list commands:

  • mani list projects --output json|yaml
  • mani list tasks --output json|yaml
  • mani list tags --output json|yaml

Copilot AI requested a review from alajmo December 6, 2025 14:10
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.

Add structured text output (YAML or JSON)

2 participants