Update bundled glab SKILL.md: add Comments section and `glab api` content-type guidance
## Context While running a Duo Developer agent session (analysed in [gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#2298 (note)](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/work_items/2298#note_3371221221)), the agent wasted ~5 tool calls trying to post a discussion reply via `glab` before falling back to `curl`. The [bundled glab skill](https://gitlab.com/gitlab-org/cli/-/blob/main/internal/commands/skills/bundled/assets/glab/SKILL.md) is missing a few details that would have let it succeed on the first attempt. ## Evidence — what actually failed | Step | Approach | Failure | |------|----------|---------| | 56 | `glab issue note` without `-m` | glab interpreted body text as a **filename** | | 58 | `glab api --input file.json` | `HTTP 415` — `--input` doesn't set `Content-Type` header | | 59 | `curl` with explicit headers | ✅ Worked | ## Proposed skill additions ### a) Comments and discussions section Comments work the same way across issues, MRs, and incidents, but only `glab mr note` supports threaded replies natively. The skill should document the full surface in one place: ````markdown ## Comments and discussions Always pass `-m` — without it, the next argument is treated as a filename. ```shell # Root-level comments (issue / mr / incident) glab issue note <iid> -m "comment text" glab mr note <iid> -m "comment text" glab incident note <iid> -m "comment text" # Long/markdown body — single-quoted heredoc keeps backticks, $, \ literal glab mr note <iid> -m "$(cat << 'EOF' Your **markdown** comment. Code blocks and `inline code` are safe. EOF )" # Cross-project glab mr note <iid> -m "..." --repo group/project ``` ### Threaded replies `glab mr note create` supports `--reply <discussion-id>` (full ID or 8+ char prefix) for replying inside an MR thread, plus diff comments and thread state management: ```shell glab mr note create <iid> --reply abc12345 -m "I agree!" glab mr note create <iid> --file main.go --line 42 -m "Needs refactoring" glab mr note resolve <iid> <discussion-id> glab mr note reopen <iid> <discussion-id> ``` For issues, incidents, and work items addressed by IID, the CLI does not wrap threaded replies. Fall back to `glab api` with the REST discussions endpoint: ```shell glab api projects/:id/issues/<iid>/discussions/<discussion-id>/notes \ -f body="reply text" ``` ```` ### b) Prefer the heredoc pattern over the temp-file pattern elsewhere in the skill The skill currently recommends `$(cat /tmp/file.md)` for `glab issue create`, `glab mr create`, and `glab mr update` descriptions, with a note to use `<< 'EOF'` only when the content contains backticks or `$`. In practice for agent usage, single-quoted heredoc is the safer default for any markdown body: - No escape bugs from backticks, `$`, or backslashes in code blocks - No separate file-write tool call - No stale tempfile state between commands Possible flaws worth discussing: - Very large bodies may approach shell command-length limits (rare for issue/MR descriptions) - The body isn't reusable across multiple commands and can't be inspected after the fact Proposal: update the `--description "$(cat /tmp/desc.md)"` examples in the quick reference (and the related "Common mistakes" bullet) to use the heredoc form, and keep the temp-file form as the fallback for very long or reusable content. ### c) Add to "Common mistakes" ```markdown - **`glab issue note` requires `-m`** — without it, the next argument is treated as a filename, not the comment text. - **`glab issue note` and `glab incident note` only post root-level comments** — use `glab mr note create --reply` for MRs, or `glab api .../discussions/<id>/notes -f body=...` for issues/incidents. ``` ### d) API content-type guidance ````markdown When POSTing with `glab api`, know the difference between `-f` and `-F`: ```shell # -f (--raw-field) — value is always a literal string glab api projects/:id/issues/:iid/notes -f body="comment text" # -F (--field) — @file reads from file, auto-infers types glab api projects/:id/issues/:iid/notes -F body=@/tmp/comment.md # ⚠️ --input sends raw bytes — requires explicit Content-Type header glab api ... --input file.json -H "Content-Type: application/json" ``` ```` ## Out of scope (follow-ups) - Adding `--reply` / `list` / `resolve` parity to `glab issue note` and `glab incident note` so the API fallback isn't needed. Tracked separately. - Threaded notes on **epics as work items** (REST epics API deprecated in 17.0, requires GraphQL). Not common enough in agent flows to warrant skill space yet. /cc @thomas-schmidt
issue