Prompt to initialize app when no config is found#654
Conversation
When any AppCentric command runs without an app name and no .miren/app.toml, we now infer a name from the directory and offer to run init inline. In non-interactive contexts, the error message points users to `miren init` or the -a flag instead of the old bare "app is required". Extracted inferAppName and initApp helpers from the Init command so both the interactive Validate prompt and the Init command share the same logic.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughWhen no app name is provided, the command now infers a name from the working directory and may prompt to initialize an app in that directory. App initialization logic was extracted into Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
cli/commands/app_test.go (1)
21-40: Consider adding edge case tests forinferAppName.The test covers common cases well, but some edge cases are missing that could cause unexpected behavior:
- Empty directory string
- Root path
"/"- Paths ending with trailing slash (e.g.,
"/home/user/my-app/")- Paths with consecutive special characters (e.g.,
"my--app","my__app")These edge cases could reveal issues with
filepath.Basebehavior or the sanitization logic.🧪 Suggested additional test cases
tests := []struct { dir string want string }{ {"/home/user/my-app", "my-app"}, {"/home/user/My App", "my-app"}, {"/home/user/my_app", "my-app"}, {"/home/user/MyApp", "myapp"}, {"/home/user/HELLO", "hello"}, + {"/home/user/my-app/", "my-app"}, + {"/home/user/my--app", "my--app"}, + {"/home/user/my__app", "my--app"}, }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/commands/app_test.go` around lines 21 - 40, Extend TestInferAppName to add edge-case table entries for inferAppName: include an empty string dir (""), root path ("/"), a path with trailing slash (e.g., "/home/user/my-app/"), and names with consecutive special characters (e.g., "/home/user/my--app" and "/home/user/my__app"); update the tests to assert the expected normalized outputs for these cases so inferAppName's handling of filepath.Base and sanitization is verified.cli/commands/app.go (1)
77-84: Prompt cancellation and error both return same generic message.When the user declines the prompt (
!confirmed) or an error occurs (err != nil), they get the same error message. Consider distinguishing these cases: a user explicitly declining might warrant a different message than an unexpected prompt error.💡 Suggested differentiation
confirmed, err := ui.Confirm( ui.WithMessage(fmt.Sprintf("No app configuration found. Initialize app %q in this directory?", appName)), ui.WithDefault(true), ui.WithIndent(" "), ) - if err != nil || !confirmed { - return fmt.Errorf("no app configured; run 'miren init' to set up your app, or use -a <name>") + if err != nil { + return fmt.Errorf("prompt failed: %w", err) + } + if !confirmed { + return fmt.Errorf("initialization declined; run 'miren init' to set up your app later, or use -a <name>") }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/commands/app.go` around lines 77 - 84, Differentiate between a user cancellation and an actual prompt error in the ui.Confirm handling: check err first and return a wrapped/explicit error (including err) when ui.Confirm returns an error, and return a different user-friendly cancellation message when confirmed is false (e.g., "operation cancelled by user; run 'miren init' to set up your app or use -a <name>"). Update the block around ui.Confirm (variables: ui.Confirm, confirmed, err, appName) so the two branches produce distinct messages and preserve original guidance.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cli/commands/app.go`:
- Around line 90-100: The reload logic after initialization uses a.Dir checks
that differ from the earlier initial load and may not match the actual directory
used by initApp (workDir); update the reload to use the exact same location used
during init by calling appconfig.LoadAppConfigUnder(workDir) (or otherwise use
the same conditional that was used for the initial load) so that the config is
consistently reloaded from the true working directory; reference the variables
a.Dir and workDir and the functions appconfig.LoadAppConfigUnder and
appconfig.LoadAppConfig when making this change.
---
Nitpick comments:
In `@cli/commands/app_test.go`:
- Around line 21-40: Extend TestInferAppName to add edge-case table entries for
inferAppName: include an empty string dir (""), root path ("/"), a path with
trailing slash (e.g., "/home/user/my-app/"), and names with consecutive special
characters (e.g., "/home/user/my--app" and "/home/user/my__app"); update the
tests to assert the expected normalized outputs for these cases so
inferAppName's handling of filepath.Base and sanitization is verified.
In `@cli/commands/app.go`:
- Around line 77-84: Differentiate between a user cancellation and an actual
prompt error in the ui.Confirm handling: check err first and return a
wrapped/explicit error (including err) when ui.Confirm returns an error, and
return a different user-friendly cancellation message when confirmed is false
(e.g., "operation cancelled by user; run 'miren init' to set up your app or use
-a <name>"). Update the block around ui.Confirm (variables: ui.Confirm,
confirmed, err, appName) so the two branches produce distinct messages and
preserve original guidance.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8d8e4097-8eef-4d54-939f-23c9d5509de3
📒 Files selected for processing (3)
cli/commands/app.gocli/commands/app_test.gocli/commands/init.go
workDir is already resolved to an absolute path, so use LoadAppConfigUnder(workDir) directly instead of re-checking a.Dir with slightly different conditions than the initial load.
Make the prompt and error messages more conversational — "Looks like this directory isn't set up yet" instead of "No app configuration found", and make it clear we're running miren init for them.
Running any app command without a
.miren/app.tomlused to give you a pretty unhelpful "app is required" error. Now it meets you where you are — if you're on a TTY, it infers an app name from your directory, offers to runmiren initfor you, and gets on with it. In CI or piped contexts, the error message tells you what to do next.The init logic got pulled into shared
inferAppNameandinitApphelpers so both themiren initcommand and theAppCentric.Validateprompt go through the same path. This lives in Validate rather than just Deploy, so every app command gets the zero-config onramp for free.UX Demo
Interactive (TTY) — no config, first deploy:
Non-interactive (CI/piped) — clear guidance:
Already initialized — no change, works as before:
Closes MIR-518