@@ -54,15 +54,16 @@ var containerApps = map[string]containerApp{
5454
5555// hostApp describes a native CLI app launched on the host.
5656type hostApp struct {
57- envFn func (baseURL string ) []string
57+ envFn func (baseURL string ) []string
58+ configInstructions func (baseURL string ) []string // for apps that need manual config
5859}
5960
6061// hostApps are launched as native executables on the host.
6162var hostApps = map [string ]hostApp {
6263 "opencode" : {envFn : openaiEnv (openaiPathSuffix )},
6364 "codex" : {envFn : openaiEnv ("/v1" )},
6465 "claude" : {envFn : anthropicEnv },
65- "clawdbot" : {envFn : nil },
66+ "clawdbot" : {configInstructions : clawdbotConfigInstructions },
6667}
6768
6869// supportedApps is derived from the registries above.
@@ -198,18 +199,18 @@ func launchContainerApp(cmd *cobra.Command, ca containerApp, baseURL string, ima
198199// launchHostApp launches a native host app executable.
199200func launchHostApp (cmd * cobra.Command , bin string , baseURL string , cli hostApp , appArgs []string , dryRun bool ) error {
200201 if _ , err := exec .LookPath (bin ); err != nil {
201- cmd .Printf ("%q executable not found in PATH.\n " , bin )
202+ cmd .PrintErrf ("%q executable not found in PATH.\n " , bin )
202203 if cli .envFn != nil {
203- cmd .Printf ("Configure your app to use:\n " )
204+ cmd .PrintErrf ("Configure your app to use:\n " )
204205 for _ , e := range cli .envFn (baseURL ) {
205- cmd .Printf (" %s\n " , e )
206+ cmd .PrintErrf (" %s\n " , e )
206207 }
207208 }
208209 return fmt .Errorf ("%s not found; please install it and re-run" , bin )
209210 }
210211
211212 if cli .envFn == nil {
212- return launchUnconfigurableHostApp (cmd , bin , baseURL , dryRun )
213+ return launchUnconfigurableHostApp (cmd , bin , baseURL , cli , dryRun )
213214 }
214215
215216 env := cli .envFn (baseURL )
@@ -224,24 +225,35 @@ func launchHostApp(cmd *cobra.Command, bin string, baseURL string, cli hostApp,
224225}
225226
226227// launchUnconfigurableHostApp handles host apps that need manual config rather than env vars.
227- func launchUnconfigurableHostApp (cmd * cobra.Command , bin string , baseURL string , dryRun bool ) error {
228+ func launchUnconfigurableHostApp (cmd * cobra.Command , bin string , baseURL string , cli hostApp , dryRun bool ) error {
228229 enginesEP := baseURL + openaiPathSuffix
229230 cmd .Printf ("Configure %s to use Docker Model Runner:\n " , bin )
230231 cmd .Printf (" Base URL: %s\n " , enginesEP )
231232 cmd .Printf (" API type: openai-completions\n " )
232- cmd .Printf (" API key: docker-model-runner\n " )
233- if bin == "clawdbot" {
233+ cmd .Printf (" API key: %s\n " , dummyAPIKey )
234+
235+ if cli .configInstructions != nil {
234236 cmd .Printf ("\n Example:\n " )
235- cmd . Printf ( " clawdbot config set models.providers.docker-model-runner.baseUrl %q \n " , enginesEP )
236- cmd .Printf (" clawdbot config set models.providers.docker-model-runner.api openai-completions \n " )
237- cmd . Printf ( " clawdbot config set models.providers.docker-model-runner.apiKey docker-model-runner \n " )
237+ for _ , line := range cli . configInstructions ( baseURL ) {
238+ cmd .Printf (" %s \n " , line )
239+ }
238240 }
239241 if dryRun {
240242 return nil
241243 }
242244 return runExternal (cmd , nil , bin )
243245}
244246
247+ // clawdbotConfigInstructions returns configuration commands for clawdbot.
248+ func clawdbotConfigInstructions (baseURL string ) []string {
249+ ep := baseURL + openaiPathSuffix
250+ return []string {
251+ fmt .Sprintf ("clawdbot config set models.providers.docker-model-runner.baseUrl %q" , ep ),
252+ "clawdbot config set models.providers.docker-model-runner.api openai-completions" ,
253+ fmt .Sprintf ("clawdbot config set models.providers.docker-model-runner.apiKey %s" , dummyAPIKey ),
254+ }
255+ }
256+
245257// openaiEnv returns an env builder that sets OpenAI-compatible
246258// environment variables using the given path suffix.
247259func openaiEnv (suffix string ) func (string ) []string {
@@ -280,6 +292,8 @@ func withEnv(extra ...string) []string {
280292}
281293
282294// runExternal executes a program inheriting stdio.
295+ // Security: prog and progArgs are either hardcoded values or user-provided
296+ // arguments that the user explicitly intends to pass to the launched app.
283297func runExternal (cmd * cobra.Command , env []string , prog string , progArgs ... string ) error {
284298 c := exec .Command (prog , progArgs ... )
285299 c .Stdout = cmd .OutOrStdout ()
0 commit comments