Add pre-commit task, CLI enhancements, and ATS updates

- Added `pre-commit` task in Makefile.
- Enhanced CLI with banner display and stricter file selection validation.
- Expanded App Transport Security settings and updated permissions in `Info.dev.plist`.
This commit is contained in:
Snider 2025-10-27 05:41:11 +00:00
parent 3944874c9f
commit 90009eccd5
5 changed files with 60 additions and 14 deletions

View file

@ -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)

View file

@ -23,10 +23,25 @@
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>© EUPL-1.2 Lethean Community</string>
<!-- Expanded App Transport Security settings -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<!-- File System Access Permissions -->
<key>NSDownloadsFolderUsageDescription</key>
<string>This app needs access to your Downloads folder to save and load files.</string>
<key>NSDocumentsFolderUsageDescription</key>
<string>This app needs access to your Documents folder to save and load files.</string>
<key>NSDesktopFolderUsageDescription</key>
<string>This app needs access to your Desktop folder to save and load files.</string>
</dict>
</plist>
</plist>

View file

@ -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)

View file

@ -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

View file

@ -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).