newDynamicResolver constructs a cmdhelp.Resolver bound to the current pad runtime: workspace, configured server URL, and credentials. Returns nil whenever the runtime is unavailable — no config, no workspace detected, or any error during detection. nil disables dynamic resolution entirely; the help
()
| 174 | // inside the resolver itself: enum_source is announced on the binding |
| 175 | // arg/flag but Enum is left empty. |
| 176 | func newDynamicResolver() *cmdhelp.Resolver { |
| 177 | cfg, err := config.Load() |
| 178 | if err != nil || !cfg.IsConfigured() { |
| 179 | return nil |
| 180 | } |
| 181 | if urlFlag != "" { |
| 182 | cfg.URL = urlFlag |
| 183 | cfg.LoadedFromFlags = true |
| 184 | } |
| 185 | |
| 186 | ws, err := cli.DetectWorkspace(workspaceFlag) |
| 187 | if err != nil || ws == "" { |
| 188 | return nil |
| 189 | } |
| 190 | |
| 191 | client := cli.NewClientFromURL(cfg.BaseURL()) |
| 192 | |
| 193 | // Per-command bindings: --role and --assign only resolve to agent |
| 194 | // roles / workspace members on commands where that's their actual |
| 195 | // semantic. They MUST NOT bind globally because: |
| 196 | // |
| 197 | // pad workspace invite --role # workspace role: owner|editor|viewer |
| 198 | // pad item create --role <slug> # agent role slug |
| 199 | // pad item update --role <slug> # agent role slug |
| 200 | // pad item list --role <slug> # agent role filter |
| 201 | // pad item create --assign <u> # workspace member |
| 202 | // pad item update --assign <u> # workspace member |
| 203 | // pad item list --assign <u> # workspace member (filter) |
| 204 | // |
| 205 | // `--role` on `workspace invite` is intentionally left without a |
| 206 | // dynamic binding so help correctly reflects the static workspace- |
| 207 | // role enum (owner/editor/viewer) rather than agent role slugs. |
| 208 | // |
| 209 | // To find new sites if this comment goes stale: |
| 210 | // grep -nE 'Flags\(\)\.StringVar\([^,]+,\s*"(role|assign)"' cmd/pad/main.go |
| 211 | itemRoleAssign := map[string]string{ |
| 212 | "role": cmdhelp.EnumSourceRoles, |
| 213 | "assign": cmdhelp.EnumSourceMembers, |
| 214 | } |
| 215 | return &cmdhelp.Resolver{ |
| 216 | Workspace: ws, |
| 217 | // `<collection>` is unambiguous across the entire CLI — every |
| 218 | // instance refers to a pad collection. Safe to bind globally. |
| 219 | ArgEnumSources: map[string]string{ |
| 220 | "collection": cmdhelp.EnumSourceCollections, |
| 221 | }, |
| 222 | CommandFlagBindings: map[string]map[string]string{ |
| 223 | "item create": itemRoleAssign, |
| 224 | "item update": itemRoleAssign, |
| 225 | "item list": itemRoleAssign, |
| 226 | }, |
| 227 | Sources: map[string]cmdhelp.DynamicEnum{ |
| 228 | cmdhelp.EnumSourceCollections: func() ([]interface{}, error) { |
| 229 | cols, err := client.ListCollections(ws) |
| 230 | if err != nil { |
| 231 | return nil, err |
| 232 | } |
| 233 | out := make([]interface{}, 0, len(cols)) |
no test coverage detected