Skip to content

feat: add optional filepath argument to run command#417

Open
zimeg wants to merge 1 commit intozimeg-fix-env-quotefrom
zimeg-feat-run-path
Open

feat: add optional filepath argument to run command#417
zimeg wants to merge 1 commit intozimeg-fix-env-quotefrom
zimeg-feat-run-path

Conversation

@zimeg
Copy link
Member

@zimeg zimeg commented Mar 19, 2026

Changelog

The run command now accepts an optional argument for the app entry point:

$ slack run ./src/app.py

Summary

This PR adds an optional filepath argument to the run command.

Preview

Current and continued behavior:

default

With a path argument provided:

path

When the file doesn't exist:

error

Reviewers

The following commands shows the optional argument of a filepath for the run command:

$ slack create asdf -t slack-samples/bolt-js-starter-template
$ cd asdf
$ slack run         # No argument defaults to the start hook
$ slack run app.js  # The common path appears to be alright
$ mkdir src
$ mv app-oauth.js src
$ slack run src/app-oauth.js  # Find a SDK runtime error!
$ slack run src/example.js    # Find the file not found

Requirements

@zimeg zimeg added this to the Next Release milestone Mar 19, 2026
@zimeg zimeg self-assigned this Mar 19, 2026
@zimeg zimeg requested review from a team as code owners March 19, 2026 06:46
@zimeg zimeg added enhancement M-T: A feature request for new functionality changelog Use on updates to be included in the release notes semver:minor Use on pull requests to describe the release version increment labels Mar 19, 2026
@codecov
Copy link

codecov bot commented Mar 19, 2026

Codecov Report

❌ Patch coverage is 57.89474% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.59%. Comparing base (5122e45) to head (bc64865).

Files with missing lines Patch % Lines
internal/pkg/platform/localserver.go 0.00% 7 Missing ⚠️
internal/pkg/platform/run.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                   Coverage Diff                   @@
##           zimeg-fix-env-quote     #417      +/-   ##
=======================================================
- Coverage                68.62%   68.59%   -0.04%     
=======================================================
  Files                      218      218              
  Lines                    18164    18177      +13     
=======================================================
+ Hits                     12465    12468       +3     
- Misses                    4539     4545       +6     
- Partials                  1160     1164       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member Author

@zimeg zimeg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🌚 A few thoughts of these changes shared for kind reviewers!

Comment on lines +100 to +108
var appPath string
if len(args) > 0 {
appPath = args[0]
if _, err := clients.Fs.Stat(appPath); err != nil {
return slackerror.New(slackerror.ErrNotFound).
WithMessage("The app path %q could not be found", appPath).
WithRemediation("Check that the file exists and the path is correct")
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var appPath string
if len(args) > 0 {
appPath = args[0]
if _, err := clients.Fs.Stat(appPath); err != nil {
return slackerror.New(slackerror.ErrNotFound).
WithMessage("The app path %q could not be found", appPath).
WithRemediation("Check that the file exists and the path is correct")
}
}

🪓 note: I'm curious of removing this in favor of leaving errors to the hook implementations. Removing this might let for strange argument parsing as perhaps:

$ slack run localhost

👾 ramble: For now it seems to make a better experience for the intended filepath arguments I think-

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: Interesting idea to leave this to the framework. I think for now, we should leave this in the CLI. We can loosen it later if there is a feature request, but this starts with ensuring an error-free experience. If developers are running a build (e.g. TypeScript: dist/index.js) then they'll need to start their watch server or build a dist before starting the Slack CLI.

Args: cobra.MaximumNArgs(1),
Example: style.ExampleCommandsf([]style.ExampleCommand{
{Command: "platform run", Meaning: "Start a local development server"},
{Command: "platform run --activity-level debug", Meaning: "Run a local development server with debug activity"},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗣️ note: IIRC this activity level flag isn't used often so we might encourage examples that outline another common use case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👾 ramble: I'm now curious if this flag updates a LOG_LEVEL environment variable for run command?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we can probably remove it as an example since it's Deno/ROSI specific as well.

thought: In the future, we will probably introduce a --log-level flag that the CLI will use and pass into Bolt Frameworks. The same log level should be passed into the Deno SDK and could be inherited by --activity-level for Deno apps.

The end result would be a universal log-level flag that works for all frameworks and ROSI.

func NewRunCommand(clients *shared.ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "run",
Use: "run [app-path]",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📚 note: I'm not so excited about this placeholder but it's clear to me...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd clarify that it's a filepath (src/app.js) instead of a path (src/). Otherwise, I think it's clear!

You could use run [file-path] if run [app-file-path] reads strange to you.

Suggested change
Use: "run [app-path]",
Use: "run [app-file-path]",

Copy link
Member

@mwbrooks mwbrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Woohoo! This is an exciting and cool addition, thanks for adding it @zimeg!

🧪 Works beautifully with local tests. 🎉

📝 Left a minor nit about renaming appPath to appFilePath for clarity. Pedantic, but the clarity can avoid confusion for developers reading the code with refresh eyes.

func NewRunCommand(clients *shared.ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "run",
Use: "run [app-path]",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd clarify that it's a filepath (src/app.js) instead of a path (src/). Otherwise, I think it's clear!

You could use run [file-path] if run [app-file-path] reads strange to you.

Suggested change
Use: "run [app-path]",
Use: "run [app-file-path]",

Args: cobra.MaximumNArgs(1),
Example: style.ExampleCommandsf([]style.ExampleCommand{
{Command: "platform run", Meaning: "Start a local development server"},
{Command: "platform run --activity-level debug", Meaning: "Run a local development server with debug activity"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we can probably remove it as an example since it's Deno/ROSI specific as well.

thought: In the future, we will probably introduce a --log-level flag that the CLI will use and pass into Bolt Frameworks. The same log level should be passed into the Deno SDK and could be inherited by --activity-level for Deno apps.

The end result would be a universal log-level flag that works for all frameworks and ROSI.

}
ctx := cmd.Context()

var appPath string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could I suggest appFilePath? To me appPath implies a path (directory path) while appFilePath implies a file path (path to a specific file).

appPath = args[0]
if _, err := clients.Fs.Stat(appPath); err != nil {
return slackerror.New(slackerror.ErrNotFound).
WithMessage("The app path %q could not be found", appPath).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WithMessage("The app path %q could not be found", appPath).
WithMessage("The app file path %q could not be found", appPath).

Comment on lines +100 to +108
var appPath string
if len(args) > 0 {
appPath = args[0]
if _, err := clients.Fs.Stat(appPath); err != nil {
return slackerror.New(slackerror.ErrNotFound).
WithMessage("The app path %q could not be found", appPath).
WithRemediation("Check that the file exists and the path is correct")
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: Interesting idea to leave this to the framework. I think for now, we should leave this in the CLI. We can loosen it later if there is a feature request, but this starts with ensuring an error-free experience. If developers are running a build (e.g. TypeScript: dist/index.js) then they'll need to start their watch server or build a dist before starting the Slack CLI.

Activity: !runFlags.noActivity,
ActivityLevel: runFlags.activityLevel,
App: selection.App,
AppPath: appPath,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You know my nit here, lol.

Suggested change
AppPath: appPath,
AppFilePath: appFilePath,

All Bolt SDKs leverage this `start` hook operating mode.

A custom start path can be set with the `SLACK_CLI_CUSTOM_FILE_PATH` variable.
A custom start path can be provided as a positional argument to the `run` command (e.g., `slack run ./src/app.py`), which sets both the `SLACK_APP_PATH` and `SLACK_CLI_CUSTOM_FILE_PATH` environment variables for the hook process.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Thank you for updating this and choosing to support both at first. #backwards-compatible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog Use on updates to be included in the release notes enhancement M-T: A feature request for new functionality semver:minor Use on pull requests to describe the release version increment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants