Skip to content

Commit 2195bb8

Browse files
committed
chore: scope to surface agent apps
1 parent 0d884c9 commit 2195bb8

2 files changed

Lines changed: 52 additions & 148 deletions

File tree

cmd/project/create_template.go

Lines changed: 45 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -35,43 +35,38 @@ import (
3535
func getSelectionOptions(clients *shared.ClientFactory, categoryID string) []promptObject {
3636
if clients.Config.WithExperimentOn(experiment.Templates) {
3737
templatePromptObjects := map[string]([]promptObject){
38-
"slack-cli#starter-templates": {
38+
"slack-cli#getting-started": {
3939
{
40-
Title: "Starter template",
41-
Description: "Getting started Slack app",
42-
Repository: "slack-cli#starter-templates/getting-started",
40+
Title: "Bolt for JavaScript",
41+
Repository: "slack-samples/bolt-js-starter-template",
4342
},
4443
{
45-
Title: "Automation template",
46-
Description: "Custom steps and workflows",
47-
Repository: "slack-cli#starter-templates/automation-apps",
44+
Title: "Bolt for Python",
45+
Repository: "slack-samples/bolt-python-starter-template",
4846
},
47+
},
48+
"slack-cli#ai-apps": {
4949
{
50-
Title: "Search template",
51-
Description: "Real-time enterprise search",
52-
Repository: "slack-cli#starter-templates/search-template",
50+
Title: fmt.Sprintf("Support Agent %s", style.Secondary("Resolve IT support cases")),
51+
Repository: "slack-cli#ai-apps/support-agent",
5352
},
5453
{
55-
Title: "Blank template",
56-
Description: "Minimal setup that will start",
57-
Repository: "slack-cli#starter-templates/blank-template",
54+
Title: fmt.Sprintf("Custom Agent %s", style.Secondary("Start from scratch")),
55+
Repository: "slack-cli#ai-apps/custom-agent",
5856
},
5957
},
60-
"slack-cli#ai-apps": {
58+
"slack-cli#automation-apps": {
6159
{
62-
Title: "Support agent",
63-
Description: "Resolve IT support cases with Casey",
64-
Repository: "slack-cli#ai-apps/support-agent",
60+
Title: "Bolt for JavaScript",
61+
Repository: "slack-samples/bolt-js-custom-function-template",
6562
},
6663
{
67-
Title: "Custom agent",
68-
Description: "Minimal setup with the Slack MCP server",
69-
Repository: "slack-cli#ai-apps/mcp-server",
64+
Title: "Bolt for Python",
65+
Repository: "slack-samples/bolt-python-custom-function-template",
7066
},
7167
{
72-
Title: "Assistant template",
73-
Description: "Scaffold for a custom assistant",
74-
Repository: "slack-cli#ai-apps/assistant-template",
68+
Title: "Deno Slack SDK",
69+
Repository: "slack-samples/deno-starter-template",
7570
},
7671
},
7772
}
@@ -129,82 +124,24 @@ func getSelectionOptions(clients *shared.ClientFactory, categoryID string) []pro
129124
// new entries. This is not an implementation requirement.
130125
func getFrameworkOptions(template string) []promptObject {
131126
frameworkPromptObjects := map[string][]promptObject{
132-
"slack-cli#starter-templates/getting-started": {
133-
{
134-
Title: "Bolt for JavaScript",
135-
Repository: "slack-samples/bolt-js-starter-template",
136-
},
137-
{
138-
Title: "Bolt for JavaScript",
139-
Description: "TypeScript",
140-
Repository: "slack-samples/bolt-ts-starter-template",
141-
},
142-
{
143-
Title: "Bolt for Python",
144-
Repository: "slack-samples/bolt-python-starter-template",
145-
},
146-
},
147-
"slack-cli#starter-templates/automation-apps": {
148-
{
149-
Title: "Bolt for JavaScript",
150-
Repository: "slack-samples/bolt-js-custom-function-template",
151-
},
152-
{
153-
Title: "Bolt for JavaScript",
154-
Description: "TypeScript",
155-
Repository: "slack-samples/bolt-ts-custom-step-template",
156-
},
157-
{
158-
Title: "Bolt for Python",
159-
Repository: "slack-samples/bolt-python-custom-function-template",
160-
},
161-
{
162-
Title: "Deno Slack SDK",
163-
Repository: "slack-samples/deno-starter-template",
164-
},
165-
},
166-
"slack-cli#starter-templates/search-template": {
167-
{
168-
Title: "Bolt for JavaScript",
169-
Repository: "slack-samples/bolt-js-search-template",
170-
},
171-
{
172-
Title: "Bolt for JavaScript",
173-
Description: "TypeScript",
174-
Repository: "slack-samples/bolt-ts-search-template",
175-
},
176-
{
177-
Title: "Bolt for Python",
178-
Repository: "slack-samples/bolt-python-search-template",
179-
},
180-
},
181-
"slack-cli#starter-templates/blank-template": {
182-
{
183-
Title: "Bolt for JavaScript",
184-
Repository: "slack-samples/bolt-js-blank-template",
185-
},
186-
},
187127
"slack-cli#ai-apps/support-agent": {
188128
{
189-
Title: "Claude Agent SDK",
190-
Description: "Bolt for Python",
191-
Repository: "slack-samples/bolt-python-support-agent",
192-
Subdir: "claude-agent-sdk",
129+
Title: fmt.Sprintf("Claude Agent SDK %s", style.Secondary("Bolt for Python")),
130+
Repository: "slack-samples/bolt-python-support-agent",
131+
Subdir: "claude-agent-sdk",
193132
},
194133
{
195-
Title: "OpenAI Agents SDK",
196-
Description: "Bolt for Python",
197-
Repository: "slack-samples/bolt-python-support-agent",
198-
Subdir: "openai-agents-sdk",
134+
Title: fmt.Sprintf("OpenAI Agents SDK %s", style.Secondary("Bolt for Python")),
135+
Repository: "slack-samples/bolt-python-support-agent",
136+
Subdir: "openai-agents-sdk",
199137
},
200138
{
201-
Title: "Pydantic AI",
202-
Description: "Bolt for Python",
203-
Repository: "slack-samples/bolt-python-support-agent",
204-
Subdir: "pydantic-ai",
139+
Title: fmt.Sprintf("Pydantic AI %s", style.Secondary("Bolt for Python")),
140+
Repository: "slack-samples/bolt-python-support-agent",
141+
Subdir: "pydantic-ai",
205142
},
206143
},
207-
"slack-cli#ai-apps/assistant-template": {
144+
"slack-cli#ai-apps/custom-agent": {
208145
{
209146
Title: "Bolt for JavaScript",
210147
Repository: "slack-samples/bolt-js-assistant-template",
@@ -214,35 +151,13 @@ func getFrameworkOptions(template string) []promptObject {
214151
Repository: "slack-samples/bolt-python-assistant-template",
215152
},
216153
},
217-
"slack-cli#ai-apps/mcp-server": {
218-
{
219-
Title: "Bolt for JavaScript",
220-
Repository: "slack-samples/bolt-js-slack-mcp-server",
221-
},
222-
},
223154
}
224155
return frameworkPromptObjects[template]
225156
}
226157

227158
// getSelectionOptionsForCategory returns the top-level category options for
228159
// the create command template selection.
229160
func getSelectionOptionsForCategory(clients *shared.ClientFactory) []promptObject {
230-
if clients.Config.WithExperimentOn(experiment.Templates) {
231-
return []promptObject{
232-
{
233-
Title: "Starter templates",
234-
Repository: "slack-cli#starter-templates",
235-
},
236-
{
237-
Title: "AI agent apps",
238-
Repository: "slack-cli#ai-apps",
239-
},
240-
{
241-
Title: "View more samples",
242-
Repository: viewMoreSamples,
243-
},
244-
}
245-
}
246161
return []promptObject{
247162
{
248163
Title: fmt.Sprintf("Starter app %s", style.Secondary("Getting started Slack app")),
@@ -336,7 +251,11 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory,
336251
// Prompt for the example template
337252
prompt := "Select a language:"
338253
if clients.Config.WithExperimentOn(experiment.Templates) {
339-
prompt = "Select a template:"
254+
if strings.HasPrefix(categoryID, "slack-cli#") && !strings.Contains(categoryID, "/") {
255+
prompt = "Select a template:"
256+
} else {
257+
prompt = "Select a framework:"
258+
}
340259
}
341260
options := getSelectionOptions(clients, categoryID)
342261
titles := make([]string, len(options))
@@ -356,7 +275,7 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory,
356275
return create.Template{}, err
357276
} else if selection.Flag {
358277
return create.Template{}, slackerror.New(slackerror.ErrPrompt)
359-
} else if selection.Prompt && !clients.Config.WithExperimentOn(experiment.Templates) {
278+
} else if selection.Prompt && !strings.HasPrefix(options[selection.Index].Repository, "slack-cli#") {
360279
return create.ResolveTemplateURL(options[selection.Index].Repository)
361280
}
362281
template := options[selection.Index].Repository
@@ -372,6 +291,7 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory,
372291
return examples[index].Description
373292
},
374293
Required: true,
294+
Template: getSelectionTemplate(clients),
375295
})
376296
if err != nil {
377297
return create.Template{}, err
@@ -438,22 +358,18 @@ func listTemplates(ctx context.Context, clients *shared.ClientFactory, categoryS
438358
if categoryShortcut == "agent" && clients.Config.WithExperimentOn(experiment.Templates) {
439359
categories = []categoryInfo{
440360
{id: "slack-cli#ai-apps/support-agent", name: "Support agent"},
441-
{id: "slack-cli#ai-apps/mcp-server", name: "Custom agent"},
442-
{id: "slack-cli#ai-apps/assistant-template", name: "Assistant templates"},
361+
{id: "slack-cli#ai-apps/custom-agent", name: "Custom agent"},
443362
}
444363
} else if categoryShortcut == "agent" {
445364
categories = []categoryInfo{
446365
{id: "slack-cli#ai-apps", name: "AI Agent apps"},
447366
}
448367
} else if clients.Config.WithExperimentOn(experiment.Templates) {
449368
categories = []categoryInfo{
450-
{id: "slack-cli#starter-templates/getting-started", name: "Starter templates"},
451-
{id: "slack-cli#starter-templates/automation-apps", name: "Automation templates"},
452-
{id: "slack-cli#starter-templates/search-template", name: "Search templates"},
453-
{id: "slack-cli#starter-templates/blank-template", name: "Blank templates"},
369+
{id: "slack-cli#getting-started", name: "Getting started"},
454370
{id: "slack-cli#ai-apps/support-agent", name: "Support agent"},
455-
{id: "slack-cli#ai-apps/mcp-server", name: "Custom agent"},
456-
{id: "slack-cli#ai-apps/assistant-template", name: "Assistant templates"},
371+
{id: "slack-cli#ai-apps/custom-agent", name: "Custom agent"},
372+
{id: "slack-cli#automation-apps", name: "Automation apps"},
457373
}
458374
} else {
459375
categories = []categoryInfo{
@@ -465,18 +381,18 @@ func listTemplates(ctx context.Context, clients *shared.ClientFactory, categoryS
465381

466382
for _, category := range categories {
467383
var secondary []string
468-
if !clients.Config.WithExperimentOn(experiment.Templates) {
469-
for _, tmpl := range getSelectionOptions(clients, category.id) {
470-
secondary = append(secondary, tmpl.Repository)
471-
}
472-
} else {
473-
for _, tmpl := range getFrameworkOptions(category.id) {
384+
if frameworks := getFrameworkOptions(category.id); len(frameworks) > 0 {
385+
for _, tmpl := range frameworks {
474386
repo := tmpl.Repository
475387
if tmpl.Subdir != "" {
476388
repo = fmt.Sprintf("%s --subdir %s", repo, tmpl.Subdir)
477389
}
478390
secondary = append(secondary, repo)
479391
}
392+
} else {
393+
for _, tmpl := range getSelectionOptions(clients, category.id) {
394+
secondary = append(secondary, tmpl.Repository)
395+
}
480396
}
481397
clients.IO.PrintInfo(ctx, false, "%s", style.Sectionf(style.TextSection{
482398
Emoji: "house_buildings",

cmd/project/create_test.go

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -611,30 +611,20 @@ func TestCreateCommand(t *testing.T) {
611611
CreateFunc = createClientMock.Create
612612
},
613613
ExpectedOutputs: []string{
614-
"Starter templates",
614+
"Getting started",
615615
"slack-samples/bolt-js-starter-template",
616-
"slack-samples/bolt-ts-starter-template",
617616
"slack-samples/bolt-python-starter-template",
618-
"Automation templates",
619-
"slack-samples/bolt-js-custom-function-template",
620-
"slack-samples/bolt-ts-custom-step-template",
621-
"slack-samples/bolt-python-custom-function-template",
622-
"slack-samples/deno-starter-template",
623-
"Search templates",
624-
"slack-samples/bolt-js-search-template",
625-
"slack-samples/bolt-ts-search-template",
626-
"slack-samples/bolt-python-search-template",
627-
"Blank templates",
628-
"slack-samples/bolt-js-blank-template",
629617
"Support agent",
630618
"slack-samples/bolt-python-support-agent --subdir claude-agent-sdk",
631619
"slack-samples/bolt-python-support-agent --subdir openai-agents-sdk",
632620
"slack-samples/bolt-python-support-agent --subdir pydantic-ai",
633621
"Custom agent",
634-
"slack-samples/bolt-js-slack-mcp-server",
635-
"Assistant templates",
636622
"slack-samples/bolt-js-assistant-template",
637623
"slack-samples/bolt-python-assistant-template",
624+
"Automation apps",
625+
"slack-samples/bolt-js-custom-function-template",
626+
"slack-samples/bolt-python-custom-function-template",
627+
"slack-samples/deno-starter-template",
638628
},
639629
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
640630
createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything)
@@ -655,16 +645,14 @@ func TestCreateCommand(t *testing.T) {
655645
"slack-samples/bolt-python-support-agent --subdir openai-agents-sdk",
656646
"slack-samples/bolt-python-support-agent --subdir pydantic-ai",
657647
"Custom agent",
658-
"slack-samples/bolt-js-slack-mcp-server",
659-
"Assistant templates",
660648
"slack-samples/bolt-js-assistant-template",
661649
"slack-samples/bolt-python-assistant-template",
662650
},
663651
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
664652
createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything)
665653
output := cm.GetCombinedOutput()
666-
assert.NotContains(t, output, "Starter templates")
667-
assert.NotContains(t, output, "Blank templates")
654+
assert.NotContains(t, output, "Getting started")
655+
assert.NotContains(t, output, "Automation apps")
668656
},
669657
},
670658
}, func(cf *shared.ClientFactory) *cobra.Command {

0 commit comments

Comments
 (0)