aitools: add --output json to install - #6481
Conversation
583618b to
5dbbee3
Compare
rugpanov
left a comment
There was a problem hiding this comment.
Automated multi-reviewer pass (Isaac, Codex, and Claude reviewers, cross-checked against the code). The feature itself is sound and mirrors aitools list --output json. Inline comments below; a few findings that don't anchor to a changed line:
[nice to have] --path + --output json silently ignores JSON (cmd/aitools/install.go:124) — the --path block returns before the jsonMode check (:138) and render (:197), so install --path DIR --output json does a text dump with exit 0 and no JSON. --skills-only+--path is already rejected at :105; per CLAUDE.md's "reject incompatible inputs early" rule, either reject this combination or honor JSON in the dump path.
[nice to have] Coverage / convention gaps — (1) no .nextchanges/cli/ changelog fragment for this user-visible output mode (the analogous aitools list --output json, #5233, shipped one; not CI-blocking but expected by .agents/rules/changelog.md); (2) only unit tests were added — .agents/rules/testing.md prefers acceptance coverage for user-visible output, and the suite already exists at acceptance/experimental/aitools/skills/install/. An acceptance case would also have caught the stderr finding below, since it runs the real binary through root.Execute.
[nit] Help text (cmd/aitools/install.go:83) — the Long help / "Escape hatches" list doesn't mention --output json or its --scope+--agents requirement, so users hit the error only at runtime.
0f9f04a to
af4bb2a
Compare
Add JSON output to `aitools install`, driven entirely by flags so the run is fully non-interactive: require --scope and --agents (erroring and naming the missing flags otherwise) so no scope prompt, agent picker, or confirm is shown. executePlan now returns a per-agent outcome (name, delivery, status, message) that the JSON payload lists. A top-level failure with no per-agent entry (e.g. a skills-group install failure) is surfaced in a top-level "error" field; per-agent failures stay in their agent entry and are not duplicated there (executePlan wraps them so the two are distinguishable). Once the JSON result is rendered, silence cobra's text "Error:"/usage output so a failure is not reported twice; the non-zero exit still comes from returning the run error. Share the indented-JSON encoder between install and list as renderJSON. Co-authored-by: Isaac <no-reply@databricks.com>
af4bb2a to
047ee54
Compare
The changelog validator now requires each fragment to be a single line starting with a `* ` bullet and ending with a period before the trailing PR link group. Reformat the install --output json fragment accordingly. Co-authored-by: Isaac <no-reply@databricks.com>
Integration test reportCommit: 28dd936
Top 6 slowest tests (at least 2 minutes):
|
--output json is meant to emit only the structured JSON document, but the
installer still wrote progress lines ("Using skills version", "Fetching
skills manifest...", "Installed N skills.") to stderr, so a consumer saw
non-JSON interleaved with the result. Mark the context quiet in JSON mode
and route those library messages through cmdio.LogProgress, which respects
it. Text mode is unaffected. Update the acceptance test to use the
non-deprecated `aitools install` and assert only JSON is emitted.
Co-authored-by: Isaac <no-reply@databricks.com>
rugpanov
left a comment
There was a problem hiding this comment.
Approving. The blocking issue from the earlier pass (a failed --output json run printing a duplicate Error: line — SilenceErrors is a no-op since root prints errors itself) is fixed correctly via root.ErrAlreadyPrinted, and it's now covered end-to-end through root.Execute (TestInstallOutputJSONThroughRoot). --path + --output json is rejected, the changelog fragment and acceptance test are in, and a fresh multi-reviewer round found nothing blocking. installOutputIsJSON keeping its own nil-safe check (rather than root.OutputType) is justified by the detached legacy skills install alias — confirmed.
One non-blocking cleanup you can take or defer: executePlan's quiet bool duplicates the cmdio.WithQuiet/LogProgress mechanism this PR already uses in the installer — converting its progress LogString calls to LogProgress would drop the param and its guards with no behavior change. LGTM either way.
Integration test reportCommit: dc00178
697 interesting tests: 631 MISS, 65 FAIL, 1 SKIP
Top 50 slowest tests (at least 2 minutes):
|
Changes
Add
--output jsontoaitools install. This requires--scopeand--agentsto avoid needing to prompt users on stdoutWhy
Needed for #6482
Tests
Added unit tests