diff --git a/Makefile b/Makefile
index 05517a9..10dda7e 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,9 @@ all:
dev:
(cd cmd/core-app && task dev)
+pre-commit:
+ coderabbit review --prompt-only
+
development-docs:
@echo "Running development documentation Website..."
@(cd pkg/core/docs && mkdocs serve -w src)
diff --git a/cmd/core-app/build/darwin/Info.dev.plist b/cmd/core-app/build/darwin/Info.dev.plist
index c7d6ce4..6b23ec1 100644
--- a/cmd/core-app/build/darwin/Info.dev.plist
+++ b/cmd/core-app/build/darwin/Info.dev.plist
@@ -23,10 +23,25 @@
true
NSHumanReadableCopyright
© EUPL-1.2 Lethean Community
+
+
NSAppTransportSecurity
NSAllowsLocalNetworking
+ NSAllowsArbitraryLoads
+
+ NSAllowsArbitraryLoadsInWebContent
+
+
+
+ NSDownloadsFolderUsageDescription
+ This app needs access to your Downloads folder to save and load files.
+ NSDocumentsFolderUsageDescription
+ This app needs access to your Documents folder to save and load files.
+ NSDesktopFolderUsageDescription
+ This app needs access to your Desktop folder to save and load files.
+
-
\ No newline at end of file
+
diff --git a/cmd/core/cmd/build.go b/cmd/core/cmd/build.go
index eb27f87..3695d37 100644
--- a/cmd/core/cmd/build.go
+++ b/cmd/core/cmd/build.go
@@ -129,6 +129,12 @@ func updateFileSelect(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
m.fileCursor++
}
case "enter":
+ // Guard against empty files or out-of-bounds cursor
+ if len(m.files) == 0 || m.fileCursor < 0 || m.fileCursor >= len(m.files) {
+ // If the guard fails, attempt to reload files for the current path
+ return m, loadFilesCmd(m.currentPath)
+ }
+
selectedEntry := m.files[m.fileCursor]
fullPath := filepath.Join(m.currentPath, selectedEntry.Name())
if selectedEntry.IsDir() {
@@ -136,9 +142,17 @@ func updateFileSelect(msg tea.Msg, m model) (tea.Model, tea.Cmd) {
return m, loadFilesCmd(m.currentPath)
} else {
// User selected a file
- m.selectedFile = fullPath
- m.view = buildOutputState
- return m, buildWailsCmd(m.selectedFile)
+ ext := strings.ToLower(filepath.Ext(selectedEntry.Name()))
+ if ext == ".html" || ext == ".htm" {
+ m.selectedFile = fullPath
+ m.view = buildOutputState
+ return m, buildWailsCmd(m.selectedFile)
+ } else {
+ // If not an HTML file, show an error and stay in file selection
+ m.buildLog = fmt.Sprintf("Error: Selected file '%s' is not an HTML file (.html or .htm).", selectedEntry.Name())
+ m.view = buildOutputState // Temporarily show error in build output view
+ return m, nil
+ }
}
case "backspace", "h":
parentPath := filepath.Dir(m.currentPath)
@@ -182,6 +196,9 @@ func (m model) View() string {
sb.WriteString(fmt.Sprintf("Select an HTML file for Wails build (Current: %s)\n\n", m.currentPath))
for i, entry := range m.files {
cursor := " "
+ if entry.IsDir() {
+ cursor = "/"
+ }
if m.fileCursor == i {
cursor = ">"
}
@@ -232,8 +249,16 @@ func buildWailsCmd(htmlPath string) tea.Cmd {
return errorMsg(fmt.Errorf("wails3 executable not found in PATH: %w", err))
}
- // Assuming the Wails project is in cmd/core-app relative to the core CLI tool
- wailsProjectDir := "../core-app"
+ var wailsProjectDir string
+ execPath, err := os.Executable()
+ if err != nil {
+ // If os.Executable fails, return an error as we cannot reliably locate the Wails project.
+ return errorMsg(fmt.Errorf("failed to determine executable path: %w. Cannot reliably locate Wails project directory.", err))
+ } else {
+ execDir := filepath.Dir(execPath)
+ // Join execDir with "../core-app" and clean the path
+ wailsProjectDir = filepath.Clean(filepath.Join(execDir, "../core-app"))
+ }
// Get the directory and base name of the selected HTML file
assetDir := filepath.Dir(htmlPath)
diff --git a/cmd/core/cmd/root.go b/cmd/core/cmd/root.go
index c638e29..cd827f9 100644
--- a/cmd/core/cmd/root.go
+++ b/cmd/core/cmd/root.go
@@ -38,7 +38,7 @@ var (
Foreground(lipgloss.Color("#3b82f6")). // Tailwind blue-500
Underline(true)
- taglineStyle = lipgloss.NewStyle().
+ taglineStyle = lipgloss.NewNewStyle().
Foreground(lipgloss.Color("#e2e8f0")).
PaddingTop(2).PaddingLeft(8).PaddingBottom(1). // vertical spacing around the tagline
Align(lipgloss.Center) // centre it under the big words
@@ -55,6 +55,9 @@ var rootCmd = &cobra.Command{
"managing various aspects of Core.Framework applications."),
Run: func(cmd *cobra.Command, args []string) {
// Default behaviour if no subcommand is given
+ if !cmd.HasSubCommands() && len(args) == 0 {
+ showBanner()
+ }
err := cmd.Help()
if err != nil {
return
@@ -70,11 +73,14 @@ func Execute() {
}
func init() {
- // Here you can define global flags and configuration that apply to all commands.
+ // Here you can define global flags and command setup.
if os.Getenv("CORE_DEV_TOOLS") == "true" {
initDevTools()
}
+}
+// showBanner generates and prints the ASCII art banner.
+func showBanner() {
coreFig := figure.NewFigure("Core", "big", true)
frameworkFig := figure.NewFigure("Framework", "big", true)
@@ -121,11 +127,8 @@ func initDevTools() {
}
return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}
- // go-prompt will block, so we run it in a goroutine for this example
- // In a real app, you'd likely manage its lifecycle more carefully.
- // The prompt.New function returns a Prompt object, which then has a Run method.
- // For a simple blocking run, you can call .Run() directly on the New object.
- go prompt.New(executor, completer, prompt.OptionPrefix(">>> ")).Run()
+ // go-prompt will now run synchronously for the demo.
+ prompt.New(executor, completer, prompt.OptionPrefix(">>> ")).Run()
// Example usage for lipgloss
// Using the global descriptionStyle for consistency
diff --git a/cmd/core/cmd/tview.go b/cmd/core/cmd/tview.go
index 08ad04f..306b88c 100644
--- a/cmd/core/cmd/tview.go
+++ b/cmd/core/cmd/tview.go
@@ -17,7 +17,7 @@ var tviewCmd = &cobra.Command{
Short: "Runs a tview example to demonstrate its capabilities",
Long: `This command launches a simple tview application to showcase its full-screen terminal UI features.`,
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println("Starting tview example...")
+ // Removed: fmt.Println("Starting tview example...") to prevent visual artifacts
app := tview.NewApplication()
box := tview.NewBox().
SetBorder(true).