@@ -113,8 +113,7 @@ type ProviderConfig struct {
113 // $(cmd) work the same way they do in MCP headers. A header whose
113 // $(cmd) work the same way they do in MCP headers. A header whose
114 // value resolves to the empty string (unset bare $VAR under
114 // value resolves to the empty string (unset bare $VAR under
115 // lenient nounset, $(echo), or literal "") is omitted from the
115 // lenient nounset, $(echo), or literal "") is omitted from the
116− // outgoing request rather than sent as "Header:". See PLAN.md
116+ // outgoing request rather than sent as "Header:".
117− // Phase 2 design decision #18.
118 ExtraHeaders map[string]string `json:"extra_headers,omitempty" jsonschema:"description=Additional HTTP headers to send with requests"`
117 ExtraHeaders map[string]string `json:"extra_headers,omitempty" jsonschema:"description=Additional HTTP headers to send with requests"`
119 // ExtraBody is merged verbatim into OpenAI-compatible request
118 // ExtraBody is merged verbatim into OpenAI-compatible request
120 // bodies. String values are NOT shell-expanded: this is a plain
119 // bodies. String values are NOT shell-expanded: this is a plain
@@ -123,7 +122,7 @@ type ProviderConfig struct {
123 // recursive walker guessing at intent. If you need an env-var-
122 // recursive walker guessing at intent. If you need an env-var-
124 // driven value at request time, put it in extra_headers, or in
123 // driven value at request time, put it in extra_headers, or in
125 // the provider's top-level api_key / base_url, all of which do
124 // the provider's top-level api_key / base_url, all of which do
126− // expand. See PLAN.md Phase 2 design decision #16.
125+ // expand.
127 ExtraBody map[string]any `json:"extra_body,omitempty" jsonschema:"description=Additional fields to include in request bodies\\, only works with openai-compatible providers"`
126 ExtraBody map[string]any `json:"extra_body,omitempty" jsonschema:"description=Additional fields to include in request bodies\\, only works with openai-compatible providers"`
129 ProviderOptions map[string]any `json:"provider_options,omitempty" jsonschema:"description=Additional provider-specific options for this provider"`
128 ProviderOptions map[string]any `json:"provider_options,omitempty" jsonschema:"description=Additional provider-specific options for this provider"`
@@ -196,7 +195,7 @@ type MCPConfig struct {
196 // work. A header whose value resolves to the empty string (unset
195 // work. A header whose value resolves to the empty string (unset
197 // bare $VAR under lenient nounset, $(echo), or literal "") is
196 // bare $VAR under lenient nounset, $(echo), or literal "") is
198 // omitted from the outgoing request rather than sent as
197 // omitted from the outgoing request rather than sent as
199− // "Header:". See PLAN.md Phase 2 design decision #18.
198+ // "Header:".
200 Headers map[string]string `json:"headers,omitempty" jsonschema:"description=HTTP headers for HTTP/SSE MCP servers"`
199 Headers map[string]string `json:"headers,omitempty" jsonschema:"description=HTTP headers for HTTP/SSE MCP servers"`
@@ -398,8 +397,7 @@ func (m MCPConfig) ResolvedURL(r VariableResolver) (string, error) {
398// under lenient nounset, $(echo), or literal "") is omitted from the
397// under lenient nounset, $(echo), or literal "") is omitted from the
399// returned map — sending "X-Auth:" with an empty value is rejected by
398// returned map — sending "X-Auth:" with an empty value is rejected by
400// some providers and the user's intent in "optional, env-gated
399// some providers and the user's intent in "optional, env-gated
401−// header" is clearly "absent when the var isn't set." See PLAN.md
400+// header" is clearly "absent when the var isn't set."
402−// Phase 2 design decision #18.
404// See ResolvedEnv for guidance on picking a resolver.
402// See ResolvedEnv for guidance on picking a resolver.
405func (m MCPConfig) ResolvedHeaders(r VariableResolver) (map[string]string, error) {
403func (m MCPConfig) ResolvedHeaders(r VariableResolver) (map[string]string, error) {
@@ -435,13 +433,11 @@ func (m MCPConfig) ResolvedHeaders(r VariableResolver) (map[string]string, error
435// errors.Is/As continues to work.
433// errors.Is/As continues to work.
437// Empty resolved values are kept (a deliberate "empty positional arg"
435// Empty resolved values are kept (a deliberate "empty positional arg"
438−// like --flag "" is sometimes valid), matching MCPConfig.ResolvedArgs;
436+// like --flag "" is sometimes valid), matching MCPConfig.ResolvedArgs.
439−// see PLAN.md Phase 2 design decision #18.
441// The resolver choice matters: in server mode pass the shell resolver
438// The resolver choice matters: in server mode pass the shell resolver
442// so $VAR / $(cmd) expand; in client mode pass IdentityResolver so the
439// so $VAR / $(cmd) expand; in client mode pass IdentityResolver so the
443−// template is forwarded verbatim. See PLAN.md Phase 2 design decision
440+// template is forwarded verbatim.
445func (l LSPConfig) ResolvedArgs(r VariableResolver) ([]string, error) {
441func (l LSPConfig) ResolvedArgs(r VariableResolver) ([]string, error) {
446 if len(l.Args) == 0 {
442 if len(l.Args) == 0 {
447 return nil, nil
443 return nil, nil
@@ -465,15 +461,13 @@ func (l LSPConfig) ResolvedArgs(r VariableResolver) ([]string, error) {
465// continues to work.
461// continues to work.
467// Empty resolved values are kept ("FOO=" is a legitimate request;
463// Empty resolved values are kept ("FOO=" is a legitimate request;
468−// opt out via ${VAR:+...}), matching MCPConfig.ResolvedEnv; see
464+// opt out via ${VAR:+...}), matching MCPConfig.ResolvedEnv.
469−// PLAN.md Phase 2 design decision #18.
471// Shape note: this returns map[string]string rather than the []string
466// Shape note: this returns map[string]string rather than the []string
472// shape MCPConfig.ResolvedEnv uses because the consumer
467// shape MCPConfig.ResolvedEnv uses because the consumer
473// (powernap.ClientConfig.Environment in internal/lsp/client.go) takes
468// (powernap.ClientConfig.Environment in internal/lsp/client.go) takes
474// a map directly — returning a []string here would only force a
469// a map directly — returning a []string here would only force a
475−// round-trip back to a map at the call site. See PLAN.md Phase 2
470+// round-trip back to a map at the call site.
476−// design decision #13.
478// See ResolvedArgs for guidance on picking a resolver.
472// See ResolvedArgs for guidance on picking a resolver.
479func (l LSPConfig) ResolvedEnv(r VariableResolver) (map[string]string, error) {
473func (l LSPConfig) ResolvedEnv(r VariableResolver) (map[string]string, error) {