Skip to content

feat(monit-agent): accept --data body from stdin; drop --tool-spec DSL#34

Open
ysyneu wants to merge 1 commit into
mainfrom
feat/monit-agent-data-stdin
Open

feat(monit-agent): accept --data body from stdin; drop --tool-spec DSL#34
ysyneu wants to merge 1 commit into
mainfrom
feat/monit-agent-data-stdin

Conversation

@ysyneu
Copy link
Copy Markdown
Contributor

@ysyneu ysyneu commented Jun 5, 2026

Problem

fduty monit-agent invoke used a repeatable --tool-spec 'name=<tool>,params={json}' flag. Its parser (parseToolSpecs) did strings.Split(s, ","), which shattered any params JSON containing commas (e.g. SQL SELECT a, b), producing Error: invalid --tool-spec: missing '=' in " b". It also forced shell-quoting hell for SQL with quotes.

End-state (no transitional code)

Fold monit-agent invoke into the standard --data body convention and make the whole CLI's --data flag accept stdin.

  1. CLI-wide --data stdin source. --data - now reads the JSON body from STDIN, alongside inline --data '<json>'. Resolved once in genAssembleBody (the shared body-assembly chokepoint in gen_support.go), so all 250 generated --data commands gain it uniformly — not a per-command special case. STDIN is read only when --data is exactly -; it is never auto-read when --data is absent, so flag-only commands don't block on an empty pipe.
  2. monit-agent invoke drops the --tool-spec flag and the parseToolSpecs call. Tools are now carried in the --data body {"tools":[{"tool":"<name>","params":{...}}, ... up to 8]}, with --target-locator (required) and --target-kind (optional) staying as typed flags that stamp the body (typed flags override matching --data keys, mirroring genAssembleBody). The "max 8 tools" check and the three-layer response/error handling are unchanged. The webapi request shape is unchanged server-side — only the client-side assembly of tools changed.
  3. Deleted parseToolSpecs (and its docstring). parseKVSlice left untouched.

New invocation shape

fduty monit-agent invoke --target-locator '<loc>' [--target-kind <kind>] --data '<json>'
  <json> = {"tools":[{"tool":"<name>","params":{<obj>}}, ... up to 8]}   # params optional → {}
  --data also accepts:  -  (stdin)

# canonical heredoc form for quoted/comma SQL:
fduty monit-agent invoke --target-locator 'X' --data - <<'FDUTY'
{"tools":[{"tool":"mysql.query","params":{"sql":"SELECT a, b FROM t WHERE s='RUNNING'","max_rows":50}}]}
FDUTY

A no-arg tool: {"tools":[{"tool":"os.overview"}]}.

Verification

  • go build ./... — clean.
  • go test -race ./... — all packages pass.
  • New/updated tests in monit_agent_test.go: happy-path via --data; a regression test proving a params value with an internal comma (SELECT a, b FROM t WHERE s='RUNNING') survives intact (the exact thing that broke before); a --data - stdin test; flag-overrides---data; malformed---data table (invalid JSON, non-array tools, non-object entry, missing tool name, non-object params); >8 tools rejected; missing locator/tools rejected; and an assertion that --tool-spec no longer exists.
  • New CLI-wide tests in command_test.go on a generated command (monit datasource-list): --data - reads stdin; inline --data + typed-flag override; and a sentinel reader proving stdin is not read when --data is absent.
  • gofmt/gci/go vet clean; generated files regenerated (only the --data usage string changed — verified zero other churn).
  • Manually exercised monit-agent invoke --help: shows --data and the heredoc form, no --tool-spec. Ran a real heredoc-over-stdin invocation against a local stub and confirmed the comma+quote SQL round-tripped intact into the request body.

Note

The fc-safari monit-agent skill docs are updated in a separate PR to match this new invocation shape.

The bespoke `--tool-spec 'name=<tool>,params={json}'` parser split each spec
on ',', shattering any params JSON containing commas (e.g. SQL `SELECT a, b`)
into "missing '=' in" errors, and forced shell-quoting hell for quoted SQL.

End-state, no transitional code:

- CLI-wide: `--data` now accepts `-` to read the JSON body from STDIN, in
  addition to inline JSON. Resolved in genAssembleBody (the shared body
  chokepoint), so all generated `--data` commands gain it uniformly. STDIN is
  read ONLY when --data is exactly "-", never auto-read, so flag-only commands
  don't block on an empty pipe.
- `monit-agent invoke`: removed the `--tool-spec` flag and parseToolSpecs.
  Tools now come via the standard `--data` body
  `{"tools":[{"tool":"<name>","params":{...}}, ...]}`, with `--target-locator`
  (required) and `--target-kind` as typed flags that stamp the body. The 8-tool
  cap and three-layer error handling are unchanged; the webapi wire shape is
  unchanged server-side.
- Deleted parseToolSpecs and its docstring (parseKVSlice untouched).
- Regenerated zz_generated_*.go for the updated --data usage string.

The fc-safari monit-agent skill docs are updated in a separate PR to match.
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