@@ -44,14 +44,14 @@ func getSelectionOptions(categoryID string) []promptObject {
4444 },
4545 },
4646 "slack-cli#ai-apps" : {
47- {
48- Title : fmt .Sprintf ("Support Agent %s" , style .Secondary ("Resolve IT support cases" )),
49- Repository : "slack-cli#ai-apps/support-agent" ,
50- },
5147 {
5248 Title : fmt .Sprintf ("Starter Agent %s" , style .Secondary ("Start from scratch" )),
5349 Repository : "slack-cli#ai-apps/starter-agent" ,
5450 },
51+ {
52+ Title : fmt .Sprintf ("Support Agent %s" , style .Secondary ("Resolve IT support cases" )),
53+ Repository : "slack-cli#ai-apps/support-agent" ,
54+ },
5555 },
5656 "slack-cli#automation-apps" : {
5757 {
@@ -71,38 +71,96 @@ func getSelectionOptions(categoryID string) []promptObject {
7171 return templatePromptObjects [categoryID ]
7272}
7373
74- // getFrameworkOptions returns the framework choices for a given template.
74+ // getFrameworkOptions returns the framework choices for a given AI app template.
7575func getFrameworkOptions (template string ) []promptObject {
7676 frameworkPromptObjects := map [string ][]promptObject {
7777 "slack-cli#ai-apps/support-agent" : {
7878 {
79- Title : fmt .Sprintf ("Claude Agent SDK %s" , style .Secondary ("Bolt for Python" )),
79+ Title : fmt .Sprintf ("Bolt for JavaScript %s" , style .Secondary ("Support Agent" )),
80+ Repository : "slack-cli#ai-apps/support-agent/bolt-js" ,
81+ },
82+ {
83+ Title : fmt .Sprintf ("Bolt for Python %s" , style .Secondary ("Support Agent" )),
84+ Repository : "slack-cli#ai-apps/support-agent/bolt-python" ,
85+ },
86+ },
87+ "slack-cli#ai-apps/starter-agent" : {
88+ {
89+ Title : fmt .Sprintf ("Bolt for JavaScript %s" , style .Secondary ("Starter Agent" )),
90+ Repository : "slack-cli#ai-apps/starter-agent/bolt-js" ,
91+ },
92+ {
93+ Title : fmt .Sprintf ("Bolt for Python %s" , style .Secondary ("Starter Agent" )),
94+ Repository : "slack-cli#ai-apps/starter-agent/bolt-python" ,
95+ },
96+ },
97+ }
98+ return frameworkPromptObjects [template ]
99+ }
100+
101+ // getAdapterOptions returns the AI agent framework choices for a given template and framework.
102+ func getAdapterOptions (framework string ) []promptObject {
103+ adapterPromptObjects := map [string ][]promptObject {
104+ "slack-cli#ai-apps/support-agent/bolt-js" : {
105+ {
106+ Title : fmt .Sprintf ("Claude Agent SDK %s" , style .Secondary ("Bolt for JavaScript - Support Agent" )),
107+ Repository : "slack-samples/bolt-js-support-agent" ,
108+ Subdir : "claude-agent-sdk" ,
109+ },
110+ {
111+ Title : fmt .Sprintf ("OpenAI Agents SDK %s" , style .Secondary ("Bolt for JavaScript - Support Agent" )),
112+ Repository : "slack-samples/bolt-js-support-agent" ,
113+ Subdir : "openai-agents-sdk" ,
114+ },
115+ },
116+ "slack-cli#ai-apps/support-agent/bolt-python" : {
117+ {
118+ Title : fmt .Sprintf ("Claude Agent SDK %s" , style .Secondary ("Bolt for Python - Support Agent" )),
80119 Repository : "slack-samples/bolt-python-support-agent" ,
81120 Subdir : "claude-agent-sdk" ,
82121 },
83122 {
84- Title : fmt .Sprintf ("OpenAI Agents SDK %s" , style .Secondary ("Bolt for Python" )),
123+ Title : fmt .Sprintf ("OpenAI Agents SDK %s" , style .Secondary ("Bolt for Python - Support Agent " )),
85124 Repository : "slack-samples/bolt-python-support-agent" ,
86125 Subdir : "openai-agents-sdk" ,
87126 },
88127 {
89- Title : fmt .Sprintf ("Pydantic AI %s" , style .Secondary ("Bolt for Python" )),
128+ Title : fmt .Sprintf ("Pydantic AI %s" , style .Secondary ("Bolt for Python - Support Agent " )),
90129 Repository : "slack-samples/bolt-python-support-agent" ,
91130 Subdir : "pydantic-ai" ,
92131 },
93132 },
94- "slack-cli#ai-apps/starter-agent" : {
133+ "slack-cli#ai-apps/starter-agent/bolt-js " : {
95134 {
96- Title : fmt .Sprintf ("Bolt for JavaScript %s" , style .Secondary ("Node.js " )),
135+ Title : fmt .Sprintf ("Claude Agent SDK %s" , style .Secondary ("Bolt for JavaScript - Starter Agent " )),
97136 Repository : "slack-samples/bolt-js-starter-agent" ,
137+ Subdir : "claude-agent-sdk" ,
98138 },
99139 {
100- Title : fmt .Sprintf ("Bolt for Python %s" , style .Secondary ("Python" )),
140+ Title : fmt .Sprintf ("OpenAI Agents SDK %s" , style .Secondary ("Bolt for JavaScript - Starter Agent" )),
141+ Repository : "slack-samples/bolt-js-starter-agent" ,
142+ Subdir : "openai-agents-sdk" ,
143+ },
144+ },
145+ "slack-cli#ai-apps/starter-agent/bolt-python" : {
146+ {
147+ Title : fmt .Sprintf ("Claude Agent SDK %s" , style .Secondary ("Bolt for Python - Starter Agent" )),
148+ Repository : "slack-samples/bolt-python-starter-agent" ,
149+ Subdir : "claude-agent-sdk" ,
150+ },
151+ {
152+ Title : fmt .Sprintf ("OpenAI Agents SDK %s" , style .Secondary ("Bolt for Python - Starter Agent" )),
153+ Repository : "slack-samples/bolt-python-starter-agent" ,
154+ Subdir : "openai-agents-sdk" ,
155+ },
156+ {
157+ Title : fmt .Sprintf ("Pydantic AI %s" , style .Secondary ("Bolt for Python - Starter Agent" )),
101158 Repository : "slack-samples/bolt-python-starter-agent" ,
159+ Subdir : "pydantic-ai" ,
102160 },
103161 },
104162 }
105- return frameworkPromptObjects [ template ]
163+ return adapterPromptObjects [ framework ]
106164}
107165
108166// getSelectionOptionsForCategory returns the top-level category options for
@@ -223,31 +281,63 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory,
223281 }
224282 template := options [selection .Index ].Repository
225283
226- // Prompt for the example framework
227- examples := getFrameworkOptions (template )
228- choices := make ([]string , len (examples ))
229- for i , opt := range examples {
230- choices [i ] = opt .Title
284+ // Prompt for the framework
285+ frameworks := getFrameworkOptions (template )
286+ frameworkChoices := make ([]string , len (frameworks ))
287+ for i , opt := range frameworks {
288+ frameworkChoices [i ] = opt .Title
231289 }
232- choice , err := clients .IO .SelectPrompt (ctx , "Select a framework:" , choices , iostreams.SelectPromptConfig {
290+ frameworkSelection , err := clients .IO .SelectPrompt (ctx , "Select a Bolt framework:" , frameworkChoices , iostreams.SelectPromptConfig {
233291 Description : func (value string , index int ) string {
234- return examples [index ].Description
292+ return frameworks [index ].Description
235293 },
236294 Required : true ,
237295 Template : getSelectionTemplate (clients ),
238296 })
239297 if err != nil {
240298 return create.Template {}, err
241- } else if choice .Flag {
299+ } else if frameworkSelection .Flag {
242300 return create.Template {}, slackerror .New (slackerror .ErrPrompt )
243301 }
244- example := examples [choice .Index ]
245- resolved , err := create .ResolveTemplateURL (example .Repository )
302+ framework := frameworks [frameworkSelection .Index ]
303+
304+ // Check if there are adapter options for this framework
305+ adapters := getAdapterOptions (framework .Repository )
306+ if len (adapters ) > 0 {
307+ adapterChoices := make ([]string , len (adapters ))
308+ for i , opt := range adapters {
309+ adapterChoices [i ] = opt .Title
310+ }
311+ adapterSelection , err := clients .IO .SelectPrompt (ctx , "Select an agent framework:" , adapterChoices , iostreams.SelectPromptConfig {
312+ Description : func (value string , index int ) string {
313+ return adapters [index ].Description
314+ },
315+ Required : true ,
316+ Template : getSelectionTemplate (clients ),
317+ })
318+ if err != nil {
319+ return create.Template {}, err
320+ } else if adapterSelection .Flag {
321+ return create.Template {}, slackerror .New (slackerror .ErrPrompt )
322+ }
323+ adapter := adapters [adapterSelection .Index ]
324+ resolved , err := create .ResolveTemplateURL (adapter .Repository )
325+ if err != nil {
326+ return create.Template {}, err
327+ }
328+ if adapter .Subdir != "" {
329+ resolved .SetSubdir (adapter .Subdir )
330+ }
331+ return resolved , nil
332+ }
333+
334+ // No adapter options - resolve the framework directly
335+ resolved , err := create .ResolveTemplateURL (framework .Repository )
246336 if err != nil {
247337 return create.Template {}, err
248338 }
249- if example .Subdir != "" {
250- resolved .SetSubdir (example .Subdir )
339+ if framework .Subdir != "" {
340+ resolved .SetSubdir (framework .Subdir )
251341 }
252342 return resolved , nil
253343}
@@ -300,27 +390,33 @@ func listTemplates(ctx context.Context, clients *shared.ClientFactory, categoryS
300390 var categories []categoryInfo
301391 if categoryShortcut == "agent" {
302392 categories = []categoryInfo {
303- {id : "slack-cli#ai-apps/support-agent" , name : "Support agent" },
304393 {id : "slack-cli#ai-apps/starter-agent" , name : "Starter agent" },
394+ {id : "slack-cli#ai-apps/support-agent" , name : "Support agent" },
305395 }
306396 } else {
307397 categories = []categoryInfo {
308398 {id : "slack-cli#getting-started" , name : "Getting started" },
309- {id : "slack-cli#ai-apps/support-agent" , name : "Support agent" },
310399 {id : "slack-cli#ai-apps/starter-agent" , name : "Starter agent" },
400+ {id : "slack-cli#ai-apps/support-agent" , name : "Support agent" },
311401 {id : "slack-cli#automation-apps" , name : "Automation apps" },
312402 }
313403 }
314404
315405 for _ , category := range categories {
316406 var secondary []string
317407 if frameworks := getFrameworkOptions (category .id ); len (frameworks ) > 0 {
318- for _ , tmpl := range frameworks {
319- repo := tmpl .Repository
320- if tmpl .Subdir != "" {
321- repo = fmt .Sprintf ("%s --subdir %s" , repo , tmpl .Subdir )
408+ for _ , fw := range frameworks {
409+ if adapters := getAdapterOptions (fw .Repository ); len (adapters ) > 0 {
410+ for _ , adapter := range adapters {
411+ repo := adapter .Repository
412+ if adapter .Subdir != "" {
413+ repo = fmt .Sprintf ("%s --subdir %s" , repo , adapter .Subdir )
414+ }
415+ secondary = append (secondary , repo )
416+ }
417+ } else {
418+ secondary = append (secondary , fw .Repository )
322419 }
323- secondary = append (secondary , repo )
324420 }
325421 } else {
326422 for _ , tmpl := range getSelectionOptions (category .id ) {
0 commit comments