From 77dbcaefad3d4b8e96362ddcc2d16cb71d5e68f0 Mon Sep 17 00:00:00 2001 From: Zohar Babin Date: Mon, 13 Apr 2026 00:23:16 -0400 Subject: [PATCH 1/2] feat(cli): add --content-stdin flag to issue comment add Allow agents to pipe comment content through stdin instead of the --content flag, avoiding shell escaping issues with backticks, quotes, and other special characters in markdown content. Usage: cat <<'COMMENT' | multica issue comment add --content-stdin Co-Authored-By: Claude Opus 4.6 --- server/cmd/multica/cmd_issue.go | 13 +++++++++++-- server/internal/daemon/execenv/runtime_config.go | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/server/cmd/multica/cmd_issue.go b/server/cmd/multica/cmd_issue.go index c200a94a6..ed751dbcd 100644 --- a/server/cmd/multica/cmd_issue.go +++ b/server/cmd/multica/cmd_issue.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "io" "net/url" "os" "strings" @@ -185,7 +186,8 @@ func init() { issueRunMessagesCmd.Flags().Int("since", 0, "Only return messages after this sequence number") // issue comment add - issueCommentAddCmd.Flags().String("content", "", "Comment content (required)") + issueCommentAddCmd.Flags().String("content", "", "Comment content (required unless --content-stdin)") + issueCommentAddCmd.Flags().Bool("content-stdin", false, "Read comment content from stdin (avoids shell escaping issues)") issueCommentAddCmd.Flags().String("parent", "", "Parent comment ID (reply to a specific comment)") issueCommentAddCmd.Flags().StringSlice("attachment", nil, "File path(s) to attach (can be specified multiple times)") issueCommentAddCmd.Flags().String("output", "json", "Output format: table or json") @@ -637,8 +639,15 @@ func runIssueCommentList(cmd *cobra.Command, args []string) error { func runIssueCommentAdd(cmd *cobra.Command, args []string) error { content, _ := cmd.Flags().GetString("content") + if useStdin, _ := cmd.Flags().GetBool("content-stdin"); useStdin { + data, err := io.ReadAll(os.Stdin) + if err != nil { + return fmt.Errorf("read stdin: %w", err) + } + content = strings.TrimRight(string(data), "\n") + } if content == "" { - return fmt.Errorf("--content is required") + return fmt.Errorf("--content or --content-stdin is required") } client, err := newAPIClient(cmd) diff --git a/server/internal/daemon/execenv/runtime_config.go b/server/internal/daemon/execenv/runtime_config.go index dd9a264d5..b3e2d692b 100644 --- a/server/internal/daemon/execenv/runtime_config.go +++ b/server/internal/daemon/execenv/runtime_config.go @@ -61,6 +61,7 @@ func buildMetaSkillContent(provider string, ctx TaskContextForEnv) string { b.WriteString("- `multica issue create --title \"...\" [--description \"...\"] [--priority X] [--assignee X] [--parent ] [--status X]` — Create a new issue\n") b.WriteString("- `multica issue assign --to ` — Assign an issue to a member or agent by name (use --unassign to remove assignee)\n") b.WriteString("- `multica issue comment add --content \"...\" [--parent ]` — Post a comment (use --parent to reply to a specific comment)\n") + b.WriteString(" - For content with special characters (backticks, quotes), pipe via stdin: `cat <<'COMMENT' | multica issue comment add --content-stdin`\n") b.WriteString("- `multica issue comment delete ` — Delete a comment\n") b.WriteString("- `multica issue status ` — Update issue status (todo, in_progress, in_review, done, blocked)\n") b.WriteString("- `multica issue update [--title X] [--description X] [--priority X]` — Update issue fields\n\n") From d37595b85e8ab0e721ab39f0212fcbaeddee2bee Mon Sep 17 00:00:00 2001 From: Zohar Babin Date: Mon, 13 Apr 2026 19:14:55 -0400 Subject: [PATCH 2/2] fix(cli): address review feedback on --content-stdin flag - Make --content and --content-stdin mutually exclusive with explicit error - Use TrimSuffix instead of TrimRight to only strip the trailing newline - Return "stdin content is empty" instead of misleading "required" error Co-Authored-By: Claude Opus 4.6 --- server/cmd/multica/cmd_issue.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/server/cmd/multica/cmd_issue.go b/server/cmd/multica/cmd_issue.go index ed751dbcd..5e153241d 100644 --- a/server/cmd/multica/cmd_issue.go +++ b/server/cmd/multica/cmd_issue.go @@ -639,13 +639,23 @@ func runIssueCommentList(cmd *cobra.Command, args []string) error { func runIssueCommentAdd(cmd *cobra.Command, args []string) error { content, _ := cmd.Flags().GetString("content") - if useStdin, _ := cmd.Flags().GetBool("content-stdin"); useStdin { + useStdin, _ := cmd.Flags().GetBool("content-stdin") + + if content != "" && useStdin { + return fmt.Errorf("--content and --content-stdin are mutually exclusive") + } + + if useStdin { data, err := io.ReadAll(os.Stdin) if err != nil { return fmt.Errorf("read stdin: %w", err) } - content = strings.TrimRight(string(data), "\n") + content = strings.TrimSuffix(string(data), "\n") + if content == "" { + return fmt.Errorf("stdin content is empty") + } } + if content == "" { return fmt.Errorf("--content or --content-stdin is required") }