refactor(cli): overhaul help output to match gh CLI style (#423)

* refactor(cli): overhaul help output to match gh CLI style

- Add gh-style grouped help with CORE/RUNTIME/ADDITIONAL COMMANDS sections
- Use UPPERCASE section headers (USAGE, FLAGS, EXAMPLES, LEARN MORE)
- Format commands as "name:  description" with automatic alignment
- Add ENVIRONMENT VARIABLES and EXAMPLES sections to root help
- Apply consistent templates to root, subcommand, and leaf commands
- Update descriptions from "Manage X" to "Work with X" for gh parity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(execenv): add explicit instruction for agents to always use multica CLI

Agents were using curl/wget to access Multica attachment URLs directly,
which fails due to authentication. Add a prominent "Important" section
to the generated CLAUDE.md template that explicitly prohibits direct
HTTP access and instructs agents to escalate missing CLI functionality
to their workspace owner.

---------

Co-authored-by: Devv <devv@Devvs-Mac-mini.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
devv-eve 2026-04-04 15:30:40 -07:00 committed by GitHub
parent 0771c15a59
commit 52a9a6ae5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 191 additions and 21 deletions

View file

@ -17,7 +17,7 @@ import (
var agentCmd = &cobra.Command{
Use: "agent",
Short: "Manage agents",
Short: "Work with agents",
}
var agentListCmd = &cobra.Command{

View file

@ -14,7 +14,7 @@ import (
var attachmentCmd = &cobra.Command{
Use: "attachment",
Short: "Manage attachments",
Short: "Work with attachments",
}
var attachmentDownloadCmd = &cobra.Command{

View file

@ -22,7 +22,7 @@ import (
var authCmd = &cobra.Command{
Use: "auth",
Short: "Manage authentication",
Short: "Authenticate multica with Multica",
}
var authLoginCmd = &cobra.Command{

View file

@ -11,7 +11,7 @@ import (
var configCmd = &cobra.Command{
Use: "config",
Short: "Show CLI configuration",
Short: "Manage configuration for multica",
RunE: runConfigShow,
}

View file

@ -23,7 +23,7 @@ import (
var daemonCmd = &cobra.Command{
Use: "daemon",
Short: "Manage the local agent runtime daemon",
Short: "Control the local agent runtime daemon",
}
var daemonStartCmd = &cobra.Command{

View file

@ -16,7 +16,7 @@ import (
var issueCmd = &cobra.Command{
Use: "issue",
Short: "Manage issues",
Short: "Work with issues",
}
var issueListCmd = &cobra.Command{
@ -63,7 +63,7 @@ var issueStatusCmd = &cobra.Command{
var issueCommentCmd = &cobra.Command{
Use: "comment",
Short: "Manage issue comments",
Short: "Work with issue comments",
}
var issueCommentListCmd = &cobra.Command{

View file

@ -14,7 +14,7 @@ import (
var repoCmd = &cobra.Command{
Use: "repo",
Short: "Manage repositories",
Short: "Work with repositories",
}
var repoCheckoutCmd = &cobra.Command{

View file

@ -13,7 +13,7 @@ import (
var runtimeCmd = &cobra.Command{
Use: "runtime",
Short: "Manage agent runtimes",
Short: "Work with agent runtimes",
}
var runtimeListCmd = &cobra.Command{

View file

@ -16,7 +16,7 @@ import (
var skillCmd = &cobra.Command{
Use: "skill",
Short: "Manage skills",
Short: "Work with skills",
}
var skillListCmd = &cobra.Command{
@ -62,7 +62,7 @@ var skillImportCmd = &cobra.Command{
var skillFilesCmd = &cobra.Command{
Use: "files",
Short: "Manage skill files",
Short: "Work with skill files",
}
var skillFilesListCmd = &cobra.Command{

View file

@ -15,7 +15,7 @@ import (
var workspaceCmd = &cobra.Command{
Use: "workspace",
Short: "Manage workspaces",
Short: "Work with workspaces",
}
var workspaceListCmd = &cobra.Command{

142
server/cmd/multica/help.go Normal file
View file

@ -0,0 +1,142 @@
package main
import (
"fmt"
"strings"
"text/template"
"github.com/spf13/cobra"
)
// Command group IDs used across the CLI.
const (
groupCore = "core"
groupRuntime = "runtime"
groupAdditional = "additional"
)
// initHelp configures the root command to use gh-style help output.
func initHelp(root *cobra.Command) {
root.SetHelpTemplate(rootHelpTemplate)
root.SetUsageTemplate(rootHelpTemplate)
root.CompletionOptions.HiddenDefaultCmd = true
root.AddGroup(
&cobra.Group{ID: groupCore, Title: "CORE COMMANDS"},
&cobra.Group{ID: groupRuntime, Title: "RUNTIME COMMANDS"},
&cobra.Group{ID: groupAdditional, Title: "ADDITIONAL COMMANDS"},
)
// Apply gh-style templates to all commands recursively.
applyTemplates(root)
}
func applyTemplates(cmd *cobra.Command) {
for _, c := range cmd.Commands() {
if c.HasSubCommands() {
c.SetHelpTemplate(subHelpTemplate)
c.SetUsageTemplate(subHelpTemplate)
} else {
c.SetHelpTemplate(leafHelpTemplate)
c.SetUsageTemplate(leafHelpTemplate)
}
applyTemplates(c)
}
}
// formatCommandList formats a list of commands in "name: description" style
// with automatic alignment, matching gh's output.
func formatCommandList(cmds []*cobra.Command) string {
if len(cmds) == 0 {
return ""
}
maxLen := 0
for _, c := range cmds {
if c.IsAvailableCommand() && len(c.Name()) > maxLen {
maxLen = len(c.Name())
}
}
var b strings.Builder
for _, c := range cmds {
if !c.IsAvailableCommand() {
continue
}
padding := strings.Repeat(" ", maxLen-len(c.Name()))
fmt.Fprintf(&b, " %s:%s %s\n", c.Name(), padding, c.Short)
}
return b.String()
}
// commandsInGroup returns commands that belong to a specific group.
func commandsInGroup(cmds []*cobra.Command, groupID string) []*cobra.Command {
var result []*cobra.Command
for _, c := range cmds {
if c.GroupID == groupID && c.IsAvailableCommand() {
result = append(result, c)
}
}
return result
}
func init() {
cobra.AddTemplateFuncs(template.FuncMap{
"formatCommandList": formatCommandList,
"commandsInGroup": commandsInGroup,
})
}
var rootHelpTemplate = `Work seamlessly with Multica from the command line.
USAGE
multica <command> <subcommand> [flags]
{{range .Groups}}
{{.Title}}
{{formatCommandList (commandsInGroup $.Commands .ID)}}
{{- end}}
FLAGS
{{.LocalFlags.FlagUsages}}
EXAMPLES
$ multica login
$ multica issue list --output json
$ multica daemon start
$ multica agent list --output json
ENVIRONMENT VARIABLES
MULTICA_SERVER_URL Override the default server URL
MULTICA_WORKSPACE_ID Set the active workspace
LEARN MORE
Use ` + "`multica <command> <subcommand> --help`" + ` for more information about a command.
`
var subHelpTemplate = `{{.Short}}
USAGE
{{.CommandPath}} <command> [flags]
COMMANDS
{{formatCommandList .Commands}}
INHERITED FLAGS
--help Show help for command
LEARN MORE
Use ` + "`{{.CommandPath}} <command> --help`" + ` for more information about a command.
`
var leafHelpTemplate = `{{if .Long}}{{.Long}}{{else}}{{.Short}}{{end}}
USAGE
{{.UseLine}}
{{- if .HasLocalFlags}}
FLAGS
{{.LocalFlags.FlagUsages}}
{{- end}}
INHERITED FLAGS
--help Show help for command
LEARN MORE
Use ` + "`multica <command> <subcommand> --help`" + ` for more information about a command.
`

View file

@ -15,7 +15,7 @@ var (
var rootCmd = &cobra.Command{
Use: "multica",
Short: "Multica CLI — local agent runtime and management tool",
Long: "multica manages local agent runtimes and provides control commands for the Multica platform.",
Long: "Work seamlessly with Multica from the command line.",
SilenceUsage: true,
SilenceErrors: true,
}
@ -25,19 +25,40 @@ func init() {
rootCmd.PersistentFlags().String("workspace-id", "", "Workspace ID (env: MULTICA_WORKSPACE_ID)")
rootCmd.PersistentFlags().String("profile", "", "Configuration profile name (e.g. dev) — isolates config, daemon state, and workspaces")
rootCmd.AddCommand(loginCmd)
rootCmd.AddCommand(authCmd)
rootCmd.AddCommand(daemonCmd)
// Core commands
issueCmd.GroupID = groupCore
agentCmd.GroupID = groupCore
workspaceCmd.GroupID = groupCore
repoCmd.GroupID = groupCore
skillCmd.GroupID = groupCore
// Runtime commands
daemonCmd.GroupID = groupRuntime
runtimeCmd.GroupID = groupRuntime
// Additional commands
authCmd.GroupID = groupAdditional
loginCmd.GroupID = groupAdditional
attachmentCmd.GroupID = groupAdditional
configCmd.GroupID = groupAdditional
updateCmd.GroupID = groupAdditional
versionCmd.GroupID = groupAdditional
rootCmd.AddCommand(issueCmd)
rootCmd.AddCommand(agentCmd)
rootCmd.AddCommand(workspaceCmd)
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(issueCmd)
rootCmd.AddCommand(attachmentCmd)
rootCmd.AddCommand(repoCmd)
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(updateCmd)
rootCmd.AddCommand(skillCmd)
rootCmd.AddCommand(daemonCmd)
rootCmd.AddCommand(runtimeCmd)
rootCmd.AddCommand(authCmd)
rootCmd.AddCommand(loginCmd)
rootCmd.AddCommand(attachmentCmd)
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(updateCmd)
rootCmd.AddCommand(versionCmd)
initHelp(rootCmd)
}
func main() {

View file

@ -143,6 +143,13 @@ func buildMetaSkillContent(provider string, ctx TaskContextForEnv) string {
b.WriteString("This downloads the file to the current directory and prints the local path. Use `-o <dir>` to save elsewhere.\n")
b.WriteString("After downloading, you can read the file directly (e.g. view an image, read a document).\n\n")
b.WriteString("## Important: Always Use the `multica` CLI\n\n")
b.WriteString("All interactions with Multica platform resources — including issues, comments, attachments, images, files, and any other platform data — **must** go through the `multica` CLI. ")
b.WriteString("Do NOT use `curl`, `wget`, or any other HTTP client to access Multica URLs or APIs directly. ")
b.WriteString("Multica resource URLs require authenticated access that only the `multica` CLI can provide.\n\n")
b.WriteString("If you need to perform an operation that is not covered by any existing `multica` command, ")
b.WriteString("do NOT attempt to work around it. Instead, post a comment mentioning the workspace owner to request the missing functionality.\n\n")
b.WriteString("## Output\n\n")
b.WriteString("Keep comments concise and natural — state the outcome, not the process.\n")
b.WriteString("Good: \"Fixed the login redirect. PR: https://...\"\n")