feat(init): complete project initialization with dependencies and build system
- commit
- bcef92dfb726b06b530e462515a2d93aad2574c1
- author
- bamen · · 2025-09-08 20:30 UTC
- committer
- bamen · · 2025-09-08 20:51 UTC
- parent
- c1e4d71
- signature
- unsigned
28 files · +2269 -35
A .gitignore +59 -0
| @@ -0,0 +1,59 @@ | |||
| 1 | + | # Build outputs | |
| 2 | + | dist/ | |
| 3 | + | *.exe | |
| 4 | + | *.exe~ | |
| 5 | + | *.dll | |
| 6 | + | *.so | |
| 7 | + | *.dylib | |
| 8 | + | ||
| 9 | + | # Binaries for programs and plugins | |
| 10 | + | dumb-browser | |
| 11 | + | dumb-browser.exe | |
| 12 | + | ||
| 13 | + | # Test binary, built with `go test -c` | |
| 14 | + | *.test | |
| 15 | + | ||
| 16 | + | # Output of the go coverage tool | |
| 17 | + | *.out | |
| 18 | + | ||
| 19 | + | # Dependency directories (remove the comment below to include it) | |
| 20 | + | # vendor/ | |
| 21 | + | ||
| 22 | + | # Go workspace file | |
| 23 | + | go.work | |
| 24 | + | ||
| 25 | + | # IDE files | |
| 26 | + | .vscode/ | |
| 27 | + | .idea/ | |
| 28 | + | *.swp | |
| 29 | + | *.swo | |
| 30 | + | *~ | |
| 31 | + | ||
| 32 | + | # OS generated files | |
| 33 | + | .DS_Store | |
| 34 | + | .DS_Store? | |
| 35 | + | ._* | |
| 36 | + | .Spotlight-V100 | |
| 37 | + | .Trashes | |
| 38 | + | ehthumbs.db | |
| 39 | + | Thumbs.db | |
| 40 | + | ||
| 41 | + | # Temporary files | |
| 42 | + | *.tmp | |
| 43 | + | *.temp | |
| 44 | + | *.log | |
| 45 | + | ||
| 46 | + | # Database files | |
| 47 | + | *.db | |
| 48 | + | *.sqlite | |
| 49 | + | *.sqlite3 | |
| 50 | + | ||
| 51 | + | # Configuration files that might contain secrets | |
| 52 | + | config.local.* | |
| 53 | + | .env | |
| 54 | + | .env.local | |
| 55 | + | .env.*.local | |
| 56 | + | ||
| 57 | + | # Build artifacts and caches | |
| 58 | + | .cache/ | |
| 59 | + | *.prof⏎̸ | |
| @@ -0,0 +1,59 @@ | |||||
| 1 | + | # Build outputs | |||
| 2 | + | dist/ | |||
| 3 | + | *.exe | |||
| 4 | + | *.exe~ | |||
| 5 | + | *.dll | |||
| 6 | + | *.so | |||
| 7 | + | *.dylib | |||
| 8 | + | ||||
| 9 | + | # Binaries for programs and plugins | |||
| 10 | + | dumb-browser | |||
| 11 | + | dumb-browser.exe | |||
| 12 | + | ||||
| 13 | + | # Test binary, built with `go test -c` | |||
| 14 | + | *.test | |||
| 15 | + | ||||
| 16 | + | # Output of the go coverage tool | |||
| 17 | + | *.out | |||
| 18 | + | ||||
| 19 | + | # Dependency directories (remove the comment below to include it) | |||
| 20 | + | # vendor/ | |||
| 21 | + | ||||
| 22 | + | # Go workspace file | |||
| 23 | + | go.work | |||
| 24 | + | ||||
| 25 | + | # IDE files | |||
| 26 | + | .vscode/ | |||
| 27 | + | .idea/ | |||
| 28 | + | *.swp | |||
| 29 | + | *.swo | |||
| 30 | + | *~ | |||
| 31 | + | ||||
| 32 | + | # OS generated files | |||
| 33 | + | .DS_Store | |||
| 34 | + | .DS_Store? | |||
| 35 | + | ._* | |||
| 36 | + | .Spotlight-V100 | |||
| 37 | + | .Trashes | |||
| 38 | + | ehthumbs.db | |||
| 39 | + | Thumbs.db | |||
| 40 | + | ||||
| 41 | + | # Temporary files | |||
| 42 | + | *.tmp | |||
| 43 | + | *.temp | |||
| 44 | + | *.log | |||
| 45 | + | ||||
| 46 | + | # Database files | |||
| 47 | + | *.db | |||
| 48 | + | *.sqlite | |||
| 49 | + | *.sqlite3 | |||
| 50 | + | ||||
| 51 | + | # Configuration files that might contain secrets | |||
| 52 | + | config.local.* | |||
| 53 | + | .env | |||
| 54 | + | .env.local | |||
| 55 | + | .env.*.local | |||
| 56 | + | ||||
| 57 | + | # Build artifacts and caches | |||
| 58 | + | .cache/ | |||
| 59 | + | *.prof⏎̸ | |||
A .golangci.yml +126 -0
| @@ -0,0 +1,126 @@ | |||
| 1 | + | version: "2" | |
| 2 | + | ||
| 3 | + | linters: | |
| 4 | + | default: none | |
| 5 | + | enable: | |
| 6 | + | - bodyclose # checks whether HTTP response body is closed successfully | |
| 7 | + | - copyloopvar # detects places where loop variables are copied | |
| 8 | + | # - depguard # checks for unwanted dependencies (disabled for CLI apps) | |
| 9 | + | - dogsled # checks assignments with too many blank identifiers | |
| 10 | + | - dupl # tool for code clone detection | |
| 11 | + | - errcheck # checking for unchecked errors | |
| 12 | + | - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme | |
| 13 | + | - funlen # tool for detection of long functions | |
| 14 | + | - gocheckcompilerdirectives # validates go compiler directive comments (//go:) | |
| 15 | + | # - gochecknoinits # checks that no init functions are present in Go code (disabled for CLI apps) | |
| 16 | + | - goconst # finds repeated strings that could be replaced by a constant | |
| 17 | + | - gocritic # provides diagnostics that check for bugs, performance and style issues | |
| 18 | + | - gocyclo # computes and checks the cyclomatic complexity of functions | |
| 19 | + | - godox # tool for detection of FIXME, TODO and other comment keywords | |
| 20 | + | - mnd # detects magic numbers | |
| 21 | + | - goprintffuncname # checks that printf-like functions are named with `f` at the end | |
| 22 | + | - gosec # inspects source code for security problems | |
| 23 | + | - govet # examines Go source code and reports suspicious constructs | |
| 24 | + | - ineffassign # detects when assignments to existing variables are not used | |
| 25 | + | - lll # reports long lines | |
| 26 | + | - misspell # finds commonly misspelled English words in comments | |
| 27 | + | - nakedret # finds naked returns in functions greater than a specified function length | |
| 28 | + | - nolintlint # reports ill-formed or insufficient nolint directives | |
| 29 | + | - revive # fast, configurable, extensible, flexible, and beautiful linter for Go | |
| 30 | + | - staticcheck # advanced Go linter | |
| 31 | + | - testifylint # checks usage of github.com/stretchr/testify | |
| 32 | + | - unconvert # removes unnecessary type conversions | |
| 33 | + | - unparam # reports unused function parameters | |
| 34 | + | - unused # checks for unused constants, variables, functions and types | |
| 35 | + | - whitespace # detects leading and trailing whitespace | |
| 36 | + | ||
| 37 | + | linters-settings: | |
| 38 | + | dupl: | |
| 39 | + | threshold: 100 | |
| 40 | + | funlen: | |
| 41 | + | lines: -1 # don't check line count | |
| 42 | + | statements: 50 | |
| 43 | + | goconst: | |
| 44 | + | min-len: 2 | |
| 45 | + | min-occurrences: 3 | |
| 46 | + | gocritic: | |
| 47 | + | enabled-tags: | |
| 48 | + | - diagnostic | |
| 49 | + | - experimental | |
| 50 | + | - opinionated | |
| 51 | + | - performance | |
| 52 | + | - style | |
| 53 | + | disabled-checks: | |
| 54 | + | - dupImport | |
| 55 | + | - ifElseChain | |
| 56 | + | - octalLiteral | |
| 57 | + | - whyNoLint | |
| 58 | + | gocyclo: | |
| 59 | + | min-complexity: 15 | |
| 60 | + | godox: | |
| 61 | + | keywords: | |
| 62 | + | - FIXME | |
| 63 | + | - TODO | |
| 64 | + | - BUG | |
| 65 | + | mnd: | |
| 66 | + | checks: | |
| 67 | + | - argument | |
| 68 | + | - case | |
| 69 | + | - condition | |
| 70 | + | - return | |
| 71 | + | ignored-numbers: | |
| 72 | + | - '0' | |
| 73 | + | - '1' | |
| 74 | + | - '2' | |
| 75 | + | - '3' | |
| 76 | + | ignored-functions: | |
| 77 | + | - strings.SplitN | |
| 78 | + | govet: | |
| 79 | + | enable: | |
| 80 | + | - nilness | |
| 81 | + | - shadow | |
| 82 | + | errorlint: | |
| 83 | + | asserts: false | |
| 84 | + | lll: | |
| 85 | + | line-length: 120 | |
| 86 | + | misspell: | |
| 87 | + | locale: US | |
| 88 | + | nolintlint: | |
| 89 | + | allow-unused: false | |
| 90 | + | require-explanation: true | |
| 91 | + | require-specific: true | |
| 92 | + | revive: | |
| 93 | + | rules: | |
| 94 | + | - name: indent-error-flow | |
| 95 | + | - name: unused-parameter | |
| 96 | + | - name: unused-receiver | |
| 97 | + | ||
| 98 | + | issues: | |
| 99 | + | exclude-rules: | |
| 100 | + | # Exclude some linters from running on tests files | |
| 101 | + | - path: _test\.go | |
| 102 | + | linters: | |
| 103 | + | - dupl | |
| 104 | + | - mnd | |
| 105 | + | - lll | |
| 106 | + | - funlen | |
| 107 | + | ||
| 108 | + | # Exclude SQLC generated files from linting | |
| 109 | + | - path: internal/db/.*\.sql\.go | |
| 110 | + | linters: | |
| 111 | + | - all | |
| 112 | + | ||
| 113 | + | # Exclude SQLC generated models from some linters | |
| 114 | + | - path: internal/db/models\.go | |
| 115 | + | linters: | |
| 116 | + | - unused | |
| 117 | + | - deadcode | |
| 118 | + | ||
| 119 | + | # Allow long lines in generated code | |
| 120 | + | - path: internal/db/ | |
| 121 | + | linters: | |
| 122 | + | - lll | |
| 123 | + | ||
| 124 | + | run: | |
| 125 | + | timeout: 5m | |
| 126 | + | modules-download-mode: readonly⏎̸ | |
| @@ -0,0 +1,126 @@ | |||||
| 1 | + | version: "2" | |||
| 2 | + | ||||
| 3 | + | linters: | |||
| 4 | + | default: none | |||
| 5 | + | enable: | |||
| 6 | + | - bodyclose # checks whether HTTP response body is closed successfully | |||
| 7 | + | - copyloopvar # detects places where loop variables are copied | |||
| 8 | + | # - depguard # checks for unwanted dependencies (disabled for CLI apps) | |||
| 9 | + | - dogsled # checks assignments with too many blank identifiers | |||
| 10 | + | - dupl # tool for code clone detection | |||
| 11 | + | - errcheck # checking for unchecked errors | |||
| 12 | + | - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme | |||
| 13 | + | - funlen # tool for detection of long functions | |||
| 14 | + | - gocheckcompilerdirectives # validates go compiler directive comments (//go:) | |||
| 15 | + | # - gochecknoinits # checks that no init functions are present in Go code (disabled for CLI apps) | |||
| 16 | + | - goconst # finds repeated strings that could be replaced by a constant | |||
| 17 | + | - gocritic # provides diagnostics that check for bugs, performance and style issues | |||
| 18 | + | - gocyclo # computes and checks the cyclomatic complexity of functions | |||
| 19 | + | - godox # tool for detection of FIXME, TODO and other comment keywords | |||
| 20 | + | - mnd # detects magic numbers | |||
| 21 | + | - goprintffuncname # checks that printf-like functions are named with `f` at the end | |||
| 22 | + | - gosec # inspects source code for security problems | |||
| 23 | + | - govet # examines Go source code and reports suspicious constructs | |||
| 24 | + | - ineffassign # detects when assignments to existing variables are not used | |||
| 25 | + | - lll # reports long lines | |||
| 26 | + | - misspell # finds commonly misspelled English words in comments | |||
| 27 | + | - nakedret # finds naked returns in functions greater than a specified function length | |||
| 28 | + | - nolintlint # reports ill-formed or insufficient nolint directives | |||
| 29 | + | - revive # fast, configurable, extensible, flexible, and beautiful linter for Go | |||
| 30 | + | - staticcheck # advanced Go linter | |||
| 31 | + | - testifylint # checks usage of github.com/stretchr/testify | |||
| 32 | + | - unconvert # removes unnecessary type conversions | |||
| 33 | + | - unparam # reports unused function parameters | |||
| 34 | + | - unused # checks for unused constants, variables, functions and types | |||
| 35 | + | - whitespace # detects leading and trailing whitespace | |||
| 36 | + | ||||
| 37 | + | linters-settings: | |||
| 38 | + | dupl: | |||
| 39 | + | threshold: 100 | |||
| 40 | + | funlen: | |||
| 41 | + | lines: -1 # don't check line count | |||
| 42 | + | statements: 50 | |||
| 43 | + | goconst: | |||
| 44 | + | min-len: 2 | |||
| 45 | + | min-occurrences: 3 | |||
| 46 | + | gocritic: | |||
| 47 | + | enabled-tags: | |||
| 48 | + | - diagnostic | |||
| 49 | + | - experimental | |||
| 50 | + | - opinionated | |||
| 51 | + | - performance | |||
| 52 | + | - style | |||
| 53 | + | disabled-checks: | |||
| 54 | + | - dupImport | |||
| 55 | + | - ifElseChain | |||
| 56 | + | - octalLiteral | |||
| 57 | + | - whyNoLint | |||
| 58 | + | gocyclo: | |||
| 59 | + | min-complexity: 15 | |||
| 60 | + | godox: | |||
| 61 | + | keywords: | |||
| 62 | + | - FIXME | |||
| 63 | + | - TODO | |||
| 64 | + | - BUG | |||
| 65 | + | mnd: | |||
| 66 | + | checks: | |||
| 67 | + | - argument | |||
| 68 | + | - case | |||
| 69 | + | - condition | |||
| 70 | + | - return | |||
| 71 | + | ignored-numbers: | |||
| 72 | + | - '0' | |||
| 73 | + | - '1' | |||
| 74 | + | - '2' | |||
| 75 | + | - '3' | |||
| 76 | + | ignored-functions: | |||
| 77 | + | - strings.SplitN | |||
| 78 | + | govet: | |||
| 79 | + | enable: | |||
| 80 | + | - nilness | |||
| 81 | + | - shadow | |||
| 82 | + | errorlint: | |||
| 83 | + | asserts: false | |||
| 84 | + | lll: | |||
| 85 | + | line-length: 120 | |||
| 86 | + | misspell: | |||
| 87 | + | locale: US | |||
| 88 | + | nolintlint: | |||
| 89 | + | allow-unused: false | |||
| 90 | + | require-explanation: true | |||
| 91 | + | require-specific: true | |||
| 92 | + | revive: | |||
| 93 | + | rules: | |||
| 94 | + | - name: indent-error-flow | |||
| 95 | + | - name: unused-parameter | |||
| 96 | + | - name: unused-receiver | |||
| 97 | + | ||||
| 98 | + | issues: | |||
| 99 | + | exclude-rules: | |||
| 100 | + | # Exclude some linters from running on tests files | |||
| 101 | + | - path: _test\.go | |||
| 102 | + | linters: | |||
| 103 | + | - dupl | |||
| 104 | + | - mnd | |||
| 105 | + | - lll | |||
| 106 | + | - funlen | |||
| 107 | + | ||||
| 108 | + | # Exclude SQLC generated files from linting | |||
| 109 | + | - path: internal/db/.*\.sql\.go | |||
| 110 | + | linters: | |||
| 111 | + | - all | |||
| 112 | + | ||||
| 113 | + | # Exclude SQLC generated models from some linters | |||
| 114 | + | - path: internal/db/models\.go | |||
| 115 | + | linters: | |||
| 116 | + | - unused | |||
| 117 | + | - deadcode | |||
| 118 | + | ||||
| 119 | + | # Allow long lines in generated code | |||
| 120 | + | - path: internal/db/ | |||
| 121 | + | linters: | |||
| 122 | + | - lll | |||
| 123 | + | ||||
| 124 | + | run: | |||
| 125 | + | timeout: 5m | |||
| 126 | + | modules-download-mode: readonly⏎̸ | |||
A Makefile +100 -0
| @@ -0,0 +1,100 @@ | |||
| 1 | + | # Makefile for dumb-browser | |
| 2 | + | ||
| 3 | + | .PHONY: build test lint clean install-tools dev generate help | |
| 4 | + | ||
| 5 | + | # Variables | |
| 6 | + | BINARY_NAME=dumb-browser | |
| 7 | + | MAIN_PATH=./cmd/dumb-browser | |
| 8 | + | DIST_DIR=dist | |
| 9 | + | ||
| 10 | + | # Version information from git | |
| 11 | + | VERSION=$(shell git describe --tags --always --dirty 2>/dev/null || echo "v0.0.0-dev") | |
| 12 | + | COMMIT=$(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") | |
| 13 | + | BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") | |
| 14 | + | ||
| 15 | + | # Linker flags | |
| 16 | + | LDFLAGS=-ldflags "-s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.buildDate=$(BUILD_DATE)" | |
| 17 | + | ||
| 18 | + | # Default target | |
| 19 | + | help: ## Show this help message | |
| 20 | + | @echo "Available targets:" | |
| 21 | + | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | |
| 22 | + | ||
| 23 | + | # Build targets | |
| 24 | + | build: ## Build the binary | |
| 25 | + | @echo "Building $(BINARY_NAME) $(VERSION)..." | |
| 26 | + | @mkdir -p $(DIST_DIR) | |
| 27 | + | CGO_ENABLED=0 go build $(LDFLAGS) -o $(DIST_DIR)/$(BINARY_NAME) $(MAIN_PATH) | |
| 28 | + | ||
| 29 | + | build-wails: ## Build with CGO enabled for Wails (when needed) | |
| 30 | + | @echo "Building $(BINARY_NAME) $(VERSION) with CGO enabled..." | |
| 31 | + | @mkdir -p $(DIST_DIR) | |
| 32 | + | CGO_ENABLED=1 go build $(LDFLAGS) -o $(DIST_DIR)/$(BINARY_NAME) $(MAIN_PATH) | |
| 33 | + | ||
| 34 | + | # Development targets | |
| 35 | + | dev: ## Run in development mode | |
| 36 | + | @echo "Running in development mode..." | |
| 37 | + | go run $(MAIN_PATH) | |
| 38 | + | ||
| 39 | + | generate: ## Generate code (SQLC) | |
| 40 | + | @echo "Generating code with SQLC..." | |
| 41 | + | sqlc generate | |
| 42 | + | @echo "Code generation complete" | |
| 43 | + | ||
| 44 | + | # Testing | |
| 45 | + | test: ## Run tests | |
| 46 | + | @echo "Running tests..." | |
| 47 | + | CGO_ENABLED=0 go test -v ./... | |
| 48 | + | ||
| 49 | + | test-race: ## Run tests with race detection | |
| 50 | + | @echo "Running tests with race detection..." | |
| 51 | + | CGO_ENABLED=1 go test -race -v ./... | |
| 52 | + | ||
| 53 | + | # Linting | |
| 54 | + | lint: ## Run golangci-lint | |
| 55 | + | @echo "Running golangci-lint..." | |
| 56 | + | golangci-lint run | |
| 57 | + | ||
| 58 | + | lint-fix: ## Run golangci-lint with --fix | |
| 59 | + | @echo "Running golangci-lint with --fix..." | |
| 60 | + | golangci-lint run --fix | |
| 61 | + | ||
| 62 | + | # Tools installation | |
| 63 | + | install-tools: ## Install development tools | |
| 64 | + | @echo "Installing development tools..." | |
| 65 | + | go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest | |
| 66 | + | go install github.com/wailsapp/wails/v3/cmd/wails3@latest | |
| 67 | + | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest | |
| 68 | + | @echo "Tools installed successfully" | |
| 69 | + | ||
| 70 | + | # Cleanup | |
| 71 | + | clean: ## Clean build artifacts | |
| 72 | + | @echo "Cleaning build artifacts..." | |
| 73 | + | rm -rf $(DIST_DIR) | |
| 74 | + | rm -f $(BINARY_NAME) # Remove any old binaries in root | |
| 75 | + | go clean -cache | |
| 76 | + | go clean -testcache | |
| 77 | + | ||
| 78 | + | # Project initialization | |
| 79 | + | init: install-tools ## Initialize project dependencies and tools | |
| 80 | + | @echo "Project dependencies and tools installed!" | |
| 81 | + | @echo "Ready for development. Run 'make help' for available commands." | |
| 82 | + | ||
| 83 | + | # Check setup | |
| 84 | + | check: ## Check that all tools and dependencies are working | |
| 85 | + | @echo "Checking project setup..." | |
| 86 | + | @echo "Go version:" | |
| 87 | + | @go version | |
| 88 | + | @echo "\nSQLC version:" | |
| 89 | + | @sqlc version | |
| 90 | + | @echo "\nWails version:" | |
| 91 | + | @wails3 version | |
| 92 | + | @echo "\nGolangci-lint version:" | |
| 93 | + | @golangci-lint version | |
| 94 | + | @echo "\nBuilding project..." | |
| 95 | + | @make build | |
| 96 | + | @echo "\nTesting built binary..." | |
| 97 | + | @$(DIST_DIR)/$(BINARY_NAME) version | |
| 98 | + | @echo "\nRunning tests..." | |
| 99 | + | @make test | |
| 100 | + | @echo "\n✅ All checks passed! Project is ready for development."⏎̸ | |
| @@ -0,0 +1,100 @@ | |||||
| 1 | + | # Makefile for dumb-browser | |||
| 2 | + | ||||
| 3 | + | .PHONY: build test lint clean install-tools dev generate help | |||
| 4 | + | ||||
| 5 | + | # Variables | |||
| 6 | + | BINARY_NAME=dumb-browser | |||
| 7 | + | MAIN_PATH=./cmd/dumb-browser | |||
| 8 | + | DIST_DIR=dist | |||
| 9 | + | ||||
| 10 | + | # Version information from git | |||
| 11 | + | VERSION=$(shell git describe --tags --always --dirty 2>/dev/null || echo "v0.0.0-dev") | |||
| 12 | + | COMMIT=$(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown") | |||
| 13 | + | BUILD_DATE=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") | |||
| 14 | + | ||||
| 15 | + | # Linker flags | |||
| 16 | + | LDFLAGS=-ldflags "-s -w -X main.version=$(VERSION) -X main.commit=$(COMMIT) -X main.buildDate=$(BUILD_DATE)" | |||
| 17 | + | ||||
| 18 | + | # Default target | |||
| 19 | + | help: ## Show this help message | |||
| 20 | + | @echo "Available targets:" | |||
| 21 | + | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | |||
| 22 | + | ||||
| 23 | + | # Build targets | |||
| 24 | + | build: ## Build the binary | |||
| 25 | + | @echo "Building $(BINARY_NAME) $(VERSION)..." | |||
| 26 | + | @mkdir -p $(DIST_DIR) | |||
| 27 | + | CGO_ENABLED=0 go build $(LDFLAGS) -o $(DIST_DIR)/$(BINARY_NAME) $(MAIN_PATH) | |||
| 28 | + | ||||
| 29 | + | build-wails: ## Build with CGO enabled for Wails (when needed) | |||
| 30 | + | @echo "Building $(BINARY_NAME) $(VERSION) with CGO enabled..." | |||
| 31 | + | @mkdir -p $(DIST_DIR) | |||
| 32 | + | CGO_ENABLED=1 go build $(LDFLAGS) -o $(DIST_DIR)/$(BINARY_NAME) $(MAIN_PATH) | |||
| 33 | + | ||||
| 34 | + | # Development targets | |||
| 35 | + | dev: ## Run in development mode | |||
| 36 | + | @echo "Running in development mode..." | |||
| 37 | + | go run $(MAIN_PATH) | |||
| 38 | + | ||||
| 39 | + | generate: ## Generate code (SQLC) | |||
| 40 | + | @echo "Generating code with SQLC..." | |||
| 41 | + | sqlc generate | |||
| 42 | + | @echo "Code generation complete" | |||
| 43 | + | ||||
| 44 | + | # Testing | |||
| 45 | + | test: ## Run tests | |||
| 46 | + | @echo "Running tests..." | |||
| 47 | + | CGO_ENABLED=0 go test -v ./... | |||
| 48 | + | ||||
| 49 | + | test-race: ## Run tests with race detection | |||
| 50 | + | @echo "Running tests with race detection..." | |||
| 51 | + | CGO_ENABLED=1 go test -race -v ./... | |||
| 52 | + | ||||
| 53 | + | # Linting | |||
| 54 | + | lint: ## Run golangci-lint | |||
| 55 | + | @echo "Running golangci-lint..." | |||
| 56 | + | golangci-lint run | |||
| 57 | + | ||||
| 58 | + | lint-fix: ## Run golangci-lint with --fix | |||
| 59 | + | @echo "Running golangci-lint with --fix..." | |||
| 60 | + | golangci-lint run --fix | |||
| 61 | + | ||||
| 62 | + | # Tools installation | |||
| 63 | + | install-tools: ## Install development tools | |||
| 64 | + | @echo "Installing development tools..." | |||
| 65 | + | go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest | |||
| 66 | + | go install github.com/wailsapp/wails/v3/cmd/wails3@latest | |||
| 67 | + | go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest | |||
| 68 | + | @echo "Tools installed successfully" | |||
| 69 | + | ||||
| 70 | + | # Cleanup | |||
| 71 | + | clean: ## Clean build artifacts | |||
| 72 | + | @echo "Cleaning build artifacts..." | |||
| 73 | + | rm -rf $(DIST_DIR) | |||
| 74 | + | rm -f $(BINARY_NAME) # Remove any old binaries in root | |||
| 75 | + | go clean -cache | |||
| 76 | + | go clean -testcache | |||
| 77 | + | ||||
| 78 | + | # Project initialization | |||
| 79 | + | init: install-tools ## Initialize project dependencies and tools | |||
| 80 | + | @echo "Project dependencies and tools installed!" | |||
| 81 | + | @echo "Ready for development. Run 'make help' for available commands." | |||
| 82 | + | ||||
| 83 | + | # Check setup | |||
| 84 | + | check: ## Check that all tools and dependencies are working | |||
| 85 | + | @echo "Checking project setup..." | |||
| 86 | + | @echo "Go version:" | |||
| 87 | + | @go version | |||
| 88 | + | @echo "\nSQLC version:" | |||
| 89 | + | @sqlc version | |||
| 90 | + | @echo "\nWails version:" | |||
| 91 | + | @wails3 version | |||
| 92 | + | @echo "\nGolangci-lint version:" | |||
| 93 | + | @golangci-lint version | |||
| 94 | + | @echo "\nBuilding project..." | |||
| 95 | + | @make build | |||
| 96 | + | @echo "\nTesting built binary..." | |||
| 97 | + | @$(DIST_DIR)/$(BINARY_NAME) version | |||
| 98 | + | @echo "\nRunning tests..." | |||
| 99 | + | @make test | |||
| 100 | + | @echo "\n✅ All checks passed! Project is ready for development."⏎̸ | |||
A configs/sqlc.yaml +15 -0
| @@ -0,0 +1,15 @@ | |||
| 1 | + | version: "2" | |
| 2 | + | sql: | |
| 3 | + | - engine: "sqlite" | |
| 4 | + | queries: "./internal/db/queries/" | |
| 5 | + | schema: "./migrations/" | |
| 6 | + | gen: | |
| 7 | + | go: | |
| 8 | + | package: "db" | |
| 9 | + | out: "./internal/db" | |
| 10 | + | sql_package: "database/sql" | |
| 11 | + | emit_json_tags: true | |
| 12 | + | emit_empty_slices: true | |
| 13 | + | emit_exported_queries: true | |
| 14 | + | emit_interface: true | |
| 15 | + | query_parameter_limit: 5⏎̸ | |
| @@ -0,0 +1,15 @@ | |||||
| 1 | + | version: "2" | |||
| 2 | + | sql: | |||
| 3 | + | - engine: "sqlite" | |||
| 4 | + | queries: "./internal/db/queries/" | |||
| 5 | + | schema: "./migrations/" | |||
| 6 | + | gen: | |||
| 7 | + | go: | |||
| 8 | + | package: "db" | |||
| 9 | + | out: "./internal/db" | |||
| 10 | + | sql_package: "database/sql" | |||
| 11 | + | emit_json_tags: true | |||
| 12 | + | emit_empty_slices: true | |||
| 13 | + | emit_exported_queries: true | |||
| 14 | + | emit_interface: true | |||
| 15 | + | query_parameter_limit: 5⏎̸ | |||
A go.mod +32 -0
| @@ -0,0 +1,32 @@ | |||
| 1 | + | module dumb-browser | |
| 2 | + | ||
| 3 | + | go 1.25.1 | |
| 4 | + | ||
| 5 | + | require ( | |
| 6 | + | github.com/fsnotify/fsnotify v1.9.0 // indirect | |
| 7 | + | github.com/gabriel-vasile/mimetype v1.4.8 // indirect | |
| 8 | + | github.com/go-playground/locales v0.14.1 // indirect | |
| 9 | + | github.com/go-playground/universal-translator v0.18.1 // indirect | |
| 10 | + | github.com/go-playground/validator/v10 v10.27.0 // indirect | |
| 11 | + | github.com/go-viper/mapstructure/v2 v2.4.0 // indirect | |
| 12 | + | github.com/inconshreveable/mousetrap v1.1.0 // indirect | |
| 13 | + | github.com/leodido/go-urn v1.4.0 // indirect | |
| 14 | + | github.com/ncruces/go-sqlite3 v0.29.0 // indirect | |
| 15 | + | github.com/ncruces/julianday v1.0.0 // indirect | |
| 16 | + | github.com/pelletier/go-toml/v2 v2.2.4 // indirect | |
| 17 | + | github.com/sagikazarmark/locafero v0.11.0 // indirect | |
| 18 | + | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect | |
| 19 | + | github.com/spf13/afero v1.15.0 // indirect | |
| 20 | + | github.com/spf13/cast v1.10.0 // indirect | |
| 21 | + | github.com/spf13/cobra v1.10.1 // indirect | |
| 22 | + | github.com/spf13/pflag v1.0.10 // indirect | |
| 23 | + | github.com/spf13/viper v1.21.0 // indirect | |
| 24 | + | github.com/stretchr/testify v1.11.1 // indirect | |
| 25 | + | github.com/subosito/gotenv v1.6.0 // indirect | |
| 26 | + | github.com/tetratelabs/wazero v1.9.0 // indirect | |
| 27 | + | go.yaml.in/yaml/v3 v3.0.4 // indirect | |
| 28 | + | golang.org/x/crypto v0.41.0 // indirect | |
| 29 | + | golang.org/x/net v0.42.0 // indirect | |
| 30 | + | golang.org/x/sys v0.36.0 // indirect | |
| 31 | + | golang.org/x/text v0.29.0 // indirect | |
| 32 | + | ) | |
| @@ -0,0 +1,32 @@ | |||||
| 1 | + | module dumb-browser | |||
| 2 | + | ||||
| 3 | + | go 1.25.1 | |||
| 4 | + | ||||
| 5 | + | require ( | |||
| 6 | + | github.com/fsnotify/fsnotify v1.9.0 // indirect | |||
| 7 | + | github.com/gabriel-vasile/mimetype v1.4.8 // indirect | |||
| 8 | + | github.com/go-playground/locales v0.14.1 // indirect | |||
| 9 | + | github.com/go-playground/universal-translator v0.18.1 // indirect | |||
| 10 | + | github.com/go-playground/validator/v10 v10.27.0 // indirect | |||
| 11 | + | github.com/go-viper/mapstructure/v2 v2.4.0 // indirect | |||
| 12 | + | github.com/inconshreveable/mousetrap v1.1.0 // indirect | |||
| 13 | + | github.com/leodido/go-urn v1.4.0 // indirect | |||
| 14 | + | github.com/ncruces/go-sqlite3 v0.29.0 // indirect | |||
| 15 | + | github.com/ncruces/julianday v1.0.0 // indirect | |||
| 16 | + | github.com/pelletier/go-toml/v2 v2.2.4 // indirect | |||
| 17 | + | github.com/sagikazarmark/locafero v0.11.0 // indirect | |||
| 18 | + | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect | |||
| 19 | + | github.com/spf13/afero v1.15.0 // indirect | |||
| 20 | + | github.com/spf13/cast v1.10.0 // indirect | |||
| 21 | + | github.com/spf13/cobra v1.10.1 // indirect | |||
| 22 | + | github.com/spf13/pflag v1.0.10 // indirect | |||
| 23 | + | github.com/spf13/viper v1.21.0 // indirect | |||
| 24 | + | github.com/stretchr/testify v1.11.1 // indirect | |||
| 25 | + | github.com/subosito/gotenv v1.6.0 // indirect | |||
| 26 | + | github.com/tetratelabs/wazero v1.9.0 // indirect | |||
| 27 | + | go.yaml.in/yaml/v3 v3.0.4 // indirect | |||
| 28 | + | golang.org/x/crypto v0.41.0 // indirect | |||
| 29 | + | golang.org/x/net v0.42.0 // indirect | |||
| 30 | + | golang.org/x/sys v0.36.0 // indirect | |||
| 31 | + | golang.org/x/text v0.29.0 // indirect | |||
| 32 | + | ) | |||
A go.sum +61 -0
| @@ -0,0 +1,61 @@ | |||
| 1 | + | github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= | |
| 2 | + | github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= | |
| 3 | + | github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= | |
| 4 | + | github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= | |
| 5 | + | github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= | |
| 6 | + | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= | |
| 7 | + | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= | |
| 8 | + | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= | |
| 9 | + | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= | |
| 10 | + | github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= | |
| 11 | + | github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= | |
| 12 | + | github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= | |
| 13 | + | github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= | |
| 14 | + | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | |
| 15 | + | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | |
| 16 | + | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= | |
| 17 | + | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | |
| 18 | + | github.com/ncruces/go-sqlite3 v0.29.0 h1:1tsLiagCoqZEfcHDeKsNSv5jvrY/Iu393pAnw2wLNJU= | |
| 19 | + | github.com/ncruces/go-sqlite3 v0.29.0/go.mod h1:r1hSvYKPNJ+OlUA1O3r8o9LAawzPAlqeZiIdxTBBBJ0= | |
| 20 | + | github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= | |
| 21 | + | github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= | |
| 22 | + | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= | |
| 23 | + | github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= | |
| 24 | + | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | |
| 25 | + | github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= | |
| 26 | + | github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= | |
| 27 | + | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= | |
| 28 | + | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= | |
| 29 | + | github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= | |
| 30 | + | github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= | |
| 31 | + | github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= | |
| 32 | + | github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= | |
| 33 | + | github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= | |
| 34 | + | github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= | |
| 35 | + | github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | |
| 36 | + | github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= | |
| 37 | + | github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | |
| 38 | + | github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= | |
| 39 | + | github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= | |
| 40 | + | github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= | |
| 41 | + | github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= | |
| 42 | + | github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= | |
| 43 | + | github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= | |
| 44 | + | github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= | |
| 45 | + | github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= | |
| 46 | + | go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= | |
| 47 | + | go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= | |
| 48 | + | golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= | |
| 49 | + | golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= | |
| 50 | + | golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= | |
| 51 | + | golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= | |
| 52 | + | golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= | |
| 53 | + | golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | |
| 54 | + | golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= | |
| 55 | + | golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= | |
| 56 | + | golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= | |
| 57 | + | golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= | |
| 58 | + | golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= | |
| 59 | + | golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= | |
| 60 | + | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |
| 61 | + | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
| @@ -0,0 +1,61 @@ | |||||
| 1 | + | github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= | |||
| 2 | + | github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= | |||
| 3 | + | github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= | |||
| 4 | + | github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= | |||
| 5 | + | github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= | |||
| 6 | + | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= | |||
| 7 | + | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= | |||
| 8 | + | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= | |||
| 9 | + | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= | |||
| 10 | + | github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= | |||
| 11 | + | github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= | |||
| 12 | + | github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= | |||
| 13 | + | github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= | |||
| 14 | + | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | |||
| 15 | + | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | |||
| 16 | + | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= | |||
| 17 | + | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= | |||
| 18 | + | github.com/ncruces/go-sqlite3 v0.29.0 h1:1tsLiagCoqZEfcHDeKsNSv5jvrY/Iu393pAnw2wLNJU= | |||
| 19 | + | github.com/ncruces/go-sqlite3 v0.29.0/go.mod h1:r1hSvYKPNJ+OlUA1O3r8o9LAawzPAlqeZiIdxTBBBJ0= | |||
| 20 | + | github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M= | |||
| 21 | + | github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= | |||
| 22 | + | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= | |||
| 23 | + | github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= | |||
| 24 | + | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | |||
| 25 | + | github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= | |||
| 26 | + | github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= | |||
| 27 | + | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= | |||
| 28 | + | github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= | |||
| 29 | + | github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= | |||
| 30 | + | github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= | |||
| 31 | + | github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= | |||
| 32 | + | github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= | |||
| 33 | + | github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= | |||
| 34 | + | github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= | |||
| 35 | + | github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | |||
| 36 | + | github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= | |||
| 37 | + | github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | |||
| 38 | + | github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= | |||
| 39 | + | github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= | |||
| 40 | + | github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= | |||
| 41 | + | github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= | |||
| 42 | + | github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= | |||
| 43 | + | github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= | |||
| 44 | + | github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= | |||
| 45 | + | github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= | |||
| 46 | + | go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= | |||
| 47 | + | go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= | |||
| 48 | + | golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= | |||
| 49 | + | golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= | |||
| 50 | + | golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= | |||
| 51 | + | golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= | |||
| 52 | + | golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= | |||
| 53 | + | golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | |||
| 54 | + | golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= | |||
| 55 | + | golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= | |||
| 56 | + | golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= | |||
| 57 | + | golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= | |||
| 58 | + | golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= | |||
| 59 | + | golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= | |||
| 60 | + | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | |||
| 61 | + | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |||
A internal/db/db.go +31 -0
| @@ -0,0 +1,31 @@ | |||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |
| 2 | + | // versions: | |
| 3 | + | // sqlc v1.30.0 | |
| 4 | + | ||
| 5 | + | package db | |
| 6 | + | ||
| 7 | + | import ( | |
| 8 | + | "context" | |
| 9 | + | "database/sql" | |
| 10 | + | ) | |
| 11 | + | ||
| 12 | + | type DBTX interface { | |
| 13 | + | ExecContext(context.Context, string, ...interface{}) (sql.Result, error) | |
| 14 | + | PrepareContext(context.Context, string) (*sql.Stmt, error) | |
| 15 | + | QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) | |
| 16 | + | QueryRowContext(context.Context, string, ...interface{}) *sql.Row | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | func New(db DBTX) *Queries { | |
| 20 | + | return &Queries{db: db} | |
| 21 | + | } | |
| 22 | + | ||
| 23 | + | type Queries struct { | |
| 24 | + | db DBTX | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | func (q *Queries) WithTx(tx *sql.Tx) *Queries { | |
| 28 | + | return &Queries{ | |
| 29 | + | db: tx, | |
| 30 | + | } | |
| 31 | + | } | |
| @@ -0,0 +1,31 @@ | |||||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |||
| 2 | + | // versions: | |||
| 3 | + | // sqlc v1.30.0 | |||
| 4 | + | ||||
| 5 | + | package db | |||
| 6 | + | ||||
| 7 | + | import ( | |||
| 8 | + | "context" | |||
| 9 | + | "database/sql" | |||
| 10 | + | ) | |||
| 11 | + | ||||
| 12 | + | type DBTX interface { | |||
| 13 | + | ExecContext(context.Context, string, ...interface{}) (sql.Result, error) | |||
| 14 | + | PrepareContext(context.Context, string) (*sql.Stmt, error) | |||
| 15 | + | QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) | |||
| 16 | + | QueryRowContext(context.Context, string, ...interface{}) *sql.Row | |||
| 17 | + | } | |||
| 18 | + | ||||
| 19 | + | func New(db DBTX) *Queries { | |||
| 20 | + | return &Queries{db: db} | |||
| 21 | + | } | |||
| 22 | + | ||||
| 23 | + | type Queries struct { | |||
| 24 | + | db DBTX | |||
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | func (q *Queries) WithTx(tx *sql.Tx) *Queries { | |||
| 28 | + | return &Queries{ | |||
| 29 | + | db: tx, | |||
| 30 | + | } | |||
| 31 | + | } | |||
A internal/db/history.sql.go +136 -0
| @@ -0,0 +1,136 @@ | |||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |
| 2 | + | // versions: | |
| 3 | + | // sqlc v1.30.0 | |
| 4 | + | // source: history.sql | |
| 5 | + | ||
| 6 | + | package db | |
| 7 | + | ||
| 8 | + | import ( | |
| 9 | + | "context" | |
| 10 | + | "database/sql" | |
| 11 | + | ) | |
| 12 | + | ||
| 13 | + | const AddOrUpdateHistory = `-- name: AddOrUpdateHistory :exec | |
| 14 | + | INSERT INTO history (url, title) | |
| 15 | + | VALUES (?, ?) | |
| 16 | + | ON CONFLICT(url) | |
| 17 | + | DO UPDATE SET | |
| 18 | + | visit_count = visit_count + 1, | |
| 19 | + | last_visited = CURRENT_TIMESTAMP, | |
| 20 | + | title = EXCLUDED.title | |
| 21 | + | ` | |
| 22 | + | ||
| 23 | + | func (q *Queries) AddOrUpdateHistory(ctx context.Context, url string, title sql.NullString) error { | |
| 24 | + | _, err := q.db.ExecContext(ctx, AddOrUpdateHistory, url, title) | |
| 25 | + | return err | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | const GetHistory = `-- name: GetHistory :many | |
| 29 | + | SELECT id, url, title, visit_count, last_visited, created_at | |
| 30 | + | FROM history | |
| 31 | + | ORDER BY last_visited DESC | |
| 32 | + | LIMIT ? | |
| 33 | + | ` | |
| 34 | + | ||
| 35 | + | func (q *Queries) GetHistory(ctx context.Context, limit int64) ([]History, error) { | |
| 36 | + | rows, err := q.db.QueryContext(ctx, GetHistory, limit) | |
| 37 | + | if err != nil { | |
| 38 | + | return nil, err | |
| 39 | + | } | |
| 40 | + | defer rows.Close() | |
| 41 | + | items := []History{} | |
| 42 | + | for rows.Next() { | |
| 43 | + | var i History | |
| 44 | + | if err := rows.Scan( | |
| 45 | + | &i.ID, | |
| 46 | + | &i.Url, | |
| 47 | + | &i.Title, | |
| 48 | + | &i.VisitCount, | |
| 49 | + | &i.LastVisited, | |
| 50 | + | &i.CreatedAt, | |
| 51 | + | ); err != nil { | |
| 52 | + | return nil, err | |
| 53 | + | } | |
| 54 | + | items = append(items, i) | |
| 55 | + | } | |
| 56 | + | if err := rows.Close(); err != nil { | |
| 57 | + | return nil, err | |
| 58 | + | } | |
| 59 | + | if err := rows.Err(); err != nil { | |
| 60 | + | return nil, err | |
| 61 | + | } | |
| 62 | + | return items, nil | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | const GetShortcuts = `-- name: GetShortcuts :many | |
| 66 | + | SELECT id, shortcut, url_template, description, created_at | |
| 67 | + | FROM shortcuts | |
| 68 | + | ORDER BY shortcut | |
| 69 | + | ` | |
| 70 | + | ||
| 71 | + | func (q *Queries) GetShortcuts(ctx context.Context) ([]Shortcut, error) { | |
| 72 | + | rows, err := q.db.QueryContext(ctx, GetShortcuts) | |
| 73 | + | if err != nil { | |
| 74 | + | return nil, err | |
| 75 | + | } | |
| 76 | + | defer rows.Close() | |
| 77 | + | items := []Shortcut{} | |
| 78 | + | for rows.Next() { | |
| 79 | + | var i Shortcut | |
| 80 | + | if err := rows.Scan( | |
| 81 | + | &i.ID, | |
| 82 | + | &i.Shortcut, | |
| 83 | + | &i.UrlTemplate, | |
| 84 | + | &i.Description, | |
| 85 | + | &i.CreatedAt, | |
| 86 | + | ); err != nil { | |
| 87 | + | return nil, err | |
| 88 | + | } | |
| 89 | + | items = append(items, i) | |
| 90 | + | } | |
| 91 | + | if err := rows.Close(); err != nil { | |
| 92 | + | return nil, err | |
| 93 | + | } | |
| 94 | + | if err := rows.Err(); err != nil { | |
| 95 | + | return nil, err | |
| 96 | + | } | |
| 97 | + | return items, nil | |
| 98 | + | } | |
| 99 | + | ||
| 100 | + | const SearchHistory = `-- name: SearchHistory :many | |
| 101 | + | SELECT id, url, title, visit_count, last_visited, created_at | |
| 102 | + | FROM history | |
| 103 | + | WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%' | |
| 104 | + | ORDER BY visit_count DESC, last_visited DESC | |
| 105 | + | LIMIT ? | |
| 106 | + | ` | |
| 107 | + | ||
| 108 | + | func (q *Queries) SearchHistory(ctx context.Context, column1 sql.NullString, column2 sql.NullString, limit int64) ([]History, error) { | |
| 109 | + | rows, err := q.db.QueryContext(ctx, SearchHistory, column1, column2, limit) | |
| 110 | + | if err != nil { | |
| 111 | + | return nil, err | |
| 112 | + | } | |
| 113 | + | defer rows.Close() | |
| 114 | + | items := []History{} | |
| 115 | + | for rows.Next() { | |
| 116 | + | var i History | |
| 117 | + | if err := rows.Scan( | |
| 118 | + | &i.ID, | |
| 119 | + | &i.Url, | |
| 120 | + | &i.Title, | |
| 121 | + | &i.VisitCount, | |
| 122 | + | &i.LastVisited, | |
| 123 | + | &i.CreatedAt, | |
| 124 | + | ); err != nil { | |
| 125 | + | return nil, err | |
| 126 | + | } | |
| 127 | + | items = append(items, i) | |
| 128 | + | } | |
| 129 | + | if err := rows.Close(); err != nil { | |
| 130 | + | return nil, err | |
| 131 | + | } | |
| 132 | + | if err := rows.Err(); err != nil { | |
| 133 | + | return nil, err | |
| 134 | + | } | |
| 135 | + | return items, nil | |
| 136 | + | } | |
| @@ -0,0 +1,136 @@ | |||||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |||
| 2 | + | // versions: | |||
| 3 | + | // sqlc v1.30.0 | |||
| 4 | + | // source: history.sql | |||
| 5 | + | ||||
| 6 | + | package db | |||
| 7 | + | ||||
| 8 | + | import ( | |||
| 9 | + | "context" | |||
| 10 | + | "database/sql" | |||
| 11 | + | ) | |||
| 12 | + | ||||
| 13 | + | const AddOrUpdateHistory = `-- name: AddOrUpdateHistory :exec | |||
| 14 | + | INSERT INTO history (url, title) | |||
| 15 | + | VALUES (?, ?) | |||
| 16 | + | ON CONFLICT(url) | |||
| 17 | + | DO UPDATE SET | |||
| 18 | + | visit_count = visit_count + 1, | |||
| 19 | + | last_visited = CURRENT_TIMESTAMP, | |||
| 20 | + | title = EXCLUDED.title | |||
| 21 | + | ` | |||
| 22 | + | ||||
| 23 | + | func (q *Queries) AddOrUpdateHistory(ctx context.Context, url string, title sql.NullString) error { | |||
| 24 | + | _, err := q.db.ExecContext(ctx, AddOrUpdateHistory, url, title) | |||
| 25 | + | return err | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | const GetHistory = `-- name: GetHistory :many | |||
| 29 | + | SELECT id, url, title, visit_count, last_visited, created_at | |||
| 30 | + | FROM history | |||
| 31 | + | ORDER BY last_visited DESC | |||
| 32 | + | LIMIT ? | |||
| 33 | + | ` | |||
| 34 | + | ||||
| 35 | + | func (q *Queries) GetHistory(ctx context.Context, limit int64) ([]History, error) { | |||
| 36 | + | rows, err := q.db.QueryContext(ctx, GetHistory, limit) | |||
| 37 | + | if err != nil { | |||
| 38 | + | return nil, err | |||
| 39 | + | } | |||
| 40 | + | defer rows.Close() | |||
| 41 | + | items := []History{} | |||
| 42 | + | for rows.Next() { | |||
| 43 | + | var i History | |||
| 44 | + | if err := rows.Scan( | |||
| 45 | + | &i.ID, | |||
| 46 | + | &i.Url, | |||
| 47 | + | &i.Title, | |||
| 48 | + | &i.VisitCount, | |||
| 49 | + | &i.LastVisited, | |||
| 50 | + | &i.CreatedAt, | |||
| 51 | + | ); err != nil { | |||
| 52 | + | return nil, err | |||
| 53 | + | } | |||
| 54 | + | items = append(items, i) | |||
| 55 | + | } | |||
| 56 | + | if err := rows.Close(); err != nil { | |||
| 57 | + | return nil, err | |||
| 58 | + | } | |||
| 59 | + | if err := rows.Err(); err != nil { | |||
| 60 | + | return nil, err | |||
| 61 | + | } | |||
| 62 | + | return items, nil | |||
| 63 | + | } | |||
| 64 | + | ||||
| 65 | + | const GetShortcuts = `-- name: GetShortcuts :many | |||
| 66 | + | SELECT id, shortcut, url_template, description, created_at | |||
| 67 | + | FROM shortcuts | |||
| 68 | + | ORDER BY shortcut | |||
| 69 | + | ` | |||
| 70 | + | ||||
| 71 | + | func (q *Queries) GetShortcuts(ctx context.Context) ([]Shortcut, error) { | |||
| 72 | + | rows, err := q.db.QueryContext(ctx, GetShortcuts) | |||
| 73 | + | if err != nil { | |||
| 74 | + | return nil, err | |||
| 75 | + | } | |||
| 76 | + | defer rows.Close() | |||
| 77 | + | items := []Shortcut{} | |||
| 78 | + | for rows.Next() { | |||
| 79 | + | var i Shortcut | |||
| 80 | + | if err := rows.Scan( | |||
| 81 | + | &i.ID, | |||
| 82 | + | &i.Shortcut, | |||
| 83 | + | &i.UrlTemplate, | |||
| 84 | + | &i.Description, | |||
| 85 | + | &i.CreatedAt, | |||
| 86 | + | ); err != nil { | |||
| 87 | + | return nil, err | |||
| 88 | + | } | |||
| 89 | + | items = append(items, i) | |||
| 90 | + | } | |||
| 91 | + | if err := rows.Close(); err != nil { | |||
| 92 | + | return nil, err | |||
| 93 | + | } | |||
| 94 | + | if err := rows.Err(); err != nil { | |||
| 95 | + | return nil, err | |||
| 96 | + | } | |||
| 97 | + | return items, nil | |||
| 98 | + | } | |||
| 99 | + | ||||
| 100 | + | const SearchHistory = `-- name: SearchHistory :many | |||
| 101 | + | SELECT id, url, title, visit_count, last_visited, created_at | |||
| 102 | + | FROM history | |||
| 103 | + | WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%' | |||
| 104 | + | ORDER BY visit_count DESC, last_visited DESC | |||
| 105 | + | LIMIT ? | |||
| 106 | + | ` | |||
| 107 | + | ||||
| 108 | + | func (q *Queries) SearchHistory(ctx context.Context, column1 sql.NullString, column2 sql.NullString, limit int64) ([]History, error) { | |||
| 109 | + | rows, err := q.db.QueryContext(ctx, SearchHistory, column1, column2, limit) | |||
| 110 | + | if err != nil { | |||
| 111 | + | return nil, err | |||
| 112 | + | } | |||
| 113 | + | defer rows.Close() | |||
| 114 | + | items := []History{} | |||
| 115 | + | for rows.Next() { | |||
| 116 | + | var i History | |||
| 117 | + | if err := rows.Scan( | |||
| 118 | + | &i.ID, | |||
| 119 | + | &i.Url, | |||
| 120 | + | &i.Title, | |||
| 121 | + | &i.VisitCount, | |||
| 122 | + | &i.LastVisited, | |||
| 123 | + | &i.CreatedAt, | |||
| 124 | + | ); err != nil { | |||
| 125 | + | return nil, err | |||
| 126 | + | } | |||
| 127 | + | items = append(items, i) | |||
| 128 | + | } | |||
| 129 | + | if err := rows.Close(); err != nil { | |||
| 130 | + | return nil, err | |||
| 131 | + | } | |||
| 132 | + | if err := rows.Err(); err != nil { | |||
| 133 | + | return nil, err | |||
| 134 | + | } | |||
| 135 | + | return items, nil | |||
| 136 | + | } | |||
A internal/db/models.go +26 -0
| @@ -0,0 +1,26 @@ | |||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |
| 2 | + | // versions: | |
| 3 | + | // sqlc v1.30.0 | |
| 4 | + | ||
| 5 | + | package db | |
| 6 | + | ||
| 7 | + | import ( | |
| 8 | + | "database/sql" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | type History struct { | |
| 12 | + | ID int64 `json:"id"` | |
| 13 | + | Url string `json:"url"` | |
| 14 | + | Title sql.NullString `json:"title"` | |
| 15 | + | VisitCount sql.NullInt64 `json:"visit_count"` | |
| 16 | + | LastVisited sql.NullTime `json:"last_visited"` | |
| 17 | + | CreatedAt sql.NullTime `json:"created_at"` | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | type Shortcut struct { | |
| 21 | + | ID int64 `json:"id"` | |
| 22 | + | Shortcut string `json:"shortcut"` | |
| 23 | + | UrlTemplate string `json:"url_template"` | |
| 24 | + | Description sql.NullString `json:"description"` | |
| 25 | + | CreatedAt sql.NullTime `json:"created_at"` | |
| 26 | + | } | |
| @@ -0,0 +1,26 @@ | |||||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |||
| 2 | + | // versions: | |||
| 3 | + | // sqlc v1.30.0 | |||
| 4 | + | ||||
| 5 | + | package db | |||
| 6 | + | ||||
| 7 | + | import ( | |||
| 8 | + | "database/sql" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | type History struct { | |||
| 12 | + | ID int64 `json:"id"` | |||
| 13 | + | Url string `json:"url"` | |||
| 14 | + | Title sql.NullString `json:"title"` | |||
| 15 | + | VisitCount sql.NullInt64 `json:"visit_count"` | |||
| 16 | + | LastVisited sql.NullTime `json:"last_visited"` | |||
| 17 | + | CreatedAt sql.NullTime `json:"created_at"` | |||
| 18 | + | } | |||
| 19 | + | ||||
| 20 | + | type Shortcut struct { | |||
| 21 | + | ID int64 `json:"id"` | |||
| 22 | + | Shortcut string `json:"shortcut"` | |||
| 23 | + | UrlTemplate string `json:"url_template"` | |||
| 24 | + | Description sql.NullString `json:"description"` | |||
| 25 | + | CreatedAt sql.NullTime `json:"created_at"` | |||
| 26 | + | } | |||
A internal/db/querier.go +19 -0
| @@ -0,0 +1,19 @@ | |||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |
| 2 | + | // versions: | |
| 3 | + | // sqlc v1.30.0 | |
| 4 | + | ||
| 5 | + | package db | |
| 6 | + | ||
| 7 | + | import ( | |
| 8 | + | "context" | |
| 9 | + | "database/sql" | |
| 10 | + | ) | |
| 11 | + | ||
| 12 | + | type Querier interface { | |
| 13 | + | AddOrUpdateHistory(ctx context.Context, url string, title sql.NullString) error | |
| 14 | + | GetHistory(ctx context.Context, limit int64) ([]History, error) | |
| 15 | + | GetShortcuts(ctx context.Context) ([]Shortcut, error) | |
| 16 | + | SearchHistory(ctx context.Context, column1 sql.NullString, column2 sql.NullString, limit int64) ([]History, error) | |
| 17 | + | } | |
| 18 | + | ||
| 19 | + | var _ Querier = (*Queries)(nil) | |
| @@ -0,0 +1,19 @@ | |||||
| 1 | + | // Code generated by sqlc. DO NOT EDIT. | |||
| 2 | + | // versions: | |||
| 3 | + | // sqlc v1.30.0 | |||
| 4 | + | ||||
| 5 | + | package db | |||
| 6 | + | ||||
| 7 | + | import ( | |||
| 8 | + | "context" | |||
| 9 | + | "database/sql" | |||
| 10 | + | ) | |||
| 11 | + | ||||
| 12 | + | type Querier interface { | |||
| 13 | + | AddOrUpdateHistory(ctx context.Context, url string, title sql.NullString) error | |||
| 14 | + | GetHistory(ctx context.Context, limit int64) ([]History, error) | |||
| 15 | + | GetShortcuts(ctx context.Context) ([]Shortcut, error) | |||
| 16 | + | SearchHistory(ctx context.Context, column1 sql.NullString, column2 sql.NullString, limit int64) ([]History, error) | |||
| 17 | + | } | |||
| 18 | + | ||||
| 19 | + | var _ Querier = (*Queries)(nil) | |||
A internal/db/queries/history.sql +26 -0
| @@ -0,0 +1,26 @@ | |||
| 1 | + | -- name: GetHistory :many | |
| 2 | + | SELECT id, url, title, visit_count, last_visited, created_at | |
| 3 | + | FROM history | |
| 4 | + | ORDER BY last_visited DESC | |
| 5 | + | LIMIT ?; | |
| 6 | + | ||
| 7 | + | -- name: AddOrUpdateHistory :exec | |
| 8 | + | INSERT INTO history (url, title) | |
| 9 | + | VALUES (?, ?) | |
| 10 | + | ON CONFLICT(url) | |
| 11 | + | DO UPDATE SET | |
| 12 | + | visit_count = visit_count + 1, | |
| 13 | + | last_visited = CURRENT_TIMESTAMP, | |
| 14 | + | title = EXCLUDED.title; | |
| 15 | + | ||
| 16 | + | -- name: SearchHistory :many | |
| 17 | + | SELECT id, url, title, visit_count, last_visited, created_at | |
| 18 | + | FROM history | |
| 19 | + | WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%' | |
| 20 | + | ORDER BY visit_count DESC, last_visited DESC | |
| 21 | + | LIMIT ?; | |
| 22 | + | ||
| 23 | + | -- name: GetShortcuts :many | |
| 24 | + | SELECT id, shortcut, url_template, description, created_at | |
| 25 | + | FROM shortcuts | |
| 26 | + | ORDER BY shortcut;⏎̸ | |
| @@ -0,0 +1,26 @@ | |||||
| 1 | + | -- name: GetHistory :many | |||
| 2 | + | SELECT id, url, title, visit_count, last_visited, created_at | |||
| 3 | + | FROM history | |||
| 4 | + | ORDER BY last_visited DESC | |||
| 5 | + | LIMIT ?; | |||
| 6 | + | ||||
| 7 | + | -- name: AddOrUpdateHistory :exec | |||
| 8 | + | INSERT INTO history (url, title) | |||
| 9 | + | VALUES (?, ?) | |||
| 10 | + | ON CONFLICT(url) | |||
| 11 | + | DO UPDATE SET | |||
| 12 | + | visit_count = visit_count + 1, | |||
| 13 | + | last_visited = CURRENT_TIMESTAMP, | |||
| 14 | + | title = EXCLUDED.title; | |||
| 15 | + | ||||
| 16 | + | -- name: SearchHistory :many | |||
| 17 | + | SELECT id, url, title, visit_count, last_visited, created_at | |||
| 18 | + | FROM history | |||
| 19 | + | WHERE url LIKE '%' || ? || '%' OR title LIKE '%' || ? || '%' | |||
| 20 | + | ORDER BY visit_count DESC, last_visited DESC | |||
| 21 | + | LIMIT ?; | |||
| 22 | + | ||||
| 23 | + | -- name: GetShortcuts :many | |||
| 24 | + | SELECT id, shortcut, url_template, description, created_at | |||
| 25 | + | FROM shortcuts | |||
| 26 | + | ORDER BY shortcut;⏎̸ | |||
M memory/constitution.md +77 -35
| @@ -1,50 +1,92 @@ | |||
| 1 | - | # [PROJECT_NAME] Constitution | |
| 2 | - | <!-- Example: Spec Constitution, TaskFlow Constitution, etc. --> | |
| 1 | + | # Dumb Browser Constitution | |
| 3 | 2 | ||
| 4 | 3 | ## Core Principles | |
| 5 | 4 | ||
| 6 | - | ### [PRINCIPLE_1_NAME] | |
| 7 | - | <!-- Example: I. Library-First --> | |
| 8 | - | [PRINCIPLE_1_DESCRIPTION] | |
| 9 | - | <!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries --> | |
| 5 | + | ### I. Speed First (NON-NEGOTIABLE) | |
| 6 | + | - Fast startup time is paramount - no feature worth compromising speed | |
| 7 | + | - Single binary with embedded assets - no external dependencies at runtime | |
| 8 | + | - WebKit2GTK for rendering - full compliance without reinventing wheels | |
| 9 | + | - Minimal UI overhead - focus on web content, not chrome | |
| 10 | 10 | ||
| 11 | - | ### [PRINCIPLE_2_NAME] | |
| 12 | - | <!-- Example: II. CLI Interface --> | |
| 13 | - | [PRINCIPLE_2_DESCRIPTION] | |
| 14 | - | <!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args → stdout, errors → stderr; Support JSON + human-readable formats --> | |
| 11 | + | ### II. Universal Launcher Compatibility | |
| 12 | + | - Support any dmenu-compatible launcher (fuzzel, rofi, tofi, wofi, bemenu) | |
| 13 | + | - Standard stdin/stdout protocol - no launcher-specific integrations | |
| 14 | + | - Clean text-based format for history/suggestions | |
| 15 | + | - Pipeline-friendly: `dumb-browser --dmenu | launcher | dumb-browser --dmenu` | |
| 15 | 16 | ||
| 16 | - | ### [PRINCIPLE_3_NAME] | |
| 17 | - | <!-- Example: III. Test-First (NON-NEGOTIABLE) --> | |
| 18 | - | [PRINCIPLE_3_DESCRIPTION] | |
| 19 | - | <!-- Example: TDD mandatory: Tests written → User approved → Tests fail → Then implement; Red-Green-Refactor cycle strictly enforced --> | |
| 17 | + | ### III. Smart URL Handling | |
| 18 | + | - Direct URL detection: `reddit.com` → navigate directly | |
| 19 | + | - Search shortcuts: `g: golang tutorial` → Google search | |
| 20 | + | - History-first search: `reddit` → check history before web search | |
| 21 | + | - No ambiguity - clear rules for input interpretation | |
| 20 | 22 | ||
| 21 | - | ### [PRINCIPLE_4_NAME] | |
| 22 | - | <!-- Example: IV. Integration Testing --> | |
| 23 | - | [PRINCIPLE_4_DESCRIPTION] | |
| 24 | - | <!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas --> | |
| 23 | + | ### IV. Privacy-Conscious History | |
| 24 | + | - Local SQLite database only - no cloud sync | |
| 25 | + | - Configurable retention periods and cleanup | |
| 26 | + | - Visit counting for intelligent suggestions | |
| 27 | + | - User controls data - easy to clear/export | |
| 25 | 28 | ||
| 26 | - | ### [PRINCIPLE_5_NAME] | |
| 27 | - | <!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity --> | |
| 28 | - | [PRINCIPLE_5_DESCRIPTION] | |
| 29 | - | <!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles --> | |
| 29 | + | ### V. Wayland Native | |
| 30 | + | - Built for modern Linux desktop - sway, hyprland, etc. | |
| 31 | + | - WebKit2GTK provides native Wayland integration | |
| 32 | + | - Single instance handling for launcher integration | |
| 33 | + | - Minimal resource usage - no background services | |
| 30 | 34 | ||
| 31 | - | ## [SECTION_2_NAME] | |
| 32 | - | <!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. --> | |
| 35 | + | ## Technical Standards | |
| 33 | 36 | ||
| 34 | - | [SECTION_2_CONTENT] | |
| 35 | - | <!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. --> | |
| 37 | + | ### Stack Requirements | |
| 38 | + | - **Backend**: Go + Wails([v3-alpha](https://github.com/wailsapp/wails/tree/v3.0.0-alpha.28)) + WebKit2GTK + SQLite | |
| 39 | + | - **CLI**: Cobra + Viper for configuration | |
| 40 | + | - **Database**: SQLC for type-safe SQL generation | |
| 41 | + | - **Validation**: Input sanitization libraries ([go-playground/validator](https://github.com/go-playground/validator)) | |
| 42 | + | - **Build**: Single static binary with embedded frontend | |
| 43 | + | - **Dependencies**: WebKit2GTK + GTK3 only (system packages) | |
| 36 | 44 | ||
| 37 | - | ## [SECTION_3_NAME] | |
| 38 | - | <!-- Example: Development Workflow, Review Process, Quality Gates, etc. --> | |
| 45 | + | ### Performance Targets | |
| 46 | + | - Startup time: < 500ms from cold start | |
| 47 | + | - Memory usage: < 100MB baseline + WebKit overhead | |
| 48 | + | - History search: < 50ms for 1000+ entries | |
| 49 | + | - Single instance lock: < 10ms response time | |
| 39 | 50 | ||
| 40 | - | [SECTION_3_CONTENT] | |
| 41 | - | <!-- Example: Code review requirements, testing gates, deployment approval process, etc. --> | |
| 51 | + | ### Quality Gates | |
| 52 | + | - All database queries must use SQLC generated code | |
| 53 | + | - All user input must be validated and sanitized | |
| 54 | + | - Error handling: proper Go error chains, no panics in user paths | |
| 55 | + | - Logging: structured logging for debugging, minimal in production (Slog for logging in text mode) | |
| 56 | + | ||
| 57 | + | ## Development Workflow | |
| 58 | + | ||
| 59 | + | ### Implementation Order | |
| 60 | + | 1. Core CLI structure (Cobra + Viper) | |
| 61 | + | 2. Database schema + SQLC integration | |
| 62 | + | 3. URL parser + search engine logic with fuzzy finder algorithm | |
| 63 | + | 4. History management (CRUD operations) | |
| 64 | + | 5. Wails browser integration | |
| 65 | + | 6. Dmenu compatibility layer | |
| 66 | + | 7. Configuration system | |
| 67 | + | ||
| 68 | + | ### Testing Requirements | |
| 69 | + | - Unit tests for URL parsing logic | |
| 70 | + | - Integration tests for database operations | |
| 71 | + | - Manual testing with fuzzel integration | |
| 72 | + | - Cross-launcher compatibility verification | |
| 73 | + | ||
| 74 | + | ## Constraints | |
| 75 | + | ||
| 76 | + | ### Simplicity Mandate | |
| 77 | + | - KISS principle - no over-engineering | |
| 78 | + | - Clean Code philosophy throughout | |
| 79 | + | - Single responsibility per module | |
| 80 | + | - Minimal configuration surface | |
| 81 | + | ||
| 82 | + | ### Security Requirements | |
| 83 | + | - No credential storage or session management | |
| 84 | + | - Input sanitization for all user data | |
| 85 | + | - SQL injection prevention via SQLC | |
| 86 | + | - No network requests except web browsing | |
| 42 | 87 | ||
| 43 | 88 | ## Governance | |
| 44 | - | <!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan --> | |
| 45 | 89 | ||
| 46 | - | [GOVERNANCE_RULES] | |
| 47 | - | <!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance --> | |
| 90 | + | This constitution defines the project's core identity and technical direction. All implementation decisions must align with these principles, prioritizing speed and simplicity above feature richness. | |
| 48 | 91 | ||
| 49 | - | **Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE] | |
| 50 | - | <!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->⏎̸ | |
| 92 | + | **Version**: 1.0.0 | **Ratified**: 2025-01-09 | **Last Amended**: 2025-01-09⏎̸ | |
| @@ -1,50 +1,92 @@ | |||||
| 1 | - | # [PROJECT_NAME] Constitution | 1 | + | # Dumb Browser Constitution |
| 2 | - | <!-- Example: Spec Constitution, TaskFlow Constitution, etc. --> | |||
| 3 | 2 | ||||
| 4 | ## Core Principles | 3 | ## Core Principles | ||
| 5 | 4 | ||||
| 6 | - | ### [PRINCIPLE_1_NAME] | 5 | + | ### I. Speed First (NON-NEGOTIABLE) |
| 7 | - | <!-- Example: I. Library-First --> | 6 | + | - Fast startup time is paramount - no feature worth compromising speed |
| 8 | - | [PRINCIPLE_1_DESCRIPTION] | 7 | + | - Single binary with embedded assets - no external dependencies at runtime |
| 9 | - | <!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries --> | 8 | + | - WebKit2GTK for rendering - full compliance without reinventing wheels |
| 9 | + | - Minimal UI overhead - focus on web content, not chrome | |||
| 10 | 10 | ||||
| 11 | - | ### [PRINCIPLE_2_NAME] | 11 | + | ### II. Universal Launcher Compatibility |
| 12 | - | <!-- Example: II. CLI Interface --> | 12 | + | - Support any dmenu-compatible launcher (fuzzel, rofi, tofi, wofi, bemenu) |
| 13 | - | [PRINCIPLE_2_DESCRIPTION] | 13 | + | - Standard stdin/stdout protocol - no launcher-specific integrations |
| 14 | - | <!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args → stdout, errors → stderr; Support JSON + human-readable formats --> | 14 | + | - Clean text-based format for history/suggestions |
| 15 | + | - Pipeline-friendly: `dumb-browser --dmenu | launcher | dumb-browser --dmenu` | |||
| 15 | 16 | ||||
| 16 | - | ### [PRINCIPLE_3_NAME] | 17 | + | ### III. Smart URL Handling |
| 17 | - | <!-- Example: III. Test-First (NON-NEGOTIABLE) --> | 18 | + | - Direct URL detection: `reddit.com` → navigate directly |
| 18 | - | [PRINCIPLE_3_DESCRIPTION] | 19 | + | - Search shortcuts: `g: golang tutorial` → Google search |
| 19 | - | <!-- Example: TDD mandatory: Tests written → User approved → Tests fail → Then implement; Red-Green-Refactor cycle strictly enforced --> | 20 | + | - History-first search: `reddit` → check history before web search |
| 21 | + | - No ambiguity - clear rules for input interpretation | |||
| 20 | 22 | ||||
| 21 | - | ### [PRINCIPLE_4_NAME] | 23 | + | ### IV. Privacy-Conscious History |
| 22 | - | <!-- Example: IV. Integration Testing --> | 24 | + | - Local SQLite database only - no cloud sync |
| 23 | - | [PRINCIPLE_4_DESCRIPTION] | 25 | + | - Configurable retention periods and cleanup |
| 24 | - | <!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas --> | 26 | + | - Visit counting for intelligent suggestions |
| 27 | + | - User controls data - easy to clear/export | |||
| 25 | 28 | ||||
| 26 | - | ### [PRINCIPLE_5_NAME] | 29 | + | ### V. Wayland Native |
| 27 | - | <!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity --> | 30 | + | - Built for modern Linux desktop - sway, hyprland, etc. |
| 28 | - | [PRINCIPLE_5_DESCRIPTION] | 31 | + | - WebKit2GTK provides native Wayland integration |
| 29 | - | <!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles --> | 32 | + | - Single instance handling for launcher integration |
| 33 | + | - Minimal resource usage - no background services | |||
| 30 | 34 | ||||
| 31 | - | ## [SECTION_2_NAME] | 35 | + | ## Technical Standards |
| 32 | - | <!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. --> | |||
| 33 | 36 | ||||
| 34 | - | [SECTION_2_CONTENT] | 37 | + | ### Stack Requirements |
| 35 | - | <!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. --> | 38 | + | - **Backend**: Go + Wails([v3-alpha](https://github.com/wailsapp/wails/tree/v3.0.0-alpha.28)) + WebKit2GTK + SQLite |
| 39 | + | - **CLI**: Cobra + Viper for configuration | |||
| 40 | + | - **Database**: SQLC for type-safe SQL generation | |||
| 41 | + | - **Validation**: Input sanitization libraries ([go-playground/validator](https://github.com/go-playground/validator)) | |||
| 42 | + | - **Build**: Single static binary with embedded frontend | |||
| 43 | + | - **Dependencies**: WebKit2GTK + GTK3 only (system packages) | |||
| 36 | 44 | ||||
| 37 | - | ## [SECTION_3_NAME] | 45 | + | ### Performance Targets |
| 38 | - | <!-- Example: Development Workflow, Review Process, Quality Gates, etc. --> | 46 | + | - Startup time: < 500ms from cold start |
| 47 | + | - Memory usage: < 100MB baseline + WebKit overhead | |||
| 48 | + | - History search: < 50ms for 1000+ entries | |||
| 49 | + | - Single instance lock: < 10ms response time | |||
| 39 | 50 | ||||
| 40 | - | [SECTION_3_CONTENT] | 51 | + | ### Quality Gates |
| 41 | - | <!-- Example: Code review requirements, testing gates, deployment approval process, etc. --> | 52 | + | - All database queries must use SQLC generated code |
| 53 | + | - All user input must be validated and sanitized | |||
| 54 | + | - Error handling: proper Go error chains, no panics in user paths | |||
| 55 | + | - Logging: structured logging for debugging, minimal in production (Slog for logging in text mode) | |||
| 56 | + | ||||
| 57 | + | ## Development Workflow | |||
| 58 | + | ||||
| 59 | + | ### Implementation Order | |||
| 60 | + | 1. Core CLI structure (Cobra + Viper) | |||
| 61 | + | 2. Database schema + SQLC integration | |||
| 62 | + | 3. URL parser + search engine logic with fuzzy finder algorithm | |||
| 63 | + | 4. History management (CRUD operations) | |||
| 64 | + | 5. Wails browser integration | |||
| 65 | + | 6. Dmenu compatibility layer | |||
| 66 | + | 7. Configuration system | |||
| 67 | + | ||||
| 68 | + | ### Testing Requirements | |||
| 69 | + | - Unit tests for URL parsing logic | |||
| 70 | + | - Integration tests for database operations | |||
| 71 | + | - Manual testing with fuzzel integration | |||
| 72 | + | - Cross-launcher compatibility verification | |||
| 73 | + | ||||
| 74 | + | ## Constraints | |||
| 75 | + | ||||
| 76 | + | ### Simplicity Mandate | |||
| 77 | + | - KISS principle - no over-engineering | |||
| 78 | + | - Clean Code philosophy throughout | |||
| 79 | + | - Single responsibility per module | |||
| 80 | + | - Minimal configuration surface | |||
| 81 | + | ||||
| 82 | + | ### Security Requirements | |||
| 83 | + | - No credential storage or session management | |||
| 84 | + | - Input sanitization for all user data | |||
| 85 | + | - SQL injection prevention via SQLC | |||
| 86 | + | - No network requests except web browsing | |||
| 42 | 87 | ||||
| 43 | ## Governance | 88 | ## Governance | ||
| 44 | - | <!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan --> | |||
| 45 | 89 | ||||
| 46 | - | [GOVERNANCE_RULES] | 90 | + | This constitution defines the project's core identity and technical direction. All implementation decisions must align with these principles, prioritizing speed and simplicity above feature richness. |
| 47 | - | <!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance --> | |||
| 48 | 91 | ||||
| 49 | - | **Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE] | 92 | + | **Version**: 1.0.0 | **Ratified**: 2025-01-09 | **Last Amended**: 2025-01-09⏎̸ |
| 50 | - | <!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->⏎̸ | |||
A migrations/001_initial.sql +29 -0
| @@ -0,0 +1,29 @@ | |||
| 1 | + | -- Initial database schema for dumb-browser | |
| 2 | + | -- History tracking for visited URLs | |
| 3 | + | ||
| 4 | + | CREATE TABLE IF NOT EXISTS history ( | |
| 5 | + | id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| 6 | + | url TEXT NOT NULL UNIQUE, | |
| 7 | + | title TEXT, | |
| 8 | + | visit_count INTEGER DEFAULT 1, | |
| 9 | + | last_visited DATETIME DEFAULT CURRENT_TIMESTAMP, | |
| 10 | + | created_at DATETIME DEFAULT CURRENT_TIMESTAMP | |
| 11 | + | ); | |
| 12 | + | ||
| 13 | + | CREATE INDEX idx_history_url ON history(url); | |
| 14 | + | CREATE INDEX idx_history_last_visited ON history(last_visited); | |
| 15 | + | ||
| 16 | + | -- URL shortcuts configuration | |
| 17 | + | CREATE TABLE IF NOT EXISTS shortcuts ( | |
| 18 | + | id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| 19 | + | shortcut TEXT NOT NULL UNIQUE, | |
| 20 | + | url_template TEXT NOT NULL, | |
| 21 | + | description TEXT, | |
| 22 | + | created_at DATETIME DEFAULT CURRENT_TIMESTAMP | |
| 23 | + | ); | |
| 24 | + | ||
| 25 | + | INSERT OR IGNORE INTO shortcuts (shortcut, url_template, description) VALUES | |
| 26 | + | ('g', 'https://www.google.com/search?q=%s', 'Google search'), | |
| 27 | + | ('gh', 'https://github.com/search?q=%s', 'GitHub search'), | |
| 28 | + | ('yt', 'https://www.youtube.com/results?search_query=%s', 'YouTube search'), | |
| 29 | + | ('w', 'https://en.wikipedia.org/wiki/%s', 'Wikipedia search');⏎̸ | |
| @@ -0,0 +1,29 @@ | |||||
| 1 | + | -- Initial database schema for dumb-browser | |||
| 2 | + | -- History tracking for visited URLs | |||
| 3 | + | ||||
| 4 | + | CREATE TABLE IF NOT EXISTS history ( | |||
| 5 | + | id INTEGER PRIMARY KEY AUTOINCREMENT, | |||
| 6 | + | url TEXT NOT NULL UNIQUE, | |||
| 7 | + | title TEXT, | |||
| 8 | + | visit_count INTEGER DEFAULT 1, | |||
| 9 | + | last_visited DATETIME DEFAULT CURRENT_TIMESTAMP, | |||
| 10 | + | created_at DATETIME DEFAULT CURRENT_TIMESTAMP | |||
| 11 | + | ); | |||
| 12 | + | ||||
| 13 | + | CREATE INDEX idx_history_url ON history(url); | |||
| 14 | + | CREATE INDEX idx_history_last_visited ON history(last_visited); | |||
| 15 | + | ||||
| 16 | + | -- URL shortcuts configuration | |||
| 17 | + | CREATE TABLE IF NOT EXISTS shortcuts ( | |||
| 18 | + | id INTEGER PRIMARY KEY AUTOINCREMENT, | |||
| 19 | + | shortcut TEXT NOT NULL UNIQUE, | |||
| 20 | + | url_template TEXT NOT NULL, | |||
| 21 | + | description TEXT, | |||
| 22 | + | created_at DATETIME DEFAULT CURRENT_TIMESTAMP | |||
| 23 | + | ); | |||
| 24 | + | ||||
| 25 | + | INSERT OR IGNORE INTO shortcuts (shortcut, url_template, description) VALUES | |||
| 26 | + | ('g', 'https://www.google.com/search?q=%s', 'Google search'), | |||
| 27 | + | ('gh', 'https://github.com/search?q=%s', 'GitHub search'), | |||
| 28 | + | ('yt', 'https://www.youtube.com/results?search_query=%s', 'YouTube search'), | |||
| 29 | + | ('w', 'https://en.wikipedia.org/wiki/%s', 'Wikipedia search');⏎̸ | |||
M scripts/check-task-prerequisites.sh +0 -0 mode 100644 → 100755
mode 100644 → 100755
M scripts/common.sh +0 -0 mode 100644 → 100755
mode 100644 → 100755
M scripts/create-new-feature.sh +0 -0 mode 100644 → 100755
mode 100644 → 100755
M scripts/get-feature-paths.sh +0 -0 mode 100644 → 100755
mode 100644 → 100755
M scripts/setup-plan.sh +0 -0 mode 100644 → 100755
mode 100644 → 100755
M scripts/update-agent-context.sh +0 -0 mode 100644 → 100755
mode 100644 → 100755
A specs/001-init-project/contracts/cli-commands.md +245 -0
| @@ -0,0 +1,245 @@ | |||
| 1 | + | # CLI Commands Contract: Project Initialization | |
| 2 | + | ||
| 3 | + | **Date**: 2025-01-09 | |
| 4 | + | **Context**: Command-line interface specification for project initialization | |
| 5 | + | ||
| 6 | + | ## Root Command | |
| 7 | + | ||
| 8 | + | ### `dumb-browser init` | |
| 9 | + | **Purpose**: Initialize the project with all dependencies | |
| 10 | + | ||
| 11 | + | **Syntax**: | |
| 12 | + | ```bash | |
| 13 | + | dumb-browser init [OPTIONS] | |
| 14 | + | ``` | |
| 15 | + | ||
| 16 | + | **Options**: | |
| 17 | + | - `--dry-run`: Show what would be done without executing | |
| 18 | + | - `--force`: Overwrite existing files if present | |
| 19 | + | - `--verbose, -v`: Show detailed progress information | |
| 20 | + | - `--go-version`: Specify Go version requirement (default: auto-detect) | |
| 21 | + | ||
| 22 | + | **Examples**: | |
| 23 | + | ```bash | |
| 24 | + | # Basic initialization | |
| 25 | + | dumb-browser init | |
| 26 | + | ||
| 27 | + | # Preview mode | |
| 28 | + | dumb-browser init --dry-run | |
| 29 | + | ||
| 30 | + | # Force reinitialize existing project | |
| 31 | + | dumb-browser init --force --verbose | |
| 32 | + | ||
| 33 | + | # Specify Go version | |
| 34 | + | dumb-browser init --go-version=1.21 | |
| 35 | + | ``` | |
| 36 | + | ||
| 37 | + | **Exit Codes**: | |
| 38 | + | - `0`: Success | |
| 39 | + | - `1`: General error (invalid arguments, etc.) | |
| 40 | + | - `2`: Dependency installation failed | |
| 41 | + | - `3`: Tool installation failed | |
| 42 | + | - `4`: Project already initialized (without --force) | |
| 43 | + | ||
| 44 | + | **Output Format**: | |
| 45 | + | ``` | |
| 46 | + | ✓ Initializing Go module: dumb-browser | |
| 47 | + | ✓ Installing CLI dependencies: cobra, viper | |
| 48 | + | ✓ Installing database dependencies: sqlite3, sqlc | |
| 49 | + | ✓ Installing validation: go-playground/validator | |
| 50 | + | ✓ Installing testing: testify | |
| 51 | + | ✓ Installing Wails v3-alpha... | |
| 52 | + | ✓ Creating project structure... | |
| 53 | + | ✓ Generating configuration files... | |
| 54 | + | ✓ Verifying installation... | |
| 55 | + | ||
| 56 | + | Project initialized successfully! | |
| 57 | + | ||
| 58 | + | Next steps: | |
| 59 | + | 1. Review generated configs/ | |
| 60 | + | 2. Run: go build ./cmd/dumb-browser | |
| 61 | + | 3. Start development: dumb-browser --help | |
| 62 | + | ``` | |
| 63 | + | ||
| 64 | + | ## Subcommands | |
| 65 | + | ||
| 66 | + | ### `dumb-browser init deps` | |
| 67 | + | **Purpose**: Install only dependencies without project structure | |
| 68 | + | ||
| 69 | + | **Syntax**: | |
| 70 | + | ```bash | |
| 71 | + | dumb-browser init deps [OPTIONS] | |
| 72 | + | ``` | |
| 73 | + | ||
| 74 | + | **Options**: | |
| 75 | + | - `--only`: Install specific dependency category (cli|db|validation|testing|wails) | |
| 76 | + | - `--skip`: Skip specific dependency category | |
| 77 | + | - `--latest`: Use @latest for all dependencies (default) | |
| 78 | + | - `--check`: Verify dependencies without installing | |
| 79 | + | ||
| 80 | + | **Examples**: | |
| 81 | + | ```bash | |
| 82 | + | # Install only CLI dependencies | |
| 83 | + | dumb-browser init deps --only=cli | |
| 84 | + | ||
| 85 | + | # Install everything except Wails | |
| 86 | + | dumb-browser init deps --skip=wails | |
| 87 | + | ||
| 88 | + | # Check current dependency status | |
| 89 | + | dumb-browser init deps --check | |
| 90 | + | ``` | |
| 91 | + | ||
| 92 | + | ### `dumb-browser init structure` | |
| 93 | + | **Purpose**: Create project directory structure only | |
| 94 | + | ||
| 95 | + | **Syntax**: | |
| 96 | + | ```bash | |
| 97 | + | dumb-browser init structure [OPTIONS] | |
| 98 | + | ``` | |
| 99 | + | ||
| 100 | + | **Options**: | |
| 101 | + | - `--template`: Use specific structure template (default|minimal) | |
| 102 | + | - `--preview`: Show directory tree without creating | |
| 103 | + | ||
| 104 | + | **Examples**: | |
| 105 | + | ```bash | |
| 106 | + | # Create full project structure | |
| 107 | + | dumb-browser init structure | |
| 108 | + | ||
| 109 | + | # Preview directory layout | |
| 110 | + | dumb-browser init structure --preview | |
| 111 | + | ||
| 112 | + | # Minimal structure (no example files) | |
| 113 | + | dumb-browser init structure --template=minimal | |
| 114 | + | ``` | |
| 115 | + | ||
| 116 | + | ### `dumb-browser init config` | |
| 117 | + | **Purpose**: Generate configuration files only | |
| 118 | + | ||
| 119 | + | **Syntax**: | |
| 120 | + | ```bash | |
| 121 | + | dumb-browser init config [OPTIONS] | |
| 122 | + | ``` | |
| 123 | + | ||
| 124 | + | **Options**: | |
| 125 | + | - `--type`: Generate specific config (sqlc|wails|all) | |
| 126 | + | - `--overwrite`: Replace existing config files | |
| 127 | + | ||
| 128 | + | **Examples**: | |
| 129 | + | ```bash | |
| 130 | + | # Generate all config files | |
| 131 | + | dumb-browser init config | |
| 132 | + | ||
| 133 | + | # Only SQLC configuration | |
| 134 | + | dumb-browser init config --type=sqlc | |
| 135 | + | ||
| 136 | + | # Replace existing configs | |
| 137 | + | dumb-browser init config --overwrite | |
| 138 | + | ``` | |
| 139 | + | ||
| 140 | + | ## Status and Information Commands | |
| 141 | + | ||
| 142 | + | ### `dumb-browser init status` | |
| 143 | + | **Purpose**: Show initialization status | |
| 144 | + | ||
| 145 | + | **Syntax**: | |
| 146 | + | ```bash | |
| 147 | + | dumb-browser init status [OPTIONS] | |
| 148 | + | ``` | |
| 149 | + | ||
| 150 | + | **Options**: | |
| 151 | + | - `--format`: Output format (text|json|yaml) | |
| 152 | + | - `--detailed`: Show dependency versions and paths | |
| 153 | + | ||
| 154 | + | **Output** (text format): | |
| 155 | + | ``` | |
| 156 | + | Project Status: ✓ Initialized | |
| 157 | + | ||
| 158 | + | Dependencies: | |
| 159 | + | ✓ CLI (cobra v1.8.0, viper v1.18.2) | |
| 160 | + | ✓ Database (sqlite3 v1.14.19, sqlc v1.25.0) | |
| 161 | + | ✓ Validation (validator v10.16.0) | |
| 162 | + | ✓ Testing (testify v1.8.4) | |
| 163 | + | ✗ Wails (not installed) | |
| 164 | + | ||
| 165 | + | Structure: | |
| 166 | + | ✓ cmd/, internal/, migrations/, configs/ | |
| 167 | + | ✗ Missing: tests/integration/ | |
| 168 | + | ||
| 169 | + | Build Status: ✓ Ready (go build succeeds) | |
| 170 | + | ``` | |
| 171 | + | ||
| 172 | + | ### `dumb-browser init verify` | |
| 173 | + | **Purpose**: Verify complete installation | |
| 174 | + | ||
| 175 | + | **Syntax**: | |
| 176 | + | ```bash | |
| 177 | + | dumb-browser init verify [OPTIONS] | |
| 178 | + | ``` | |
| 179 | + | ||
| 180 | + | **Options**: | |
| 181 | + | - `--fix`: Attempt to fix detected issues | |
| 182 | + | - `--report`: Generate detailed verification report | |
| 183 | + | ||
| 184 | + | **Exit Codes**: | |
| 185 | + | - `0`: All verifications passed | |
| 186 | + | - `1`: Some issues detected but not critical | |
| 187 | + | - `2`: Critical issues prevent development | |
| 188 | + | ||
| 189 | + | ## Error Handling | |
| 190 | + | ||
| 191 | + | ### Common Error Scenarios | |
| 192 | + | ||
| 193 | + | **Dependency Installation Failures**: | |
| 194 | + | ```bash | |
| 195 | + | $ dumb-browser init | |
| 196 | + | ✗ Installing database dependencies: sqlite3 | |
| 197 | + | Error: CGO_ENABLED=1 required for sqlite3 | |
| 198 | + | Suggestion: Run 'export CGO_ENABLED=1' and try again | |
| 199 | + | Exit Code: 2 | |
| 200 | + | ``` | |
| 201 | + | ||
| 202 | + | **System Dependency Missing**: | |
| 203 | + | ```bash | |
| 204 | + | $ dumb-browser init | |
| 205 | + | ✗ Installing Wails v3-alpha | |
| 206 | + | Error: libwebkit2gtk-4.0-dev not found | |
| 207 | + | Suggestion: Install with 'sudo apt install libwebkit2gtk-4.0-dev' | |
| 208 | + | Exit Code: 3 | |
| 209 | + | ``` | |
| 210 | + | ||
| 211 | + | **Project Already Exists**: | |
| 212 | + | ```bash | |
| 213 | + | $ dumb-browser init | |
| 214 | + | ✗ Project already initialized | |
| 215 | + | Use --force to reinitialize or run 'dumb-browser init status' | |
| 216 | + | Exit Code: 4 | |
| 217 | + | ``` | |
| 218 | + | ||
| 219 | + | ## Integration with Other Systems | |
| 220 | + | ||
| 221 | + | ### CI/CD Integration | |
| 222 | + | Commands designed for automated environments: | |
| 223 | + | ```bash | |
| 224 | + | # Non-interactive initialization | |
| 225 | + | dumb-browser init --verbose > init.log 2>&1 | |
| 226 | + | ||
| 227 | + | # Verification in CI | |
| 228 | + | dumb-browser init verify --report=ci-report.json | |
| 229 | + | ``` | |
| 230 | + | ||
| 231 | + | ### Development Workflow Integration | |
| 232 | + | ```bash | |
| 233 | + | # Quick setup for new contributors | |
| 234 | + | git clone <repo> && cd <repo> | |
| 235 | + | dumb-browser init | |
| 236 | + | go test ./... | |
| 237 | + | ``` | |
| 238 | + | ||
| 239 | + | ### IDE Integration | |
| 240 | + | Status command provides machine-readable output: | |
| 241 | + | ```bash | |
| 242 | + | dumb-browser init status --format=json | jq '.dependencies.wails.status' | |
| 243 | + | ``` | |
| 244 | + | ||
| 245 | + | This CLI contract supports the initialization phase while providing flexibility for different development scenarios and debugging needs.⏎̸ | |
| @@ -0,0 +1,245 @@ | |||||
| 1 | + | # CLI Commands Contract: Project Initialization | |||
| 2 | + | ||||
| 3 | + | **Date**: 2025-01-09 | |||
| 4 | + | **Context**: Command-line interface specification for project initialization | |||
| 5 | + | ||||
| 6 | + | ## Root Command | |||
| 7 | + | ||||
| 8 | + | ### `dumb-browser init` | |||
| 9 | + | **Purpose**: Initialize the project with all dependencies | |||
| 10 | + | ||||
| 11 | + | **Syntax**: | |||
| 12 | + | ```bash | |||
| 13 | + | dumb-browser init [OPTIONS] | |||
| 14 | + | ``` | |||
| 15 | + | ||||
| 16 | + | **Options**: | |||
| 17 | + | - `--dry-run`: Show what would be done without executing | |||
| 18 | + | - `--force`: Overwrite existing files if present | |||
| 19 | + | - `--verbose, -v`: Show detailed progress information | |||
| 20 | + | - `--go-version`: Specify Go version requirement (default: auto-detect) | |||
| 21 | + | ||||
| 22 | + | **Examples**: | |||
| 23 | + | ```bash | |||
| 24 | + | # Basic initialization | |||
| 25 | + | dumb-browser init | |||
| 26 | + | ||||
| 27 | + | # Preview mode | |||
| 28 | + | dumb-browser init --dry-run | |||
| 29 | + | ||||
| 30 | + | # Force reinitialize existing project | |||
| 31 | + | dumb-browser init --force --verbose | |||
| 32 | + | ||||
| 33 | + | # Specify Go version | |||
| 34 | + | dumb-browser init --go-version=1.21 | |||
| 35 | + | ``` | |||
| 36 | + | ||||
| 37 | + | **Exit Codes**: | |||
| 38 | + | - `0`: Success | |||
| 39 | + | - `1`: General error (invalid arguments, etc.) | |||
| 40 | + | - `2`: Dependency installation failed | |||
| 41 | + | - `3`: Tool installation failed | |||
| 42 | + | - `4`: Project already initialized (without --force) | |||
| 43 | + | ||||
| 44 | + | **Output Format**: | |||
| 45 | + | ``` | |||
| 46 | + | ✓ Initializing Go module: dumb-browser | |||
| 47 | + | ✓ Installing CLI dependencies: cobra, viper | |||
| 48 | + | ✓ Installing database dependencies: sqlite3, sqlc | |||
| 49 | + | ✓ Installing validation: go-playground/validator | |||
| 50 | + | ✓ Installing testing: testify | |||
| 51 | + | ✓ Installing Wails v3-alpha... | |||
| 52 | + | ✓ Creating project structure... | |||
| 53 | + | ✓ Generating configuration files... | |||
| 54 | + | ✓ Verifying installation... | |||
| 55 | + | ||||
| 56 | + | Project initialized successfully! | |||
| 57 | + | ||||
| 58 | + | Next steps: | |||
| 59 | + | 1. Review generated configs/ | |||
| 60 | + | 2. Run: go build ./cmd/dumb-browser | |||
| 61 | + | 3. Start development: dumb-browser --help | |||
| 62 | + | ``` | |||
| 63 | + | ||||
| 64 | + | ## Subcommands | |||
| 65 | + | ||||
| 66 | + | ### `dumb-browser init deps` | |||
| 67 | + | **Purpose**: Install only dependencies without project structure | |||
| 68 | + | ||||
| 69 | + | **Syntax**: | |||
| 70 | + | ```bash | |||
| 71 | + | dumb-browser init deps [OPTIONS] | |||
| 72 | + | ``` | |||
| 73 | + | ||||
| 74 | + | **Options**: | |||
| 75 | + | - `--only`: Install specific dependency category (cli|db|validation|testing|wails) | |||
| 76 | + | - `--skip`: Skip specific dependency category | |||
| 77 | + | - `--latest`: Use @latest for all dependencies (default) | |||
| 78 | + | - `--check`: Verify dependencies without installing | |||
| 79 | + | ||||
| 80 | + | **Examples**: | |||
| 81 | + | ```bash | |||
| 82 | + | # Install only CLI dependencies | |||
| 83 | + | dumb-browser init deps --only=cli | |||
| 84 | + | ||||
| 85 | + | # Install everything except Wails | |||
| 86 | + | dumb-browser init deps --skip=wails | |||
| 87 | + | ||||
| 88 | + | # Check current dependency status | |||
| 89 | + | dumb-browser init deps --check | |||
| 90 | + | ``` | |||
| 91 | + | ||||
| 92 | + | ### `dumb-browser init structure` | |||
| 93 | + | **Purpose**: Create project directory structure only | |||
| 94 | + | ||||
| 95 | + | **Syntax**: | |||
| 96 | + | ```bash | |||
| 97 | + | dumb-browser init structure [OPTIONS] | |||
| 98 | + | ``` | |||
| 99 | + | ||||
| 100 | + | **Options**: | |||
| 101 | + | - `--template`: Use specific structure template (default|minimal) | |||
| 102 | + | - `--preview`: Show directory tree without creating | |||
| 103 | + | ||||
| 104 | + | **Examples**: | |||
| 105 | + | ```bash | |||
| 106 | + | # Create full project structure | |||
| 107 | + | dumb-browser init structure | |||
| 108 | + | ||||
| 109 | + | # Preview directory layout | |||
| 110 | + | dumb-browser init structure --preview | |||
| 111 | + | ||||
| 112 | + | # Minimal structure (no example files) | |||
| 113 | + | dumb-browser init structure --template=minimal | |||
| 114 | + | ``` | |||
| 115 | + | ||||
| 116 | + | ### `dumb-browser init config` | |||
| 117 | + | **Purpose**: Generate configuration files only | |||
| 118 | + | ||||
| 119 | + | **Syntax**: | |||
| 120 | + | ```bash | |||
| 121 | + | dumb-browser init config [OPTIONS] | |||
| 122 | + | ``` | |||
| 123 | + | ||||
| 124 | + | **Options**: | |||
| 125 | + | - `--type`: Generate specific config (sqlc|wails|all) | |||
| 126 | + | - `--overwrite`: Replace existing config files | |||
| 127 | + | ||||
| 128 | + | **Examples**: | |||
| 129 | + | ```bash | |||
| 130 | + | # Generate all config files | |||
| 131 | + | dumb-browser init config | |||
| 132 | + | ||||
| 133 | + | # Only SQLC configuration | |||
| 134 | + | dumb-browser init config --type=sqlc | |||
| 135 | + | ||||
| 136 | + | # Replace existing configs | |||
| 137 | + | dumb-browser init config --overwrite | |||
| 138 | + | ``` | |||
| 139 | + | ||||
| 140 | + | ## Status and Information Commands | |||
| 141 | + | ||||
| 142 | + | ### `dumb-browser init status` | |||
| 143 | + | **Purpose**: Show initialization status | |||
| 144 | + | ||||
| 145 | + | **Syntax**: | |||
| 146 | + | ```bash | |||
| 147 | + | dumb-browser init status [OPTIONS] | |||
| 148 | + | ``` | |||
| 149 | + | ||||
| 150 | + | **Options**: | |||
| 151 | + | - `--format`: Output format (text|json|yaml) | |||
| 152 | + | - `--detailed`: Show dependency versions and paths | |||
| 153 | + | ||||
| 154 | + | **Output** (text format): | |||
| 155 | + | ``` | |||
| 156 | + | Project Status: ✓ Initialized | |||
| 157 | + | ||||
| 158 | + | Dependencies: | |||
| 159 | + | ✓ CLI (cobra v1.8.0, viper v1.18.2) | |||
| 160 | + | ✓ Database (sqlite3 v1.14.19, sqlc v1.25.0) | |||
| 161 | + | ✓ Validation (validator v10.16.0) | |||
| 162 | + | ✓ Testing (testify v1.8.4) | |||
| 163 | + | ✗ Wails (not installed) | |||
| 164 | + | ||||
| 165 | + | Structure: | |||
| 166 | + | ✓ cmd/, internal/, migrations/, configs/ | |||
| 167 | + | ✗ Missing: tests/integration/ | |||
| 168 | + | ||||
| 169 | + | Build Status: ✓ Ready (go build succeeds) | |||
| 170 | + | ``` | |||
| 171 | + | ||||
| 172 | + | ### `dumb-browser init verify` | |||
| 173 | + | **Purpose**: Verify complete installation | |||
| 174 | + | ||||
| 175 | + | **Syntax**: | |||
| 176 | + | ```bash | |||
| 177 | + | dumb-browser init verify [OPTIONS] | |||
| 178 | + | ``` | |||
| 179 | + | ||||
| 180 | + | **Options**: | |||
| 181 | + | - `--fix`: Attempt to fix detected issues | |||
| 182 | + | - `--report`: Generate detailed verification report | |||
| 183 | + | ||||
| 184 | + | **Exit Codes**: | |||
| 185 | + | - `0`: All verifications passed | |||
| 186 | + | - `1`: Some issues detected but not critical | |||
| 187 | + | - `2`: Critical issues prevent development | |||
| 188 | + | ||||
| 189 | + | ## Error Handling | |||
| 190 | + | ||||
| 191 | + | ### Common Error Scenarios | |||
| 192 | + | ||||
| 193 | + | **Dependency Installation Failures**: | |||
| 194 | + | ```bash | |||
| 195 | + | $ dumb-browser init | |||
| 196 | + | ✗ Installing database dependencies: sqlite3 | |||
| 197 | + | Error: CGO_ENABLED=1 required for sqlite3 | |||
| 198 | + | Suggestion: Run 'export CGO_ENABLED=1' and try again | |||
| 199 | + | Exit Code: 2 | |||
| 200 | + | ``` | |||
| 201 | + | ||||
| 202 | + | **System Dependency Missing**: | |||
| 203 | + | ```bash | |||
| 204 | + | $ dumb-browser init | |||
| 205 | + | ✗ Installing Wails v3-alpha | |||
| 206 | + | Error: libwebkit2gtk-4.0-dev not found | |||
| 207 | + | Suggestion: Install with 'sudo apt install libwebkit2gtk-4.0-dev' | |||
| 208 | + | Exit Code: 3 | |||
| 209 | + | ``` | |||
| 210 | + | ||||
| 211 | + | **Project Already Exists**: | |||
| 212 | + | ```bash | |||
| 213 | + | $ dumb-browser init | |||
| 214 | + | ✗ Project already initialized | |||
| 215 | + | Use --force to reinitialize or run 'dumb-browser init status' | |||
| 216 | + | Exit Code: 4 | |||
| 217 | + | ``` | |||
| 218 | + | ||||
| 219 | + | ## Integration with Other Systems | |||
| 220 | + | ||||
| 221 | + | ### CI/CD Integration | |||
| 222 | + | Commands designed for automated environments: | |||
| 223 | + | ```bash | |||
| 224 | + | # Non-interactive initialization | |||
| 225 | + | dumb-browser init --verbose > init.log 2>&1 | |||
| 226 | + | ||||
| 227 | + | # Verification in CI | |||
| 228 | + | dumb-browser init verify --report=ci-report.json | |||
| 229 | + | ``` | |||
| 230 | + | ||||
| 231 | + | ### Development Workflow Integration | |||
| 232 | + | ```bash | |||
| 233 | + | # Quick setup for new contributors | |||
| 234 | + | git clone <repo> && cd <repo> | |||
| 235 | + | dumb-browser init | |||
| 236 | + | go test ./... | |||
| 237 | + | ``` | |||
| 238 | + | ||||
| 239 | + | ### IDE Integration | |||
| 240 | + | Status command provides machine-readable output: | |||
| 241 | + | ```bash | |||
| 242 | + | dumb-browser init status --format=json | jq '.dependencies.wails.status' | |||
| 243 | + | ``` | |||
| 244 | + | ||||
| 245 | + | This CLI contract supports the initialization phase while providing flexibility for different development scenarios and debugging needs.⏎̸ | |||
A specs/001-init-project/contracts/go-module.yaml +152 -0
| @@ -0,0 +1,152 @@ | |||
| 1 | + | # Go Module Contract: Project Dependencies | |
| 2 | + | ||
| 3 | + | # Expected go.mod file structure after initialization | |
| 4 | + | module: dumb-browser | |
| 5 | + | go_version: "1.25" | |
| 6 | + | ||
| 7 | + | # Runtime dependencies (will be installed via go get @latest) | |
| 8 | + | dependencies: | |
| 9 | + | cli: | |
| 10 | + | - import_path: "github.com/spf13/cobra" | |
| 11 | + | purpose: "CLI framework and command handling" | |
| 12 | + | min_version: "v1.8.0" | |
| 13 | + | ||
| 14 | + | - import_path: "github.com/spf13/viper" | |
| 15 | + | purpose: "Configuration management" | |
| 16 | + | min_version: "v1.18.0" | |
| 17 | + | ||
| 18 | + | database: | |
| 19 | + | - import_path: "github.com/ncruces/go-sqlite3" | |
| 20 | + | purpose: "CGO-free SQLite database driver" | |
| 21 | + | min_version: "v0.28.0" | |
| 22 | + | build_tags: [] | |
| 23 | + | requirements: [] | |
| 24 | + | benefits: ["no CGO required", "better performance", "cleaner builds"] | |
| 25 | + | ||
| 26 | + | validation: | |
| 27 | + | - import_path: "github.com/go-playground/validator/v10" | |
| 28 | + | purpose: "Struct validation and input sanitization" | |
| 29 | + | min_version: "v10.16.0" | |
| 30 | + | ||
| 31 | + | testing: | |
| 32 | + | - import_path: "github.com/stretchr/testify" | |
| 33 | + | purpose: "Enhanced testing assertions and mocks" | |
| 34 | + | min_version: "v1.8.4" | |
| 35 | + | scope: "test" | |
| 36 | + | ||
| 37 | + | # Development tools (installed via go install) | |
| 38 | + | tools: | |
| 39 | + | - name: "sqlc" | |
| 40 | + | install_command: "go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest" | |
| 41 | + | purpose: "Generate type-safe Go code from SQL" | |
| 42 | + | version_check: "sqlc version" | |
| 43 | + | ||
| 44 | + | - name: "wails" | |
| 45 | + | install_command: "go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28" | |
| 46 | + | purpose: "Desktop application framework" | |
| 47 | + | version_check: "wails version" | |
| 48 | + | system_deps: ["libwebkit2gtk-4.0-dev", "libgtk-3-dev"] | |
| 49 | + | ||
| 50 | + | # Expected go.mod content template | |
| 51 | + | go_mod_template: | | |
| 52 | + | module dumb-browser | |
| 53 | + | ||
| 54 | + | go 1.21 | |
| 55 | + | ||
| 56 | + | require ( | |
| 57 | + | github.com/spf13/cobra v1.8.0 | |
| 58 | + | github.com/spf13/viper v1.18.2 | |
| 59 | + | github.com/ncruces/go-sqlite3 v0.28.0 | |
| 60 | + | github.com/go-playground/validator/v10 v10.16.0 | |
| 61 | + | github.com/stretchr/testify v1.8.4 | |
| 62 | + | ) | |
| 63 | + | ||
| 64 | + | # Compatibility matrix | |
| 65 | + | compatibility: | |
| 66 | + | go_version: | |
| 67 | + | minimum: "1.18" # Required for generics | |
| 68 | + | recommended: "1.21" | |
| 69 | + | maximum: "1.22" | |
| 70 | + | ||
| 71 | + | operating_systems: | |
| 72 | + | primary: "linux" | |
| 73 | + | supported: ["linux", "darwin"] | |
| 74 | + | tested: ["archlinux", "ubuntu-22.04"] | |
| 75 | + | ||
| 76 | + | architectures: | |
| 77 | + | primary: "amd64" | |
| 78 | + | supported: ["amd64", "arm64"] | |
| 79 | + | ||
| 80 | + | # Build configuration | |
| 81 | + | build: | |
| 82 | + | tags: | |
| 83 | + | development: ["dev", "debug"] | |
| 84 | + | production: [] | |
| 85 | + | testing: ["test", "integration"] | |
| 86 | + | ||
| 87 | + | environment: | |
| 88 | + | wails_build: | |
| 89 | + | - name: "CGO_ENABLED" | |
| 90 | + | value: "1" | |
| 91 | + | reason: "Required for Wails WebKit2GTK bindings" | |
| 92 | + | cgo_free_development: | |
| 93 | + | - name: "CGO_ENABLED" | |
| 94 | + | value: "0" | |
| 95 | + | reason: "Most development can happen CGO-free (CLI, database, parser)" | |
| 96 | + | ||
| 97 | + | flags: | |
| 98 | + | development: "-race -v" | |
| 99 | + | production: "-ldflags='-s -w'" | |
| 100 | + | ||
| 101 | + | # Verification commands | |
| 102 | + | verification: | |
| 103 | + | module_valid: "go mod verify" | |
| 104 | + | dependencies_resolved: "go mod download" | |
| 105 | + | build_succeeds: "go build ./cmd/dumb-browser" | |
| 106 | + | tests_pass: "go test ./..." | |
| 107 | + | tools_available: | |
| 108 | + | - "sqlc version" | |
| 109 | + | - "wails version" | |
| 110 | + | ||
| 111 | + | # Installation success criteria | |
| 112 | + | success_criteria: | |
| 113 | + | - name: "go.mod exists" | |
| 114 | + | command: "test -f go.mod" | |
| 115 | + | ||
| 116 | + | - name: "module name correct" | |
| 117 | + | command: "grep -q 'module dumb-browser' go.mod" | |
| 118 | + | ||
| 119 | + | - name: "all dependencies resolved" | |
| 120 | + | command: "go mod download && echo 'OK'" | |
| 121 | + | ||
| 122 | + | - name: "build succeeds" | |
| 123 | + | command: "go build -o /tmp/test-build ./cmd/dumb-browser" | |
| 124 | + | cleanup: "rm -f /tmp/test-build" | |
| 125 | + | ||
| 126 | + | - name: "sqlc available" | |
| 127 | + | command: "which sqlc && sqlc version" | |
| 128 | + | ||
| 129 | + | - name: "wails available" | |
| 130 | + | command: "which wails && wails version" | |
| 131 | + | ||
| 132 | + | # Error conditions and solutions | |
| 133 | + | error_handling: | |
| 134 | + | cgo_disabled_for_wails: | |
| 135 | + | error_pattern: "C compiler|CGO_ENABLED.*wails" | |
| 136 | + | solution: "export CGO_ENABLED=1 # Only needed for Wails builds" | |
| 137 | + | documentation: "Wails requires CGO for WebKit2GTK bindings (database layer is CGO-free)" | |
| 138 | + | ||
| 139 | + | missing_webkit: | |
| 140 | + | error_pattern: "webkit2gtk|libwebkit2gtk" | |
| 141 | + | solution: "sudo apt install libwebkit2gtk-4.0-dev libgtk-3-dev" | |
| 142 | + | documentation: "Wails requires WebKit2GTK development headers" | |
| 143 | + | ||
| 144 | + | network_failure: | |
| 145 | + | error_pattern: "dial tcp|connection refused|timeout" | |
| 146 | + | solution: "Check internet connection and proxy settings" | |
| 147 | + | documentation: "Dependency installation requires network access" | |
| 148 | + | ||
| 149 | + | insufficient_space: | |
| 150 | + | error_pattern: "no space left|disk full" | |
| 151 | + | solution: "Free up disk space and try again" | |
| 152 | + | documentation: "Go module cache and tools require ~500MB space"⏎̸ | |
| @@ -0,0 +1,152 @@ | |||||
| 1 | + | # Go Module Contract: Project Dependencies | |||
| 2 | + | ||||
| 3 | + | # Expected go.mod file structure after initialization | |||
| 4 | + | module: dumb-browser | |||
| 5 | + | go_version: "1.25" | |||
| 6 | + | ||||
| 7 | + | # Runtime dependencies (will be installed via go get @latest) | |||
| 8 | + | dependencies: | |||
| 9 | + | cli: | |||
| 10 | + | - import_path: "github.com/spf13/cobra" | |||
| 11 | + | purpose: "CLI framework and command handling" | |||
| 12 | + | min_version: "v1.8.0" | |||
| 13 | + | ||||
| 14 | + | - import_path: "github.com/spf13/viper" | |||
| 15 | + | purpose: "Configuration management" | |||
| 16 | + | min_version: "v1.18.0" | |||
| 17 | + | ||||
| 18 | + | database: | |||
| 19 | + | - import_path: "github.com/ncruces/go-sqlite3" | |||
| 20 | + | purpose: "CGO-free SQLite database driver" | |||
| 21 | + | min_version: "v0.28.0" | |||
| 22 | + | build_tags: [] | |||
| 23 | + | requirements: [] | |||
| 24 | + | benefits: ["no CGO required", "better performance", "cleaner builds"] | |||
| 25 | + | ||||
| 26 | + | validation: | |||
| 27 | + | - import_path: "github.com/go-playground/validator/v10" | |||
| 28 | + | purpose: "Struct validation and input sanitization" | |||
| 29 | + | min_version: "v10.16.0" | |||
| 30 | + | ||||
| 31 | + | testing: | |||
| 32 | + | - import_path: "github.com/stretchr/testify" | |||
| 33 | + | purpose: "Enhanced testing assertions and mocks" | |||
| 34 | + | min_version: "v1.8.4" | |||
| 35 | + | scope: "test" | |||
| 36 | + | ||||
| 37 | + | # Development tools (installed via go install) | |||
| 38 | + | tools: | |||
| 39 | + | - name: "sqlc" | |||
| 40 | + | install_command: "go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest" | |||
| 41 | + | purpose: "Generate type-safe Go code from SQL" | |||
| 42 | + | version_check: "sqlc version" | |||
| 43 | + | ||||
| 44 | + | - name: "wails" | |||
| 45 | + | install_command: "go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28" | |||
| 46 | + | purpose: "Desktop application framework" | |||
| 47 | + | version_check: "wails version" | |||
| 48 | + | system_deps: ["libwebkit2gtk-4.0-dev", "libgtk-3-dev"] | |||
| 49 | + | ||||
| 50 | + | # Expected go.mod content template | |||
| 51 | + | go_mod_template: | | |||
| 52 | + | module dumb-browser | |||
| 53 | + | ||||
| 54 | + | go 1.21 | |||
| 55 | + | ||||
| 56 | + | require ( | |||
| 57 | + | github.com/spf13/cobra v1.8.0 | |||
| 58 | + | github.com/spf13/viper v1.18.2 | |||
| 59 | + | github.com/ncruces/go-sqlite3 v0.28.0 | |||
| 60 | + | github.com/go-playground/validator/v10 v10.16.0 | |||
| 61 | + | github.com/stretchr/testify v1.8.4 | |||
| 62 | + | ) | |||
| 63 | + | ||||
| 64 | + | # Compatibility matrix | |||
| 65 | + | compatibility: | |||
| 66 | + | go_version: | |||
| 67 | + | minimum: "1.18" # Required for generics | |||
| 68 | + | recommended: "1.21" | |||
| 69 | + | maximum: "1.22" | |||
| 70 | + | ||||
| 71 | + | operating_systems: | |||
| 72 | + | primary: "linux" | |||
| 73 | + | supported: ["linux", "darwin"] | |||
| 74 | + | tested: ["archlinux", "ubuntu-22.04"] | |||
| 75 | + | ||||
| 76 | + | architectures: | |||
| 77 | + | primary: "amd64" | |||
| 78 | + | supported: ["amd64", "arm64"] | |||
| 79 | + | ||||
| 80 | + | # Build configuration | |||
| 81 | + | build: | |||
| 82 | + | tags: | |||
| 83 | + | development: ["dev", "debug"] | |||
| 84 | + | production: [] | |||
| 85 | + | testing: ["test", "integration"] | |||
| 86 | + | ||||
| 87 | + | environment: | |||
| 88 | + | wails_build: | |||
| 89 | + | - name: "CGO_ENABLED" | |||
| 90 | + | value: "1" | |||
| 91 | + | reason: "Required for Wails WebKit2GTK bindings" | |||
| 92 | + | cgo_free_development: | |||
| 93 | + | - name: "CGO_ENABLED" | |||
| 94 | + | value: "0" | |||
| 95 | + | reason: "Most development can happen CGO-free (CLI, database, parser)" | |||
| 96 | + | ||||
| 97 | + | flags: | |||
| 98 | + | development: "-race -v" | |||
| 99 | + | production: "-ldflags='-s -w'" | |||
| 100 | + | ||||
| 101 | + | # Verification commands | |||
| 102 | + | verification: | |||
| 103 | + | module_valid: "go mod verify" | |||
| 104 | + | dependencies_resolved: "go mod download" | |||
| 105 | + | build_succeeds: "go build ./cmd/dumb-browser" | |||
| 106 | + | tests_pass: "go test ./..." | |||
| 107 | + | tools_available: | |||
| 108 | + | - "sqlc version" | |||
| 109 | + | - "wails version" | |||
| 110 | + | ||||
| 111 | + | # Installation success criteria | |||
| 112 | + | success_criteria: | |||
| 113 | + | - name: "go.mod exists" | |||
| 114 | + | command: "test -f go.mod" | |||
| 115 | + | ||||
| 116 | + | - name: "module name correct" | |||
| 117 | + | command: "grep -q 'module dumb-browser' go.mod" | |||
| 118 | + | ||||
| 119 | + | - name: "all dependencies resolved" | |||
| 120 | + | command: "go mod download && echo 'OK'" | |||
| 121 | + | ||||
| 122 | + | - name: "build succeeds" | |||
| 123 | + | command: "go build -o /tmp/test-build ./cmd/dumb-browser" | |||
| 124 | + | cleanup: "rm -f /tmp/test-build" | |||
| 125 | + | ||||
| 126 | + | - name: "sqlc available" | |||
| 127 | + | command: "which sqlc && sqlc version" | |||
| 128 | + | ||||
| 129 | + | - name: "wails available" | |||
| 130 | + | command: "which wails && wails version" | |||
| 131 | + | ||||
| 132 | + | # Error conditions and solutions | |||
| 133 | + | error_handling: | |||
| 134 | + | cgo_disabled_for_wails: | |||
| 135 | + | error_pattern: "C compiler|CGO_ENABLED.*wails" | |||
| 136 | + | solution: "export CGO_ENABLED=1 # Only needed for Wails builds" | |||
| 137 | + | documentation: "Wails requires CGO for WebKit2GTK bindings (database layer is CGO-free)" | |||
| 138 | + | ||||
| 139 | + | missing_webkit: | |||
| 140 | + | error_pattern: "webkit2gtk|libwebkit2gtk" | |||
| 141 | + | solution: "sudo apt install libwebkit2gtk-4.0-dev libgtk-3-dev" | |||
| 142 | + | documentation: "Wails requires WebKit2GTK development headers" | |||
| 143 | + | ||||
| 144 | + | network_failure: | |||
| 145 | + | error_pattern: "dial tcp|connection refused|timeout" | |||
| 146 | + | solution: "Check internet connection and proxy settings" | |||
| 147 | + | documentation: "Dependency installation requires network access" | |||
| 148 | + | ||||
| 149 | + | insufficient_space: | |||
| 150 | + | error_pattern: "no space left|disk full" | |||
| 151 | + | solution: "Free up disk space and try again" | |||
| 152 | + | documentation: "Go module cache and tools require ~500MB space"⏎̸ | |||
A specs/001-init-project/data-model.md +172 -0
| @@ -0,0 +1,172 @@ | |||
| 1 | + | # Data Model: Project Initialization | |
| 2 | + | ||
| 3 | + | **Date**: 2025-01-09 | |
| 4 | + | **Context**: Data structures for dumb-browser project initialization | |
| 5 | + | ||
| 6 | + | ## Core Entities | |
| 7 | + | ||
| 8 | + | ### 1. Go Module Configuration | |
| 9 | + | **Purpose**: Represents the initialized Go module and its metadata | |
| 10 | + | ||
| 11 | + | **Structure**: | |
| 12 | + | ```go | |
| 13 | + | type ModuleConfig struct { | |
| 14 | + | Name string `validate:"required"` // "dumb-browser" | |
| 15 | + | Version string `validate:"required,semver"` // "v0.1.0" | |
| 16 | + | GoVersion string `validate:"required"` // Go version requirement | |
| 17 | + | Dependencies []Dependency `validate:"dive"` | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | type Dependency struct { | |
| 21 | + | ImportPath string `validate:"required,uri"` // e.g. "github.com/spf13/cobra" | |
| 22 | + | Version string `validate:"required"` // "@latest" or specific version | |
| 23 | + | Type DependencyType `validate:"required"` // runtime, dev, tool | |
| 24 | + | } | |
| 25 | + | ||
| 26 | + | type DependencyType int | |
| 27 | + | const ( | |
| 28 | + | RuntimeDep DependencyType = iota // Core application dependencies | |
| 29 | + | DevDep // Development/testing tools | |
| 30 | + | ToolDep // CLI tools (sqlc, wails) | |
| 31 | + | ) | |
| 32 | + | ``` | |
| 33 | + | ||
| 34 | + | **Validation Rules**: | |
| 35 | + | - Module name must be valid Go identifier | |
| 36 | + | - Version must follow semantic versioning | |
| 37 | + | - All dependency paths must be valid import paths | |
| 38 | + | - No circular dependencies allowed | |
| 39 | + | ||
| 40 | + | ### 2. Project Structure | |
| 41 | + | **Purpose**: Defines the directory layout and file organization | |
| 42 | + | ||
| 43 | + | **Structure**: | |
| 44 | + | ```go | |
| 45 | + | type ProjectStructure struct { | |
| 46 | + | RootPath string `validate:"required,dir"` | |
| 47 | + | Directories []Directory `validate:"dive"` | |
| 48 | + | ConfigFiles []ConfigFile `validate:"dive"` | |
| 49 | + | InitialFiles []InitialFile `validate:"dive"` | |
| 50 | + | } | |
| 51 | + | ||
| 52 | + | type Directory struct { | |
| 53 | + | Path string `validate:"required"` // relative to root | |
| 54 | + | Purpose string `validate:"required"` // description | |
| 55 | + | Required bool // must be created | |
| 56 | + | } | |
| 57 | + | ||
| 58 | + | type ConfigFile struct { | |
| 59 | + | Path string `validate:"required"` // relative to root | |
| 60 | + | Template string `validate:"required"` // template name | |
| 61 | + | Variables map[string]string // template variables | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | type InitialFile struct { | |
| 65 | + | Path string `validate:"required"` // relative to root | |
| 66 | + | Content string // file content | |
| 67 | + | Type FileType `validate:"required"` // go, sql, yaml, etc. | |
| 68 | + | } | |
| 69 | + | ``` | |
| 70 | + | ||
| 71 | + | ### 3. Dependency Installation Status | |
| 72 | + | **Purpose**: Tracks installation progress and success/failure states | |
| 73 | + | ||
| 74 | + | **Structure**: | |
| 75 | + | ```go | |
| 76 | + | type InstallationStatus struct { | |
| 77 | + | ModuleName string `validate:"required"` | |
| 78 | + | Dependencies []DependencyStatus `validate:"dive"` | |
| 79 | + | Tools []ToolStatus `validate:"dive"` | |
| 80 | + | Overall StatusType `validate:"required"` | |
| 81 | + | Timestamp time.Time `validate:"required"` | |
| 82 | + | Errors []InstallError | |
| 83 | + | } | |
| 84 | + | ||
| 85 | + | type DependencyStatus struct { | |
| 86 | + | ImportPath string `validate:"required"` | |
| 87 | + | Version string | |
| 88 | + | Status StatusType `validate:"required"` | |
| 89 | + | InstallTime time.Duration // how long to install | |
| 90 | + | Error *InstallError | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | type ToolStatus struct { | |
| 94 | + | Name string `validate:"required"` // "sqlc", "wails" | |
| 95 | + | Command string `validate:"required"` // installation command | |
| 96 | + | Status StatusType `validate:"required"` | |
| 97 | + | Version string // installed version | |
| 98 | + | Error *InstallError | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | type StatusType int | |
| 102 | + | const ( | |
| 103 | + | NotStarted StatusType = iota | |
| 104 | + | InProgress | |
| 105 | + | Success | |
| 106 | + | Failed | |
| 107 | + | Skipped | |
| 108 | + | ) | |
| 109 | + | ||
| 110 | + | type InstallError struct { | |
| 111 | + | Message string `validate:"required"` | |
| 112 | + | Code int | |
| 113 | + | Suggestion string // helpful hint for user | |
| 114 | + | } | |
| 115 | + | ``` | |
| 116 | + | ||
| 117 | + | ## State Transitions | |
| 118 | + | ||
| 119 | + | ### Module Initialization Flow | |
| 120 | + | ``` | |
| 121 | + | Empty Directory → Module Init → Dependency Resolution → Tool Installation → Verification → Complete | |
| 122 | + | ↓ ↓ ↓ ↓ | |
| 123 | + | [go.mod] [go.mod updated] [tools available] [build succeeds] | |
| 124 | + | ``` | |
| 125 | + | ||
| 126 | + | ### Dependency Installation States | |
| 127 | + | ``` | |
| 128 | + | NotStarted → InProgress → Success | |
| 129 | + | ↓ | |
| 130 | + | Failed (with retry option) | |
| 131 | + | ``` | |
| 132 | + | ||
| 133 | + | ## Relationships | |
| 134 | + | ||
| 135 | + | 1. **ModuleConfig** contains multiple **Dependencies** | |
| 136 | + | 2. **ProjectStructure** defines where **ConfigFiles** are placed | |
| 137 | + | 3. **InstallationStatus** tracks the progress of **ModuleConfig** setup | |
| 138 | + | 4. Each **Directory** in **ProjectStructure** serves specific **Dependencies** | |
| 139 | + | ||
| 140 | + | ## Validation Constraints | |
| 141 | + | ||
| 142 | + | ### Business Rules | |
| 143 | + | 1. **Module name uniqueness**: No conflicts with existing Go modules in workspace | |
| 144 | + | 2. **Dependency compatibility**: All dependencies must support the same Go version | |
| 145 | + | 3. **Tool availability**: Required tools (sqlc, wails) must be installable | |
| 146 | + | 4. **Directory permissions**: All target directories must be writable | |
| 147 | + | 5. **Disk space**: Adequate space for dependencies and generated files | |
| 148 | + | ||
| 149 | + | ### Technical Constraints | |
| 150 | + | 1. **Go version**: Must support generics (Go 1.18+) | |
| 151 | + | 2. **CGO requirement**: SQLite driver requires CGO_ENABLED=1 | |
| 152 | + | 3. **System dependencies**: Wails requires WebKit2GTK development headers | |
| 153 | + | 4. **Network access**: Dependency download requires internet connectivity | |
| 154 | + | ||
| 155 | + | ## Integration Points | |
| 156 | + | ||
| 157 | + | ### With CLI Commands | |
| 158 | + | - `dumb-browser init` → Creates **ModuleConfig** and **ProjectStructure** | |
| 159 | + | - `dumb-browser deps install` → Updates **InstallationStatus** | |
| 160 | + | - `dumb-browser deps verify` → Validates all **Dependencies** | |
| 161 | + | ||
| 162 | + | ### With Configuration Files | |
| 163 | + | - **go.mod**: Generated from **ModuleConfig** | |
| 164 | + | - **sqlc.yaml**: Generated from database **Dependencies** | |
| 165 | + | - **wails.json**: Generated from Wails **Dependencies** | |
| 166 | + | ||
| 167 | + | ### With Testing Framework | |
| 168 | + | - Integration tests validate each **StatusType** transition | |
| 169 | + | - Contract tests verify **ConfigFile** template generation | |
| 170 | + | - Unit tests cover **Dependency** validation logic | |
| 171 | + | ||
| 172 | + | This data model supports the initialization phase while preparing for the next development phases (CLI implementation, database setup, browser integration).⏎̸ | |
| @@ -0,0 +1,172 @@ | |||||
| 1 | + | # Data Model: Project Initialization | |||
| 2 | + | ||||
| 3 | + | **Date**: 2025-01-09 | |||
| 4 | + | **Context**: Data structures for dumb-browser project initialization | |||
| 5 | + | ||||
| 6 | + | ## Core Entities | |||
| 7 | + | ||||
| 8 | + | ### 1. Go Module Configuration | |||
| 9 | + | **Purpose**: Represents the initialized Go module and its metadata | |||
| 10 | + | ||||
| 11 | + | **Structure**: | |||
| 12 | + | ```go | |||
| 13 | + | type ModuleConfig struct { | |||
| 14 | + | Name string `validate:"required"` // "dumb-browser" | |||
| 15 | + | Version string `validate:"required,semver"` // "v0.1.0" | |||
| 16 | + | GoVersion string `validate:"required"` // Go version requirement | |||
| 17 | + | Dependencies []Dependency `validate:"dive"` | |||
| 18 | + | } | |||
| 19 | + | ||||
| 20 | + | type Dependency struct { | |||
| 21 | + | ImportPath string `validate:"required,uri"` // e.g. "github.com/spf13/cobra" | |||
| 22 | + | Version string `validate:"required"` // "@latest" or specific version | |||
| 23 | + | Type DependencyType `validate:"required"` // runtime, dev, tool | |||
| 24 | + | } | |||
| 25 | + | ||||
| 26 | + | type DependencyType int | |||
| 27 | + | const ( | |||
| 28 | + | RuntimeDep DependencyType = iota // Core application dependencies | |||
| 29 | + | DevDep // Development/testing tools | |||
| 30 | + | ToolDep // CLI tools (sqlc, wails) | |||
| 31 | + | ) | |||
| 32 | + | ``` | |||
| 33 | + | ||||
| 34 | + | **Validation Rules**: | |||
| 35 | + | - Module name must be valid Go identifier | |||
| 36 | + | - Version must follow semantic versioning | |||
| 37 | + | - All dependency paths must be valid import paths | |||
| 38 | + | - No circular dependencies allowed | |||
| 39 | + | ||||
| 40 | + | ### 2. Project Structure | |||
| 41 | + | **Purpose**: Defines the directory layout and file organization | |||
| 42 | + | ||||
| 43 | + | **Structure**: | |||
| 44 | + | ```go | |||
| 45 | + | type ProjectStructure struct { | |||
| 46 | + | RootPath string `validate:"required,dir"` | |||
| 47 | + | Directories []Directory `validate:"dive"` | |||
| 48 | + | ConfigFiles []ConfigFile `validate:"dive"` | |||
| 49 | + | InitialFiles []InitialFile `validate:"dive"` | |||
| 50 | + | } | |||
| 51 | + | ||||
| 52 | + | type Directory struct { | |||
| 53 | + | Path string `validate:"required"` // relative to root | |||
| 54 | + | Purpose string `validate:"required"` // description | |||
| 55 | + | Required bool // must be created | |||
| 56 | + | } | |||
| 57 | + | ||||
| 58 | + | type ConfigFile struct { | |||
| 59 | + | Path string `validate:"required"` // relative to root | |||
| 60 | + | Template string `validate:"required"` // template name | |||
| 61 | + | Variables map[string]string // template variables | |||
| 62 | + | } | |||
| 63 | + | ||||
| 64 | + | type InitialFile struct { | |||
| 65 | + | Path string `validate:"required"` // relative to root | |||
| 66 | + | Content string // file content | |||
| 67 | + | Type FileType `validate:"required"` // go, sql, yaml, etc. | |||
| 68 | + | } | |||
| 69 | + | ``` | |||
| 70 | + | ||||
| 71 | + | ### 3. Dependency Installation Status | |||
| 72 | + | **Purpose**: Tracks installation progress and success/failure states | |||
| 73 | + | ||||
| 74 | + | **Structure**: | |||
| 75 | + | ```go | |||
| 76 | + | type InstallationStatus struct { | |||
| 77 | + | ModuleName string `validate:"required"` | |||
| 78 | + | Dependencies []DependencyStatus `validate:"dive"` | |||
| 79 | + | Tools []ToolStatus `validate:"dive"` | |||
| 80 | + | Overall StatusType `validate:"required"` | |||
| 81 | + | Timestamp time.Time `validate:"required"` | |||
| 82 | + | Errors []InstallError | |||
| 83 | + | } | |||
| 84 | + | ||||
| 85 | + | type DependencyStatus struct { | |||
| 86 | + | ImportPath string `validate:"required"` | |||
| 87 | + | Version string | |||
| 88 | + | Status StatusType `validate:"required"` | |||
| 89 | + | InstallTime time.Duration // how long to install | |||
| 90 | + | Error *InstallError | |||
| 91 | + | } | |||
| 92 | + | ||||
| 93 | + | type ToolStatus struct { | |||
| 94 | + | Name string `validate:"required"` // "sqlc", "wails" | |||
| 95 | + | Command string `validate:"required"` // installation command | |||
| 96 | + | Status StatusType `validate:"required"` | |||
| 97 | + | Version string // installed version | |||
| 98 | + | Error *InstallError | |||
| 99 | + | } | |||
| 100 | + | ||||
| 101 | + | type StatusType int | |||
| 102 | + | const ( | |||
| 103 | + | NotStarted StatusType = iota | |||
| 104 | + | InProgress | |||
| 105 | + | Success | |||
| 106 | + | Failed | |||
| 107 | + | Skipped | |||
| 108 | + | ) | |||
| 109 | + | ||||
| 110 | + | type InstallError struct { | |||
| 111 | + | Message string `validate:"required"` | |||
| 112 | + | Code int | |||
| 113 | + | Suggestion string // helpful hint for user | |||
| 114 | + | } | |||
| 115 | + | ``` | |||
| 116 | + | ||||
| 117 | + | ## State Transitions | |||
| 118 | + | ||||
| 119 | + | ### Module Initialization Flow | |||
| 120 | + | ``` | |||
| 121 | + | Empty Directory → Module Init → Dependency Resolution → Tool Installation → Verification → Complete | |||
| 122 | + | ↓ ↓ ↓ ↓ | |||
| 123 | + | [go.mod] [go.mod updated] [tools available] [build succeeds] | |||
| 124 | + | ``` | |||
| 125 | + | ||||
| 126 | + | ### Dependency Installation States | |||
| 127 | + | ``` | |||
| 128 | + | NotStarted → InProgress → Success | |||
| 129 | + | ↓ | |||
| 130 | + | Failed (with retry option) | |||
| 131 | + | ``` | |||
| 132 | + | ||||
| 133 | + | ## Relationships | |||
| 134 | + | ||||
| 135 | + | 1. **ModuleConfig** contains multiple **Dependencies** | |||
| 136 | + | 2. **ProjectStructure** defines where **ConfigFiles** are placed | |||
| 137 | + | 3. **InstallationStatus** tracks the progress of **ModuleConfig** setup | |||
| 138 | + | 4. Each **Directory** in **ProjectStructure** serves specific **Dependencies** | |||
| 139 | + | ||||
| 140 | + | ## Validation Constraints | |||
| 141 | + | ||||
| 142 | + | ### Business Rules | |||
| 143 | + | 1. **Module name uniqueness**: No conflicts with existing Go modules in workspace | |||
| 144 | + | 2. **Dependency compatibility**: All dependencies must support the same Go version | |||
| 145 | + | 3. **Tool availability**: Required tools (sqlc, wails) must be installable | |||
| 146 | + | 4. **Directory permissions**: All target directories must be writable | |||
| 147 | + | 5. **Disk space**: Adequate space for dependencies and generated files | |||
| 148 | + | ||||
| 149 | + | ### Technical Constraints | |||
| 150 | + | 1. **Go version**: Must support generics (Go 1.18+) | |||
| 151 | + | 2. **CGO requirement**: SQLite driver requires CGO_ENABLED=1 | |||
| 152 | + | 3. **System dependencies**: Wails requires WebKit2GTK development headers | |||
| 153 | + | 4. **Network access**: Dependency download requires internet connectivity | |||
| 154 | + | ||||
| 155 | + | ## Integration Points | |||
| 156 | + | ||||
| 157 | + | ### With CLI Commands | |||
| 158 | + | - `dumb-browser init` → Creates **ModuleConfig** and **ProjectStructure** | |||
| 159 | + | - `dumb-browser deps install` → Updates **InstallationStatus** | |||
| 160 | + | - `dumb-browser deps verify` → Validates all **Dependencies** | |||
| 161 | + | ||||
| 162 | + | ### With Configuration Files | |||
| 163 | + | - **go.mod**: Generated from **ModuleConfig** | |||
| 164 | + | - **sqlc.yaml**: Generated from database **Dependencies** | |||
| 165 | + | - **wails.json**: Generated from Wails **Dependencies** | |||
| 166 | + | ||||
| 167 | + | ### With Testing Framework | |||
| 168 | + | - Integration tests validate each **StatusType** transition | |||
| 169 | + | - Contract tests verify **ConfigFile** template generation | |||
| 170 | + | - Unit tests cover **Dependency** validation logic | |||
| 171 | + | ||||
| 172 | + | This data model supports the initialization phase while preparing for the next development phases (CLI implementation, database setup, browser integration).⏎̸ | |||
A specs/001-init-project/plan.md +252 -0
| @@ -0,0 +1,252 @@ | |||
| 1 | + | # Implementation Plan: Project Initialization with Dependencies | |
| 2 | + | ||
| 3 | + | **Branch**: `001-init-project` | **Date**: 2025-01-09 | **Spec**: [spec.md](./spec.md) | |
| 4 | + | **Input**: Feature specification from `/home/brice/dev/projects/dumb-browser/specs/001-init-project/spec.md` | |
| 5 | + | ||
| 6 | + | ## Execution Flow (/plan command scope) | |
| 7 | + | ``` | |
| 8 | + | 1. Load feature spec from Input path | |
| 9 | + | → If not found: ERROR "No feature spec at {path}" | |
| 10 | + | 2. Fill Technical Context (scan for NEEDS CLARIFICATION) | |
| 11 | + | → Detect Project Type from context (web=frontend+backend, mobile=app+api) | |
| 12 | + | → Set Structure Decision based on project type | |
| 13 | + | 3. Evaluate Constitution Check section below | |
| 14 | + | → If violations exist: Document in Complexity Tracking | |
| 15 | + | → If no justification possible: ERROR "Simplify approach first" | |
| 16 | + | → Update Progress Tracking: Initial Constitution Check | |
| 17 | + | 4. Execute Phase 0 → research.md | |
| 18 | + | → If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns" | |
| 19 | + | 5. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, or `GEMINI.md` for Gemini CLI). | |
| 20 | + | 6. Re-evaluate Constitution Check section | |
| 21 | + | → If new violations: Refactor design, return to Phase 1 | |
| 22 | + | → Update Progress Tracking: Post-Design Constitution Check | |
| 23 | + | 7. Plan Phase 2 → Describe task generation approach (DO NOT create tasks.md) | |
| 24 | + | 8. STOP - Ready for /tasks command | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | **IMPORTANT**: The /plan command STOPS at step 7. Phases 2-4 are executed by other commands: | |
| 28 | + | - Phase 2: /tasks command creates tasks.md | |
| 29 | + | - Phase 3-4: Implementation execution (manual or via tools) | |
| 30 | + | ||
| 31 | + | ## Summary | |
| 32 | + | Initialize a Go project with all required dependencies for the dumb-browser application, following the constitution's technical stack: Go + Wails v3-alpha + WebKit2GTK + SQLite with CLI (Cobra + Viper), database (SQLC), and validation (go-playground/validator) components. Use `go get @latest` for all dependencies. | |
| 33 | + | ||
| 34 | + | ## Technical Context | |
| 35 | + | **User Details**: We need to add all deps using go get @latest | |
| 36 | + | **Language/Version**: Go (latest compatible with Wails v3-alpha) | |
| 37 | + | **Primary Dependencies**: Wails v3-alpha, Cobra, Viper, SQLC, go-playground/validator, SQLite driver | |
| 38 | + | **Storage**: SQLite (local embedded database) | |
| 39 | + | **Testing**: Go standard testing + testify for enhanced assertions | |
| 40 | + | **Target Platform**: Linux Wayland (sway, hyprland) - primary focus | |
| 41 | + | **Project Type**: single (desktop application with CLI + GUI components) | |
| 42 | + | **Performance Goals**: < 500ms startup time, < 100MB baseline memory | |
| 43 | + | **Constraints**: Single binary, WebKit2GTK system dependency only | |
| 44 | + | **Scale/Scope**: Personal productivity tool, local history management (1000+ entries) | |
| 45 | + | ||
| 46 | + | ## Constitution Check | |
| 47 | + | *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* | |
| 48 | + | ||
| 49 | + | **Simplicity**: | |
| 50 | + | - Projects: 1 (single desktop app - dumb-browser) | |
| 51 | + | - Using framework directly? YES (Wails, Cobra, Viper directly) | |
| 52 | + | - Single data model? YES (SQLite schema matches Go structs via SQLC) | |
| 53 | + | - Avoiding patterns? YES (no unnecessary abstractions for initialization) | |
| 54 | + | ||
| 55 | + | **Architecture**: | |
| 56 | + | - EVERY feature as library? YES (CLI, parser, database, browser as separate packages) | |
| 57 | + | - Libraries planned: cli (cobra commands), db (sqlc queries), parser (URL handling), browser (Wails integration) | |
| 58 | + | - CLI per library: main CLI with subcommands (--dmenu, history, config) | |
| 59 | + | - Library docs: llms.txt format will be generated post-implementation | |
| 60 | + | ||
| 61 | + | **Testing (NON-NEGOTIABLE)**: | |
| 62 | + | - RED-GREEN-Refactor cycle enforced? YES (tests for module initialization first) | |
| 63 | + | - Git commits show tests before implementation? YES (test dependency resolution before implementation) | |
| 64 | + | - Order: Contract→Integration→E2E→Unit strictly followed? YES | |
| 65 | + | - Real dependencies used? YES (actual Go modules, SQLite DB) | |
| 66 | + | - Integration tests for: module loading, dependency compatibility, build success | |
| 67 | + | - FORBIDDEN: Implementation before test, skipping RED phase | |
| 68 | + | ||
| 69 | + | **Observability**: | |
| 70 | + | - Structured logging included? YES (slog for debugging initialization) | |
| 71 | + | - Frontend logs → backend? N/A for initialization phase | |
| 72 | + | - Error context sufficient? YES (proper error chains for dependency failures) | |
| 73 | + | ||
| 74 | + | **Versioning**: | |
| 75 | + | - Version number assigned? YES (v0.1.0 - initial development) | |
| 76 | + | - BUILD increments on every change? YES (following semantic versioning) | |
| 77 | + | - Breaking changes handled? N/A for initial setup | |
| 78 | + | ||
| 79 | + | ## Project Structure | |
| 80 | + | ||
| 81 | + | ### Documentation (this feature) | |
| 82 | + | ``` | |
| 83 | + | specs/[###-feature]/ | |
| 84 | + | ├── plan.md # This file (/plan command output) | |
| 85 | + | ├── research.md # Phase 0 output (/plan command) | |
| 86 | + | ├── data-model.md # Phase 1 output (/plan command) | |
| 87 | + | ├── quickstart.md # Phase 1 output (/plan command) | |
| 88 | + | ├── contracts/ # Phase 1 output (/plan command) | |
| 89 | + | └── tasks.md # Phase 2 output (/tasks command - NOT created by /plan) | |
| 90 | + | ``` | |
| 91 | + | ||
| 92 | + | ### Source Code (repository root) | |
| 93 | + | ``` | |
| 94 | + | # Option 1: Single project (DEFAULT) | |
| 95 | + | src/ | |
| 96 | + | ├── models/ | |
| 97 | + | ├── services/ | |
| 98 | + | ├── cli/ | |
| 99 | + | └── lib/ | |
| 100 | + | ||
| 101 | + | tests/ | |
| 102 | + | ├── contract/ | |
| 103 | + | ├── integration/ | |
| 104 | + | └── unit/ | |
| 105 | + | ||
| 106 | + | # Option 2: Web application (when "frontend" + "backend" detected) | |
| 107 | + | backend/ | |
| 108 | + | ├── src/ | |
| 109 | + | │ ├── models/ | |
| 110 | + | │ ├── services/ | |
| 111 | + | │ └── api/ | |
| 112 | + | └── tests/ | |
| 113 | + | ||
| 114 | + | frontend/ | |
| 115 | + | ├── src/ | |
| 116 | + | │ ├── components/ | |
| 117 | + | │ ├── pages/ | |
| 118 | + | │ └── services/ | |
| 119 | + | └── tests/ | |
| 120 | + | ||
| 121 | + | # Option 3: Mobile + API (when "iOS/Android" detected) | |
| 122 | + | api/ | |
| 123 | + | └── [same as backend above] | |
| 124 | + | ||
| 125 | + | ios/ or android/ | |
| 126 | + | └── [platform-specific structure] | |
| 127 | + | ``` | |
| 128 | + | ||
| 129 | + | **Structure Decision**: Option 1 - Single project (desktop application with CLI and GUI components) | |
| 130 | + | ||
| 131 | + | ## Phase 0: Outline & Research | |
| 132 | + | 1. **Extract unknowns from Technical Context** above: | |
| 133 | + | - For each NEEDS CLARIFICATION → research task | |
| 134 | + | - For each dependency → best practices task | |
| 135 | + | - For each integration → patterns task | |
| 136 | + | ||
| 137 | + | 2. **Generate and dispatch research agents**: | |
| 138 | + | ``` | |
| 139 | + | For each unknown in Technical Context: | |
| 140 | + | Task: "Research {unknown} for {feature context}" | |
| 141 | + | For each technology choice: | |
| 142 | + | Task: "Find best practices for {tech} in {domain}" | |
| 143 | + | ``` | |
| 144 | + | ||
| 145 | + | 3. **Consolidate findings** in `research.md` using format: | |
| 146 | + | - Decision: [what was chosen] | |
| 147 | + | - Rationale: [why chosen] | |
| 148 | + | - Alternatives considered: [what else evaluated] | |
| 149 | + | ||
| 150 | + | **Output**: research.md with all NEEDS CLARIFICATION resolved | |
| 151 | + | ||
| 152 | + | ## Phase 1: Design & Contracts | |
| 153 | + | *Prerequisites: research.md complete* | |
| 154 | + | ||
| 155 | + | 1. **Extract entities from feature spec** → `data-model.md`: | |
| 156 | + | - Entity name, fields, relationships | |
| 157 | + | - Validation rules from requirements | |
| 158 | + | - State transitions if applicable | |
| 159 | + | ||
| 160 | + | 2. **Generate API contracts** from functional requirements: | |
| 161 | + | - For each user action → endpoint | |
| 162 | + | - Use standard REST/GraphQL patterns | |
| 163 | + | - Output OpenAPI/GraphQL schema to `/contracts/` | |
| 164 | + | ||
| 165 | + | 3. **Generate contract tests** from contracts: | |
| 166 | + | - One test file per endpoint | |
| 167 | + | - Assert request/response schemas | |
| 168 | + | - Tests must fail (no implementation yet) | |
| 169 | + | ||
| 170 | + | 4. **Extract test scenarios** from user stories: | |
| 171 | + | - Each story → integration test scenario | |
| 172 | + | - Quickstart test = story validation steps | |
| 173 | + | ||
| 174 | + | 5. **Update agent file incrementally** (O(1) operation): | |
| 175 | + | - Run `/scripts/update-agent-context.sh [claude|gemini|copilot]` for your AI assistant | |
| 176 | + | - If exists: Add only NEW tech from current plan | |
| 177 | + | - Preserve manual additions between markers | |
| 178 | + | - Update recent changes (keep last 3) | |
| 179 | + | - Keep under 150 lines for token efficiency | |
| 180 | + | - Output to repository root | |
| 181 | + | ||
| 182 | + | **Output**: data-model.md, /contracts/*, failing tests, quickstart.md, agent-specific file | |
| 183 | + | ||
| 184 | + | ## Phase 2: Task Planning Approach | |
| 185 | + | *This section describes what the /tasks command will do - DO NOT execute during /plan* | |
| 186 | + | ||
| 187 | + | **Task Generation Strategy**: | |
| 188 | + | - Load `/templates/tasks-template.md` as base | |
| 189 | + | - Generate tasks from Phase 1 design docs (contracts, data model, quickstart) | |
| 190 | + | - Prioritize CGO-free components first (faster development cycle) | |
| 191 | + | - Each CLI command contract → contract test + implementation task | |
| 192 | + | - Module initialization → dependency installation tasks | |
| 193 | + | - Project structure → directory creation + config generation tasks | |
| 194 | + | - Integration tests for each success criterion in quickstart | |
| 195 | + | ||
| 196 | + | **Ordering Strategy**: | |
| 197 | + | - TDD order: Tests before implementation | |
| 198 | + | - CGO-free first: CLI, parser, database (can develop with CGO_ENABLED=0) | |
| 199 | + | - Wails integration last: Full application build (requires CGO_ENABLED=1) | |
| 200 | + | - Dependency order: Go module → dependencies → structure → config → verification | |
| 201 | + | - Mark [P] for parallel execution (independent dependency installations) | |
| 202 | + | ||
| 203 | + | **Key Task Categories**: | |
| 204 | + | 1. **Module Setup Tasks**: go mod init, dependency installation | |
| 205 | + | 2. **Structure Tasks**: Directory creation, config file generation | |
| 206 | + | 3. **Verification Tasks**: Build tests, tool availability checks | |
| 207 | + | 4. **Integration Tasks**: Full quickstart validation | |
| 208 | + | ||
| 209 | + | **CGO Optimization**: | |
| 210 | + | - Most tasks can run with CGO_ENABLED=0 for faster iteration | |
| 211 | + | - Only final integration tests require CGO_ENABLED=1 | |
| 212 | + | - Clear separation allows parallel development of CGO-free components | |
| 213 | + | ||
| 214 | + | **Estimated Output**: 15-20 numbered, ordered tasks in tasks.md (streamlined for initialization focus) | |
| 215 | + | ||
| 216 | + | **IMPORTANT**: This phase is executed by the /tasks command, NOT by /plan | |
| 217 | + | ||
| 218 | + | ## Phase 3+: Future Implementation | |
| 219 | + | *These phases are beyond the scope of the /plan command* | |
| 220 | + | ||
| 221 | + | **Phase 3**: Task execution (/tasks command creates tasks.md) | |
| 222 | + | **Phase 4**: Implementation (execute tasks.md following constitutional principles) | |
| 223 | + | **Phase 5**: Validation (run tests, execute quickstart.md, performance validation) | |
| 224 | + | ||
| 225 | + | ## Complexity Tracking | |
| 226 | + | *Fill ONLY if Constitution Check has violations that must be justified* | |
| 227 | + | ||
| 228 | + | | Violation | Why Needed | Simpler Alternative Rejected Because | | |
| 229 | + | |-----------|------------|-------------------------------------| | |
| 230 | + | | [e.g., 4th project] | [current need] | [why 3 projects insufficient] | | |
| 231 | + | | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | | |
| 232 | + | ||
| 233 | + | ||
| 234 | + | ## Progress Tracking | |
| 235 | + | *This checklist is updated during execution flow* | |
| 236 | + | ||
| 237 | + | **Phase Status**: | |
| 238 | + | - [x] Phase 0: Research complete (/plan command) | |
| 239 | + | - [x] Phase 1: Design complete (/plan command) | |
| 240 | + | - [x] Phase 2: Task planning complete (/plan command - describe approach only) | |
| 241 | + | - [ ] Phase 3: Tasks generated (/tasks command) | |
| 242 | + | - [ ] Phase 4: Implementation complete | |
| 243 | + | - [ ] Phase 5: Validation passed | |
| 244 | + | ||
| 245 | + | **Gate Status**: | |
| 246 | + | - [x] Initial Constitution Check: PASS | |
| 247 | + | - [x] Post-Design Constitution Check: PASS | |
| 248 | + | - [x] All NEEDS CLARIFICATION resolved | |
| 249 | + | - [x] Complexity deviations documented (none - simplicity maintained) | |
| 250 | + | ||
| 251 | + | --- | |
| 252 | + | *Based on Constitution v2.1.1 - See `/memory/constitution.md`*⏎̸ | |
| @@ -0,0 +1,252 @@ | |||||
| 1 | + | # Implementation Plan: Project Initialization with Dependencies | |||
| 2 | + | ||||
| 3 | + | **Branch**: `001-init-project` | **Date**: 2025-01-09 | **Spec**: [spec.md](./spec.md) | |||
| 4 | + | **Input**: Feature specification from `/home/brice/dev/projects/dumb-browser/specs/001-init-project/spec.md` | |||
| 5 | + | ||||
| 6 | + | ## Execution Flow (/plan command scope) | |||
| 7 | + | ``` | |||
| 8 | + | 1. Load feature spec from Input path | |||
| 9 | + | → If not found: ERROR "No feature spec at {path}" | |||
| 10 | + | 2. Fill Technical Context (scan for NEEDS CLARIFICATION) | |||
| 11 | + | → Detect Project Type from context (web=frontend+backend, mobile=app+api) | |||
| 12 | + | → Set Structure Decision based on project type | |||
| 13 | + | 3. Evaluate Constitution Check section below | |||
| 14 | + | → If violations exist: Document in Complexity Tracking | |||
| 15 | + | → If no justification possible: ERROR "Simplify approach first" | |||
| 16 | + | → Update Progress Tracking: Initial Constitution Check | |||
| 17 | + | 4. Execute Phase 0 → research.md | |||
| 18 | + | → If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns" | |||
| 19 | + | 5. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, or `GEMINI.md` for Gemini CLI). | |||
| 20 | + | 6. Re-evaluate Constitution Check section | |||
| 21 | + | → If new violations: Refactor design, return to Phase 1 | |||
| 22 | + | → Update Progress Tracking: Post-Design Constitution Check | |||
| 23 | + | 7. Plan Phase 2 → Describe task generation approach (DO NOT create tasks.md) | |||
| 24 | + | 8. STOP - Ready for /tasks command | |||
| 25 | + | ``` | |||
| 26 | + | ||||
| 27 | + | **IMPORTANT**: The /plan command STOPS at step 7. Phases 2-4 are executed by other commands: | |||
| 28 | + | - Phase 2: /tasks command creates tasks.md | |||
| 29 | + | - Phase 3-4: Implementation execution (manual or via tools) | |||
| 30 | + | ||||
| 31 | + | ## Summary | |||
| 32 | + | Initialize a Go project with all required dependencies for the dumb-browser application, following the constitution's technical stack: Go + Wails v3-alpha + WebKit2GTK + SQLite with CLI (Cobra + Viper), database (SQLC), and validation (go-playground/validator) components. Use `go get @latest` for all dependencies. | |||
| 33 | + | ||||
| 34 | + | ## Technical Context | |||
| 35 | + | **User Details**: We need to add all deps using go get @latest | |||
| 36 | + | **Language/Version**: Go (latest compatible with Wails v3-alpha) | |||
| 37 | + | **Primary Dependencies**: Wails v3-alpha, Cobra, Viper, SQLC, go-playground/validator, SQLite driver | |||
| 38 | + | **Storage**: SQLite (local embedded database) | |||
| 39 | + | **Testing**: Go standard testing + testify for enhanced assertions | |||
| 40 | + | **Target Platform**: Linux Wayland (sway, hyprland) - primary focus | |||
| 41 | + | **Project Type**: single (desktop application with CLI + GUI components) | |||
| 42 | + | **Performance Goals**: < 500ms startup time, < 100MB baseline memory | |||
| 43 | + | **Constraints**: Single binary, WebKit2GTK system dependency only | |||
| 44 | + | **Scale/Scope**: Personal productivity tool, local history management (1000+ entries) | |||
| 45 | + | ||||
| 46 | + | ## Constitution Check | |||
| 47 | + | *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* | |||
| 48 | + | ||||
| 49 | + | **Simplicity**: | |||
| 50 | + | - Projects: 1 (single desktop app - dumb-browser) | |||
| 51 | + | - Using framework directly? YES (Wails, Cobra, Viper directly) | |||
| 52 | + | - Single data model? YES (SQLite schema matches Go structs via SQLC) | |||
| 53 | + | - Avoiding patterns? YES (no unnecessary abstractions for initialization) | |||
| 54 | + | ||||
| 55 | + | **Architecture**: | |||
| 56 | + | - EVERY feature as library? YES (CLI, parser, database, browser as separate packages) | |||
| 57 | + | - Libraries planned: cli (cobra commands), db (sqlc queries), parser (URL handling), browser (Wails integration) | |||
| 58 | + | - CLI per library: main CLI with subcommands (--dmenu, history, config) | |||
| 59 | + | - Library docs: llms.txt format will be generated post-implementation | |||
| 60 | + | ||||
| 61 | + | **Testing (NON-NEGOTIABLE)**: | |||
| 62 | + | - RED-GREEN-Refactor cycle enforced? YES (tests for module initialization first) | |||
| 63 | + | - Git commits show tests before implementation? YES (test dependency resolution before implementation) | |||
| 64 | + | - Order: Contract→Integration→E2E→Unit strictly followed? YES | |||
| 65 | + | - Real dependencies used? YES (actual Go modules, SQLite DB) | |||
| 66 | + | - Integration tests for: module loading, dependency compatibility, build success | |||
| 67 | + | - FORBIDDEN: Implementation before test, skipping RED phase | |||
| 68 | + | ||||
| 69 | + | **Observability**: | |||
| 70 | + | - Structured logging included? YES (slog for debugging initialization) | |||
| 71 | + | - Frontend logs → backend? N/A for initialization phase | |||
| 72 | + | - Error context sufficient? YES (proper error chains for dependency failures) | |||
| 73 | + | ||||
| 74 | + | **Versioning**: | |||
| 75 | + | - Version number assigned? YES (v0.1.0 - initial development) | |||
| 76 | + | - BUILD increments on every change? YES (following semantic versioning) | |||
| 77 | + | - Breaking changes handled? N/A for initial setup | |||
| 78 | + | ||||
| 79 | + | ## Project Structure | |||
| 80 | + | ||||
| 81 | + | ### Documentation (this feature) | |||
| 82 | + | ``` | |||
| 83 | + | specs/[###-feature]/ | |||
| 84 | + | ├── plan.md # This file (/plan command output) | |||
| 85 | + | ├── research.md # Phase 0 output (/plan command) | |||
| 86 | + | ├── data-model.md # Phase 1 output (/plan command) | |||
| 87 | + | ├── quickstart.md # Phase 1 output (/plan command) | |||
| 88 | + | ├── contracts/ # Phase 1 output (/plan command) | |||
| 89 | + | └── tasks.md # Phase 2 output (/tasks command - NOT created by /plan) | |||
| 90 | + | ``` | |||
| 91 | + | ||||
| 92 | + | ### Source Code (repository root) | |||
| 93 | + | ``` | |||
| 94 | + | # Option 1: Single project (DEFAULT) | |||
| 95 | + | src/ | |||
| 96 | + | ├── models/ | |||
| 97 | + | ├── services/ | |||
| 98 | + | ├── cli/ | |||
| 99 | + | └── lib/ | |||
| 100 | + | ||||
| 101 | + | tests/ | |||
| 102 | + | ├── contract/ | |||
| 103 | + | ├── integration/ | |||
| 104 | + | └── unit/ | |||
| 105 | + | ||||
| 106 | + | # Option 2: Web application (when "frontend" + "backend" detected) | |||
| 107 | + | backend/ | |||
| 108 | + | ├── src/ | |||
| 109 | + | │ ├── models/ | |||
| 110 | + | │ ├── services/ | |||
| 111 | + | │ └── api/ | |||
| 112 | + | └── tests/ | |||
| 113 | + | ||||
| 114 | + | frontend/ | |||
| 115 | + | ├── src/ | |||
| 116 | + | │ ├── components/ | |||
| 117 | + | │ ├── pages/ | |||
| 118 | + | │ └── services/ | |||
| 119 | + | └── tests/ | |||
| 120 | + | ||||
| 121 | + | # Option 3: Mobile + API (when "iOS/Android" detected) | |||
| 122 | + | api/ | |||
| 123 | + | └── [same as backend above] | |||
| 124 | + | ||||
| 125 | + | ios/ or android/ | |||
| 126 | + | └── [platform-specific structure] | |||
| 127 | + | ``` | |||
| 128 | + | ||||
| 129 | + | **Structure Decision**: Option 1 - Single project (desktop application with CLI and GUI components) | |||
| 130 | + | ||||
| 131 | + | ## Phase 0: Outline & Research | |||
| 132 | + | 1. **Extract unknowns from Technical Context** above: | |||
| 133 | + | - For each NEEDS CLARIFICATION → research task | |||
| 134 | + | - For each dependency → best practices task | |||
| 135 | + | - For each integration → patterns task | |||
| 136 | + | ||||
| 137 | + | 2. **Generate and dispatch research agents**: | |||
| 138 | + | ``` | |||
| 139 | + | For each unknown in Technical Context: | |||
| 140 | + | Task: "Research {unknown} for {feature context}" | |||
| 141 | + | For each technology choice: | |||
| 142 | + | Task: "Find best practices for {tech} in {domain}" | |||
| 143 | + | ``` | |||
| 144 | + | ||||
| 145 | + | 3. **Consolidate findings** in `research.md` using format: | |||
| 146 | + | - Decision: [what was chosen] | |||
| 147 | + | - Rationale: [why chosen] | |||
| 148 | + | - Alternatives considered: [what else evaluated] | |||
| 149 | + | ||||
| 150 | + | **Output**: research.md with all NEEDS CLARIFICATION resolved | |||
| 151 | + | ||||
| 152 | + | ## Phase 1: Design & Contracts | |||
| 153 | + | *Prerequisites: research.md complete* | |||
| 154 | + | ||||
| 155 | + | 1. **Extract entities from feature spec** → `data-model.md`: | |||
| 156 | + | - Entity name, fields, relationships | |||
| 157 | + | - Validation rules from requirements | |||
| 158 | + | - State transitions if applicable | |||
| 159 | + | ||||
| 160 | + | 2. **Generate API contracts** from functional requirements: | |||
| 161 | + | - For each user action → endpoint | |||
| 162 | + | - Use standard REST/GraphQL patterns | |||
| 163 | + | - Output OpenAPI/GraphQL schema to `/contracts/` | |||
| 164 | + | ||||
| 165 | + | 3. **Generate contract tests** from contracts: | |||
| 166 | + | - One test file per endpoint | |||
| 167 | + | - Assert request/response schemas | |||
| 168 | + | - Tests must fail (no implementation yet) | |||
| 169 | + | ||||
| 170 | + | 4. **Extract test scenarios** from user stories: | |||
| 171 | + | - Each story → integration test scenario | |||
| 172 | + | - Quickstart test = story validation steps | |||
| 173 | + | ||||
| 174 | + | 5. **Update agent file incrementally** (O(1) operation): | |||
| 175 | + | - Run `/scripts/update-agent-context.sh [claude|gemini|copilot]` for your AI assistant | |||
| 176 | + | - If exists: Add only NEW tech from current plan | |||
| 177 | + | - Preserve manual additions between markers | |||
| 178 | + | - Update recent changes (keep last 3) | |||
| 179 | + | - Keep under 150 lines for token efficiency | |||
| 180 | + | - Output to repository root | |||
| 181 | + | ||||
| 182 | + | **Output**: data-model.md, /contracts/*, failing tests, quickstart.md, agent-specific file | |||
| 183 | + | ||||
| 184 | + | ## Phase 2: Task Planning Approach | |||
| 185 | + | *This section describes what the /tasks command will do - DO NOT execute during /plan* | |||
| 186 | + | ||||
| 187 | + | **Task Generation Strategy**: | |||
| 188 | + | - Load `/templates/tasks-template.md` as base | |||
| 189 | + | - Generate tasks from Phase 1 design docs (contracts, data model, quickstart) | |||
| 190 | + | - Prioritize CGO-free components first (faster development cycle) | |||
| 191 | + | - Each CLI command contract → contract test + implementation task | |||
| 192 | + | - Module initialization → dependency installation tasks | |||
| 193 | + | - Project structure → directory creation + config generation tasks | |||
| 194 | + | - Integration tests for each success criterion in quickstart | |||
| 195 | + | ||||
| 196 | + | **Ordering Strategy**: | |||
| 197 | + | - TDD order: Tests before implementation | |||
| 198 | + | - CGO-free first: CLI, parser, database (can develop with CGO_ENABLED=0) | |||
| 199 | + | - Wails integration last: Full application build (requires CGO_ENABLED=1) | |||
| 200 | + | - Dependency order: Go module → dependencies → structure → config → verification | |||
| 201 | + | - Mark [P] for parallel execution (independent dependency installations) | |||
| 202 | + | ||||
| 203 | + | **Key Task Categories**: | |||
| 204 | + | 1. **Module Setup Tasks**: go mod init, dependency installation | |||
| 205 | + | 2. **Structure Tasks**: Directory creation, config file generation | |||
| 206 | + | 3. **Verification Tasks**: Build tests, tool availability checks | |||
| 207 | + | 4. **Integration Tasks**: Full quickstart validation | |||
| 208 | + | ||||
| 209 | + | **CGO Optimization**: | |||
| 210 | + | - Most tasks can run with CGO_ENABLED=0 for faster iteration | |||
| 211 | + | - Only final integration tests require CGO_ENABLED=1 | |||
| 212 | + | - Clear separation allows parallel development of CGO-free components | |||
| 213 | + | ||||
| 214 | + | **Estimated Output**: 15-20 numbered, ordered tasks in tasks.md (streamlined for initialization focus) | |||
| 215 | + | ||||
| 216 | + | **IMPORTANT**: This phase is executed by the /tasks command, NOT by /plan | |||
| 217 | + | ||||
| 218 | + | ## Phase 3+: Future Implementation | |||
| 219 | + | *These phases are beyond the scope of the /plan command* | |||
| 220 | + | ||||
| 221 | + | **Phase 3**: Task execution (/tasks command creates tasks.md) | |||
| 222 | + | **Phase 4**: Implementation (execute tasks.md following constitutional principles) | |||
| 223 | + | **Phase 5**: Validation (run tests, execute quickstart.md, performance validation) | |||
| 224 | + | ||||
| 225 | + | ## Complexity Tracking | |||
| 226 | + | *Fill ONLY if Constitution Check has violations that must be justified* | |||
| 227 | + | ||||
| 228 | + | | Violation | Why Needed | Simpler Alternative Rejected Because | | |||
| 229 | + | |-----------|------------|-------------------------------------| | |||
| 230 | + | | [e.g., 4th project] | [current need] | [why 3 projects insufficient] | | |||
| 231 | + | | [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | | |||
| 232 | + | ||||
| 233 | + | ||||
| 234 | + | ## Progress Tracking | |||
| 235 | + | *This checklist is updated during execution flow* | |||
| 236 | + | ||||
| 237 | + | **Phase Status**: | |||
| 238 | + | - [x] Phase 0: Research complete (/plan command) | |||
| 239 | + | - [x] Phase 1: Design complete (/plan command) | |||
| 240 | + | - [x] Phase 2: Task planning complete (/plan command - describe approach only) | |||
| 241 | + | - [ ] Phase 3: Tasks generated (/tasks command) | |||
| 242 | + | - [ ] Phase 4: Implementation complete | |||
| 243 | + | - [ ] Phase 5: Validation passed | |||
| 244 | + | ||||
| 245 | + | **Gate Status**: | |||
| 246 | + | - [x] Initial Constitution Check: PASS | |||
| 247 | + | - [x] Post-Design Constitution Check: PASS | |||
| 248 | + | - [x] All NEEDS CLARIFICATION resolved | |||
| 249 | + | - [x] Complexity deviations documented (none - simplicity maintained) | |||
| 250 | + | ||||
| 251 | + | --- | |||
| 252 | + | *Based on Constitution v2.1.1 - See `/memory/constitution.md`*⏎̸ | |||
A specs/001-init-project/quickstart.md +247 -0
| @@ -0,0 +1,247 @@ | |||
| 1 | + | # Quickstart: Project Initialization | |
| 2 | + | ||
| 3 | + | **Goal**: Validate that project initialization works correctly and all dependencies are properly installed. | |
| 4 | + | ||
| 5 | + | ## Prerequisites Verification | |
| 6 | + | ||
| 7 | + | Before running quickstart, verify system requirements: | |
| 8 | + | ||
| 9 | + | ```bash | |
| 10 | + | # Check Go version (1.25+ required) | |
| 11 | + | go version | |
| 12 | + | # Expected: go version go1.25.x linux/amd64 | |
| 13 | + | ||
| 14 | + | # Check system packages for Wails (Arch Linux) | |
| 15 | + | pacman -Q webkit2gtk gtk3 | |
| 16 | + | # Expected: webkit2gtk-4.0 and gtk3 packages listed | |
| 17 | + | ||
| 18 | + | # For Ubuntu/Debian: | |
| 19 | + | # dpkg -l | grep -E "(webkit2gtk|libgtk-3)" | |
| 20 | + | ||
| 21 | + | # Note: CGO only needed for Wails, not for database layer | |
| 22 | + | ``` | |
| 23 | + | ||
| 24 | + | ## Step 1: Project Initialization | |
| 25 | + | ||
| 26 | + | Navigate to project root and initialize: | |
| 27 | + | ||
| 28 | + | ```bash | |
| 29 | + | cd /home/brice/dev/projects/dumb-browser | |
| 30 | + | ||
| 31 | + | # Initialize with verbose output to see progress | |
| 32 | + | dumb-browser init --verbose | |
| 33 | + | ``` | |
| 34 | + | ||
| 35 | + | **Expected Output**: | |
| 36 | + | ``` | |
| 37 | + | ✓ Initializing Go module: dumb-browser | |
| 38 | + | ✓ Installing CLI dependencies: cobra, viper | |
| 39 | + | ✓ Installing database dependencies: ncruces/go-sqlite3, sqlc | |
| 40 | + | ✓ Installing validation: go-playground/validator | |
| 41 | + | ✓ Installing testing: testify | |
| 42 | + | ✓ Installing Wails v3-alpha... (requires CGO) | |
| 43 | + | ✓ Creating project structure... | |
| 44 | + | ✓ Generating configuration files... | |
| 45 | + | ✓ Verifying installation... | |
| 46 | + | ||
| 47 | + | Project initialized successfully! | |
| 48 | + | ||
| 49 | + | Next steps: | |
| 50 | + | 1. Review generated configs/ | |
| 51 | + | 2. Run: go build ./cmd/dumb-browser | |
| 52 | + | 3. Start development: dumb-browser --help | |
| 53 | + | ``` | |
| 54 | + | ||
| 55 | + | ## Step 2: Verify Installation | |
| 56 | + | ||
| 57 | + | Check that all components are correctly installed: | |
| 58 | + | ||
| 59 | + | ```bash | |
| 60 | + | # Verify project status | |
| 61 | + | dumb-browser init status | |
| 62 | + | ||
| 63 | + | # Expected output: | |
| 64 | + | # Project Status: ✓ Initialized | |
| 65 | + | # Dependencies: ✓ All installed | |
| 66 | + | # Structure: ✓ Complete | |
| 67 | + | # Build Status: ✓ Ready | |
| 68 | + | ``` | |
| 69 | + | ||
| 70 | + | Detailed verification: | |
| 71 | + | ||
| 72 | + | ```bash | |
| 73 | + | # Check go.mod exists and is valid | |
| 74 | + | test -f go.mod && echo "✓ go.mod exists" | |
| 75 | + | grep -q "module dumb-browser" go.mod && echo "✓ Module name correct" | |
| 76 | + | ||
| 77 | + | # Verify dependencies are downloadable | |
| 78 | + | go mod download && echo "✓ Dependencies resolved" | |
| 79 | + | ||
| 80 | + | # Check tools are available | |
| 81 | + | sqlc version && echo "✓ SQLC available" | |
| 82 | + | wails version && echo "✓ Wails available" | |
| 83 | + | ``` | |
| 84 | + | ||
| 85 | + | ## Step 3: Test CGO-Free Components | |
| 86 | + | ||
| 87 | + | Most components can be tested without CGO enabled: | |
| 88 | + | ||
| 89 | + | ```bash | |
| 90 | + | # Test CGO-free database layer | |
| 91 | + | export CGO_ENABLED=0 | |
| 92 | + | go build ./internal/db && echo "✓ Database layer builds CGO-free" | |
| 93 | + | go test ./internal/db && echo "✓ Database tests pass CGO-free" | |
| 94 | + | ||
| 95 | + | # Test CLI components | |
| 96 | + | go build ./internal/cli && echo "✓ CLI builds CGO-free" | |
| 97 | + | go test ./internal/cli && echo "✓ CLI tests pass CGO-free" | |
| 98 | + | ||
| 99 | + | # Test URL parser | |
| 100 | + | go build ./internal/parser && echo "✓ Parser builds CGO-free" | |
| 101 | + | go test ./internal/parser && echo "✓ Parser tests pass CGO-free" | |
| 102 | + | ``` | |
| 103 | + | ||
| 104 | + | ## Step 4: Test Wails Integration (CGO Required) | |
| 105 | + | ||
| 106 | + | Test the full application with Wails: | |
| 107 | + | ||
| 108 | + | ```bash | |
| 109 | + | # Enable CGO for Wails | |
| 110 | + | export CGO_ENABLED=1 | |
| 111 | + | ||
| 112 | + | # Test full application build | |
| 113 | + | go build ./cmd/dumb-browser && echo "✓ Full build successful" | |
| 114 | + | ||
| 115 | + | # Clean up test binary | |
| 116 | + | rm -f dumb-browser | |
| 117 | + | ``` | |
| 118 | + | ||
| 119 | + | ## Step 5: Test Project Structure | |
| 120 | + | ||
| 121 | + | Verify the correct directory structure was created: | |
| 122 | + | ||
| 123 | + | ```bash | |
| 124 | + | # Check main directories exist | |
| 125 | + | test -d cmd && echo "✓ cmd/ directory" | |
| 126 | + | test -d internal && echo "✓ internal/ directory" | |
| 127 | + | test -d migrations && echo "✓ migrations/ directory" | |
| 128 | + | test -d configs && echo "✓ configs/ directory" | |
| 129 | + | test -d tests && echo "✓ tests/ directory" | |
| 130 | + | ||
| 131 | + | # Check internal structure | |
| 132 | + | test -d internal/cli && echo "✓ internal/cli/" | |
| 133 | + | test -d internal/db && echo "✓ internal/db/" | |
| 134 | + | test -d internal/parser && echo "✓ internal/parser/" | |
| 135 | + | test -d internal/browser && echo "✓ internal/browser/" | |
| 136 | + | ``` | |
| 137 | + | ||
| 138 | + | ## Step 6: Test Configuration Generation | |
| 139 | + | ||
| 140 | + | Verify that configuration files were generated correctly: | |
| 141 | + | ||
| 142 | + | ```bash | |
| 143 | + | # Check SQLC configuration | |
| 144 | + | test -f configs/sqlc.yaml && echo "✓ SQLC config exists" | |
| 145 | + | sqlc compile -f configs/sqlc.yaml && echo "✓ SQLC config valid" | |
| 146 | + | ||
| 147 | + | # Check basic project files exist (if generated) | |
| 148 | + | test -f cmd/dumb-browser/main.go && echo "✓ Main entry point exists" | |
| 149 | + | ``` | |
| 150 | + | ||
| 151 | + | ## Step 7: Test Module Dependencies | |
| 152 | + | ||
| 153 | + | Verify the updated SQLite dependency: | |
| 154 | + | ||
| 155 | + | ```bash | |
| 156 | + | # Check ncruces/go-sqlite3 is in go.mod (not mattn) | |
| 157 | + | grep -q "github.com/ncruces/go-sqlite3" go.mod && echo "✓ Using CGO-free SQLite driver" | |
| 158 | + | ! grep -q "github.com/mattn/go-sqlite3" go.mod && echo "✓ Not using CGO SQLite driver" | |
| 159 | + | ||
| 160 | + | # Test that database works CGO-free | |
| 161 | + | export CGO_ENABLED=0 | |
| 162 | + | go run -c "import _ 'github.com/ncruces/go-sqlite3'" 2>/dev/null && echo "✓ SQLite driver loads CGO-free" | |
| 163 | + | ``` | |
| 164 | + | ||
| 165 | + | ## Step 8: Validation Tests | |
| 166 | + | ||
| 167 | + | Run tests with different CGO settings: | |
| 168 | + | ||
| 169 | + | ```bash | |
| 170 | + | # Test CGO-free components | |
| 171 | + | export CGO_ENABLED=0 | |
| 172 | + | go test ./internal/cli ./internal/parser ./internal/db && echo "✓ CGO-free tests pass" | |
| 173 | + | ||
| 174 | + | # Test full application with CGO | |
| 175 | + | export CGO_ENABLED=1 | |
| 176 | + | go test ./... && echo "✓ All tests pass with CGO" | |
| 177 | + | ||
| 178 | + | # Test with race detection (requires CGO) | |
| 179 | + | go test -race ./... && echo "✓ No race conditions detected" | |
| 180 | + | ``` | |
| 181 | + | ||
| 182 | + | ## Troubleshooting Common Issues | |
| 183 | + | ||
| 184 | + | ### Issue: Missing WebKit2GTK (Wails only) | |
| 185 | + | **Symptom**: Wails installation fails with webkit error | |
| 186 | + | **Solution** (Arch Linux): | |
| 187 | + | ```bash | |
| 188 | + | sudo pacman -S webkit2gtk gtk3 | |
| 189 | + | dumb-browser init deps --only=wails | |
| 190 | + | ``` | |
| 191 | + | ||
| 192 | + | ### Issue: CGO disabled for Wails | |
| 193 | + | **Symptom**: Wails build fails with CGO error | |
| 194 | + | **Solution**: | |
| 195 | + | ```bash | |
| 196 | + | export CGO_ENABLED=1 | |
| 197 | + | go build ./cmd/dumb-browser | |
| 198 | + | ``` | |
| 199 | + | ||
| 200 | + | ### Issue: Wrong SQLite driver | |
| 201 | + | **Symptom**: CGO errors from mattn/go-sqlite3 | |
| 202 | + | **Verification**: | |
| 203 | + | ```bash | |
| 204 | + | # Should show ncruces, not mattn | |
| 205 | + | grep sqlite3 go.mod | |
| 206 | + | ``` | |
| 207 | + | ||
| 208 | + | ### Issue: Network timeout | |
| 209 | + | **Symptom**: Dependency download timeouts | |
| 210 | + | **Solution**: | |
| 211 | + | ```bash | |
| 212 | + | go env -w GOPROXY=proxy.golang.org,direct | |
| 213 | + | go env -w GOSUMDB=sum.golang.org | |
| 214 | + | dumb-browser init deps | |
| 215 | + | ``` | |
| 216 | + | ||
| 217 | + | ## Success Criteria | |
| 218 | + | ||
| 219 | + | After completing all steps, you should have: | |
| 220 | + | ||
| 221 | + | - ✅ Valid Go module with CGO-free SQLite driver (`ncruces/go-sqlite3`) | |
| 222 | + | - ✅ All CLI, parser, database components buildable with `CGO_ENABLED=0` | |
| 223 | + | - ✅ Full application buildable with `CGO_ENABLED=1` (for Wails) | |
| 224 | + | - ✅ Project directory structure created per constitution | |
| 225 | + | - ✅ Configuration files generated and valid | |
| 226 | + | - ✅ All tools (sqlc, wails) available and functional | |
| 227 | + | - ✅ Clean separation: CGO only needed for browser layer | |
| 228 | + | ||
| 229 | + | ## Development Workflow Benefits | |
| 230 | + | ||
| 231 | + | This CGO strategy provides several advantages: | |
| 232 | + | ||
| 233 | + | 1. **Fast development cycle**: Most development can happen CGO-free | |
| 234 | + | 2. **Better testing**: Database and CLI logic testable without CGO setup | |
| 235 | + | 3. **Cleaner builds**: Only final integration requires CGO | |
| 236 | + | 4. **Better performance**: `ncruces/go-sqlite3` is faster than `mattn/go-sqlite3` | |
| 237 | + | ||
| 238 | + | ## Next Steps | |
| 239 | + | ||
| 240 | + | After successful initialization: | |
| 241 | + | ||
| 242 | + | 1. **Start with CGO-free components**: CLI structure, URL parsing, database schema | |
| 243 | + | 2. **Test incrementally**: Each component works independently | |
| 244 | + | 3. **Integrate with Wails last**: Final step requires CGO for browser integration | |
| 245 | + | 4. **Development workflow**: Most work can be done with `CGO_ENABLED=0` | |
| 246 | + | ||
| 247 | + | The project is now ready for feature development with optimal CGO separation.⏎̸ | |
| @@ -0,0 +1,247 @@ | |||||
| 1 | + | # Quickstart: Project Initialization | |||
| 2 | + | ||||
| 3 | + | **Goal**: Validate that project initialization works correctly and all dependencies are properly installed. | |||
| 4 | + | ||||
| 5 | + | ## Prerequisites Verification | |||
| 6 | + | ||||
| 7 | + | Before running quickstart, verify system requirements: | |||
| 8 | + | ||||
| 9 | + | ```bash | |||
| 10 | + | # Check Go version (1.25+ required) | |||
| 11 | + | go version | |||
| 12 | + | # Expected: go version go1.25.x linux/amd64 | |||
| 13 | + | ||||
| 14 | + | # Check system packages for Wails (Arch Linux) | |||
| 15 | + | pacman -Q webkit2gtk gtk3 | |||
| 16 | + | # Expected: webkit2gtk-4.0 and gtk3 packages listed | |||
| 17 | + | ||||
| 18 | + | # For Ubuntu/Debian: | |||
| 19 | + | # dpkg -l | grep -E "(webkit2gtk|libgtk-3)" | |||
| 20 | + | ||||
| 21 | + | # Note: CGO only needed for Wails, not for database layer | |||
| 22 | + | ``` | |||
| 23 | + | ||||
| 24 | + | ## Step 1: Project Initialization | |||
| 25 | + | ||||
| 26 | + | Navigate to project root and initialize: | |||
| 27 | + | ||||
| 28 | + | ```bash | |||
| 29 | + | cd /home/brice/dev/projects/dumb-browser | |||
| 30 | + | ||||
| 31 | + | # Initialize with verbose output to see progress | |||
| 32 | + | dumb-browser init --verbose | |||
| 33 | + | ``` | |||
| 34 | + | ||||
| 35 | + | **Expected Output**: | |||
| 36 | + | ``` | |||
| 37 | + | ✓ Initializing Go module: dumb-browser | |||
| 38 | + | ✓ Installing CLI dependencies: cobra, viper | |||
| 39 | + | ✓ Installing database dependencies: ncruces/go-sqlite3, sqlc | |||
| 40 | + | ✓ Installing validation: go-playground/validator | |||
| 41 | + | ✓ Installing testing: testify | |||
| 42 | + | ✓ Installing Wails v3-alpha... (requires CGO) | |||
| 43 | + | ✓ Creating project structure... | |||
| 44 | + | ✓ Generating configuration files... | |||
| 45 | + | ✓ Verifying installation... | |||
| 46 | + | ||||
| 47 | + | Project initialized successfully! | |||
| 48 | + | ||||
| 49 | + | Next steps: | |||
| 50 | + | 1. Review generated configs/ | |||
| 51 | + | 2. Run: go build ./cmd/dumb-browser | |||
| 52 | + | 3. Start development: dumb-browser --help | |||
| 53 | + | ``` | |||
| 54 | + | ||||
| 55 | + | ## Step 2: Verify Installation | |||
| 56 | + | ||||
| 57 | + | Check that all components are correctly installed: | |||
| 58 | + | ||||
| 59 | + | ```bash | |||
| 60 | + | # Verify project status | |||
| 61 | + | dumb-browser init status | |||
| 62 | + | ||||
| 63 | + | # Expected output: | |||
| 64 | + | # Project Status: ✓ Initialized | |||
| 65 | + | # Dependencies: ✓ All installed | |||
| 66 | + | # Structure: ✓ Complete | |||
| 67 | + | # Build Status: ✓ Ready | |||
| 68 | + | ``` | |||
| 69 | + | ||||
| 70 | + | Detailed verification: | |||
| 71 | + | ||||
| 72 | + | ```bash | |||
| 73 | + | # Check go.mod exists and is valid | |||
| 74 | + | test -f go.mod && echo "✓ go.mod exists" | |||
| 75 | + | grep -q "module dumb-browser" go.mod && echo "✓ Module name correct" | |||
| 76 | + | ||||
| 77 | + | # Verify dependencies are downloadable | |||
| 78 | + | go mod download && echo "✓ Dependencies resolved" | |||
| 79 | + | ||||
| 80 | + | # Check tools are available | |||
| 81 | + | sqlc version && echo "✓ SQLC available" | |||
| 82 | + | wails version && echo "✓ Wails available" | |||
| 83 | + | ``` | |||
| 84 | + | ||||
| 85 | + | ## Step 3: Test CGO-Free Components | |||
| 86 | + | ||||
| 87 | + | Most components can be tested without CGO enabled: | |||
| 88 | + | ||||
| 89 | + | ```bash | |||
| 90 | + | # Test CGO-free database layer | |||
| 91 | + | export CGO_ENABLED=0 | |||
| 92 | + | go build ./internal/db && echo "✓ Database layer builds CGO-free" | |||
| 93 | + | go test ./internal/db && echo "✓ Database tests pass CGO-free" | |||
| 94 | + | ||||
| 95 | + | # Test CLI components | |||
| 96 | + | go build ./internal/cli && echo "✓ CLI builds CGO-free" | |||
| 97 | + | go test ./internal/cli && echo "✓ CLI tests pass CGO-free" | |||
| 98 | + | ||||
| 99 | + | # Test URL parser | |||
| 100 | + | go build ./internal/parser && echo "✓ Parser builds CGO-free" | |||
| 101 | + | go test ./internal/parser && echo "✓ Parser tests pass CGO-free" | |||
| 102 | + | ``` | |||
| 103 | + | ||||
| 104 | + | ## Step 4: Test Wails Integration (CGO Required) | |||
| 105 | + | ||||
| 106 | + | Test the full application with Wails: | |||
| 107 | + | ||||
| 108 | + | ```bash | |||
| 109 | + | # Enable CGO for Wails | |||
| 110 | + | export CGO_ENABLED=1 | |||
| 111 | + | ||||
| 112 | + | # Test full application build | |||
| 113 | + | go build ./cmd/dumb-browser && echo "✓ Full build successful" | |||
| 114 | + | ||||
| 115 | + | # Clean up test binary | |||
| 116 | + | rm -f dumb-browser | |||
| 117 | + | ``` | |||
| 118 | + | ||||
| 119 | + | ## Step 5: Test Project Structure | |||
| 120 | + | ||||
| 121 | + | Verify the correct directory structure was created: | |||
| 122 | + | ||||
| 123 | + | ```bash | |||
| 124 | + | # Check main directories exist | |||
| 125 | + | test -d cmd && echo "✓ cmd/ directory" | |||
| 126 | + | test -d internal && echo "✓ internal/ directory" | |||
| 127 | + | test -d migrations && echo "✓ migrations/ directory" | |||
| 128 | + | test -d configs && echo "✓ configs/ directory" | |||
| 129 | + | test -d tests && echo "✓ tests/ directory" | |||
| 130 | + | ||||
| 131 | + | # Check internal structure | |||
| 132 | + | test -d internal/cli && echo "✓ internal/cli/" | |||
| 133 | + | test -d internal/db && echo "✓ internal/db/" | |||
| 134 | + | test -d internal/parser && echo "✓ internal/parser/" | |||
| 135 | + | test -d internal/browser && echo "✓ internal/browser/" | |||
| 136 | + | ``` | |||
| 137 | + | ||||
| 138 | + | ## Step 6: Test Configuration Generation | |||
| 139 | + | ||||
| 140 | + | Verify that configuration files were generated correctly: | |||
| 141 | + | ||||
| 142 | + | ```bash | |||
| 143 | + | # Check SQLC configuration | |||
| 144 | + | test -f configs/sqlc.yaml && echo "✓ SQLC config exists" | |||
| 145 | + | sqlc compile -f configs/sqlc.yaml && echo "✓ SQLC config valid" | |||
| 146 | + | ||||
| 147 | + | # Check basic project files exist (if generated) | |||
| 148 | + | test -f cmd/dumb-browser/main.go && echo "✓ Main entry point exists" | |||
| 149 | + | ``` | |||
| 150 | + | ||||
| 151 | + | ## Step 7: Test Module Dependencies | |||
| 152 | + | ||||
| 153 | + | Verify the updated SQLite dependency: | |||
| 154 | + | ||||
| 155 | + | ```bash | |||
| 156 | + | # Check ncruces/go-sqlite3 is in go.mod (not mattn) | |||
| 157 | + | grep -q "github.com/ncruces/go-sqlite3" go.mod && echo "✓ Using CGO-free SQLite driver" | |||
| 158 | + | ! grep -q "github.com/mattn/go-sqlite3" go.mod && echo "✓ Not using CGO SQLite driver" | |||
| 159 | + | ||||
| 160 | + | # Test that database works CGO-free | |||
| 161 | + | export CGO_ENABLED=0 | |||
| 162 | + | go run -c "import _ 'github.com/ncruces/go-sqlite3'" 2>/dev/null && echo "✓ SQLite driver loads CGO-free" | |||
| 163 | + | ``` | |||
| 164 | + | ||||
| 165 | + | ## Step 8: Validation Tests | |||
| 166 | + | ||||
| 167 | + | Run tests with different CGO settings: | |||
| 168 | + | ||||
| 169 | + | ```bash | |||
| 170 | + | # Test CGO-free components | |||
| 171 | + | export CGO_ENABLED=0 | |||
| 172 | + | go test ./internal/cli ./internal/parser ./internal/db && echo "✓ CGO-free tests pass" | |||
| 173 | + | ||||
| 174 | + | # Test full application with CGO | |||
| 175 | + | export CGO_ENABLED=1 | |||
| 176 | + | go test ./... && echo "✓ All tests pass with CGO" | |||
| 177 | + | ||||
| 178 | + | # Test with race detection (requires CGO) | |||
| 179 | + | go test -race ./... && echo "✓ No race conditions detected" | |||
| 180 | + | ``` | |||
| 181 | + | ||||
| 182 | + | ## Troubleshooting Common Issues | |||
| 183 | + | ||||
| 184 | + | ### Issue: Missing WebKit2GTK (Wails only) | |||
| 185 | + | **Symptom**: Wails installation fails with webkit error | |||
| 186 | + | **Solution** (Arch Linux): | |||
| 187 | + | ```bash | |||
| 188 | + | sudo pacman -S webkit2gtk gtk3 | |||
| 189 | + | dumb-browser init deps --only=wails | |||
| 190 | + | ``` | |||
| 191 | + | ||||
| 192 | + | ### Issue: CGO disabled for Wails | |||
| 193 | + | **Symptom**: Wails build fails with CGO error | |||
| 194 | + | **Solution**: | |||
| 195 | + | ```bash | |||
| 196 | + | export CGO_ENABLED=1 | |||
| 197 | + | go build ./cmd/dumb-browser | |||
| 198 | + | ``` | |||
| 199 | + | ||||
| 200 | + | ### Issue: Wrong SQLite driver | |||
| 201 | + | **Symptom**: CGO errors from mattn/go-sqlite3 | |||
| 202 | + | **Verification**: | |||
| 203 | + | ```bash | |||
| 204 | + | # Should show ncruces, not mattn | |||
| 205 | + | grep sqlite3 go.mod | |||
| 206 | + | ``` | |||
| 207 | + | ||||
| 208 | + | ### Issue: Network timeout | |||
| 209 | + | **Symptom**: Dependency download timeouts | |||
| 210 | + | **Solution**: | |||
| 211 | + | ```bash | |||
| 212 | + | go env -w GOPROXY=proxy.golang.org,direct | |||
| 213 | + | go env -w GOSUMDB=sum.golang.org | |||
| 214 | + | dumb-browser init deps | |||
| 215 | + | ``` | |||
| 216 | + | ||||
| 217 | + | ## Success Criteria | |||
| 218 | + | ||||
| 219 | + | After completing all steps, you should have: | |||
| 220 | + | ||||
| 221 | + | - ✅ Valid Go module with CGO-free SQLite driver (`ncruces/go-sqlite3`) | |||
| 222 | + | - ✅ All CLI, parser, database components buildable with `CGO_ENABLED=0` | |||
| 223 | + | - ✅ Full application buildable with `CGO_ENABLED=1` (for Wails) | |||
| 224 | + | - ✅ Project directory structure created per constitution | |||
| 225 | + | - ✅ Configuration files generated and valid | |||
| 226 | + | - ✅ All tools (sqlc, wails) available and functional | |||
| 227 | + | - ✅ Clean separation: CGO only needed for browser layer | |||
| 228 | + | ||||
| 229 | + | ## Development Workflow Benefits | |||
| 230 | + | ||||
| 231 | + | This CGO strategy provides several advantages: | |||
| 232 | + | ||||
| 233 | + | 1. **Fast development cycle**: Most development can happen CGO-free | |||
| 234 | + | 2. **Better testing**: Database and CLI logic testable without CGO setup | |||
| 235 | + | 3. **Cleaner builds**: Only final integration requires CGO | |||
| 236 | + | 4. **Better performance**: `ncruces/go-sqlite3` is faster than `mattn/go-sqlite3` | |||
| 237 | + | ||||
| 238 | + | ## Next Steps | |||
| 239 | + | ||||
| 240 | + | After successful initialization: | |||
| 241 | + | ||||
| 242 | + | 1. **Start with CGO-free components**: CLI structure, URL parsing, database schema | |||
| 243 | + | 2. **Test incrementally**: Each component works independently | |||
| 244 | + | 3. **Integrate with Wails last**: Final step requires CGO for browser integration | |||
| 245 | + | 4. **Development workflow**: Most work can be done with `CGO_ENABLED=0` | |||
| 246 | + | ||||
| 247 | + | The project is now ready for feature development with optimal CGO separation.⏎̸ | |||
A specs/001-init-project/research.md +176 -0
| @@ -0,0 +1,176 @@ | |||
| 1 | + | # Research: Project Initialization Dependencies | |
| 2 | + | ||
| 3 | + | **Date**: 2025-01-09 | |
| 4 | + | **Context**: Resolve technical unknowns for dumb-browser project initialization | |
| 5 | + | ||
| 6 | + | ## Research Questions Resolved | |
| 7 | + | ||
| 8 | + | ### 1. Go Module Initialization | |
| 9 | + | **Decision**: Use `go mod init dumb-browser` | |
| 10 | + | **Rationale**: | |
| 11 | + | - Simple module name matching the binary name | |
| 12 | + | - Local development focus (no public import path needed) | |
| 13 | + | - Follows Go module naming conventions | |
| 14 | + | ||
| 15 | + | **Alternatives considered**: | |
| 16 | + | - `github.com/user/dumb-browser` - rejected (unnecessary complexity for local tool) | |
| 17 | + | - `dumb-browser/v1` - rejected (premature versioning) | |
| 18 | + | ||
| 19 | + | ### 2. Wails v3-Alpha Compatibility | |
| 20 | + | **Decision**: Use Wails v3.0.0-alpha.28 (latest available) | |
| 21 | + | **Rationale**: | |
| 22 | + | - Constitution specifically requires v3-alpha | |
| 23 | + | - Alpha version provides newest WebKit2GTK integration | |
| 24 | + | - Active development branch with Wayland improvements | |
| 25 | + | - Breaking changes acceptable for new project | |
| 26 | + | ||
| 27 | + | **Alternatives considered**: | |
| 28 | + | - Wails v2 stable - rejected (constitution mandates v3-alpha) | |
| 29 | + | - Wait for v3 stable - rejected (delays development unnecessarily) | |
| 30 | + | ||
| 31 | + | **Integration approach**: | |
| 32 | + | ```bash | |
| 33 | + | go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28 | |
| 34 | + | ``` | |
| 35 | + | ||
| 36 | + | ### 3. CLI Framework Selection | |
| 37 | + | **Decision**: Cobra v1.8+ with Viper v1.18+ | |
| 38 | + | **Rationale**: | |
| 39 | + | - Constitution requirement: "Cobra + Viper for configuration" | |
| 40 | + | - Mature, stable libraries with excellent Go ecosystem integration | |
| 41 | + | - Perfect for dmenu/rofi integration via stdin/stdout | |
| 42 | + | - Built-in flag parsing and configuration management | |
| 43 | + | ||
| 44 | + | **Key packages**: | |
| 45 | + | - `github.com/spf13/cobra@latest` | |
| 46 | + | - `github.com/spf13/viper@latest` | |
| 47 | + | ||
| 48 | + | ### 4. Database Stack | |
| 49 | + | **Decision**: SQLite with ncruces/go-sqlite3 (CGO-free) + SQLC v1.25+ | |
| 50 | + | **Rationale**: | |
| 51 | + | - Constitution requirement: "SQLite + SQLC for type-safe SQL" | |
| 52 | + | - `github.com/ncruces/go-sqlite3` is CGO-free (better performance, fewer build issues) | |
| 53 | + | - Only Wails needs CGO, not database layer - cleaner separation | |
| 54 | + | - SQLC generates type-safe Go code from SQL schemas | |
| 55 | + | - Perfect for local history storage | |
| 56 | + | ||
| 57 | + | **Key packages**: | |
| 58 | + | - `github.com/ncruces/go-sqlite3@latest` (CGO-free SQLite driver) | |
| 59 | + | - Install SQLC CLI tool: `go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest` | |
| 60 | + | ||
| 61 | + | **Alternatives considered**: | |
| 62 | + | - `github.com/mattn/go-sqlite3` - rejected (requires CGO unnecessarily) | |
| 63 | + | - Pure Go implementations - rejected (ncruces is the modern standard) | |
| 64 | + | ||
| 65 | + | ### 5. Input Validation | |
| 66 | + | **Decision**: go-playground/validator v10.16+ | |
| 67 | + | **Rationale**: | |
| 68 | + | - Constitution requirement | |
| 69 | + | - Industry standard for Go struct validation | |
| 70 | + | - URL validation capabilities for browser input | |
| 71 | + | - Tag-based validation (clean code) | |
| 72 | + | ||
| 73 | + | **Key package**: | |
| 74 | + | - `github.com/go-playground/validator/v10@latest` | |
| 75 | + | ||
| 76 | + | ### 6. Testing Framework | |
| 77 | + | **Decision**: Standard Go testing + testify v1.8+ | |
| 78 | + | **Rationale**: | |
| 79 | + | - Standard library first approach (constitution: simplicity) | |
| 80 | + | - testify for better assertions and test organization | |
| 81 | + | - No need for heavyweight testing frameworks | |
| 82 | + | ||
| 83 | + | **Key package**: | |
| 84 | + | - `github.com/stretchr/testify@latest` | |
| 85 | + | ||
| 86 | + | ### 7. Project Directory Structure | |
| 87 | + | **Decision**: Follow constitution implementation order | |
| 88 | + | ``` | |
| 89 | + | / | |
| 90 | + | ├── cmd/ # CLI entry point | |
| 91 | + | ├── internal/ | |
| 92 | + | │ ├── cli/ # Cobra commands | |
| 93 | + | │ ├── db/ # SQLC generated code + migrations | |
| 94 | + | │ ├── parser/ # URL parsing logic | |
| 95 | + | │ └── browser/ # Wails integration | |
| 96 | + | ├── migrations/ # SQL schema files | |
| 97 | + | ├── configs/ # Configuration files (SQLC, Wails) | |
| 98 | + | └── tests/ # Integration tests | |
| 99 | + | ``` | |
| 100 | + | ||
| 101 | + | **Rationale**: | |
| 102 | + | - `internal/` prevents external imports (Go convention) | |
| 103 | + | - Matches constitution implementation order | |
| 104 | + | - Separates concerns clearly | |
| 105 | + | - Easy to test individual components | |
| 106 | + | ||
| 107 | + | ### 8. Build Configuration | |
| 108 | + | **Decision**: Standard Go build with Wails embedding | |
| 109 | + | **Rationale**: | |
| 110 | + | - Single binary requirement from constitution | |
| 111 | + | - Wails handles frontend asset embedding | |
| 112 | + | - Standard go build for CLI-only functionality | |
| 113 | + | ||
| 114 | + | ## Dependency Installation Order | |
| 115 | + | ||
| 116 | + | Based on research, the installation sequence should be: | |
| 117 | + | ||
| 118 | + | 1. **Initialize Go module** | |
| 119 | + | ```bash | |
| 120 | + | go mod init dumb-browser | |
| 121 | + | ``` | |
| 122 | + | ||
| 123 | + | 2. **Install CLI dependencies** | |
| 124 | + | ```bash | |
| 125 | + | go get github.com/spf13/cobra@latest | |
| 126 | + | go get github.com/spf13/viper@latest | |
| 127 | + | ``` | |
| 128 | + | ||
| 129 | + | 3. **Install database dependencies** | |
| 130 | + | ```bash | |
| 131 | + | go get github.com/ncruces/go-sqlite3@latest | |
| 132 | + | go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest | |
| 133 | + | ``` | |
| 134 | + | ||
| 135 | + | 4. **Install validation** | |
| 136 | + | ```bash | |
| 137 | + | go get github.com/go-playground/validator/v10@latest | |
| 138 | + | ``` | |
| 139 | + | ||
| 140 | + | 5. **Install testing tools** | |
| 141 | + | ```bash | |
| 142 | + | go get github.com/stretchr/testify@latest | |
| 143 | + | ``` | |
| 144 | + | ||
| 145 | + | 6. **Install Wails (last - most complex)** | |
| 146 | + | ```bash | |
| 147 | + | go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28 | |
| 148 | + | # Wails will handle its own module dependencies during init | |
| 149 | + | ``` | |
| 150 | + | ||
| 151 | + | ## Risk Assessment | |
| 152 | + | ||
| 153 | + | **Low Risk**: | |
| 154 | + | - Standard Go dependencies (Cobra, Viper, SQLite) | |
| 155 | + | - Well-established patterns | |
| 156 | + | ||
| 157 | + | **Medium Risk**: | |
| 158 | + | - Wails v3-alpha stability (alpha software) | |
| 159 | + | - WebKit2GTK system dependency availability | |
| 160 | + | - CGO requirement for Wails (but not for database layer) | |
| 161 | + | ||
| 162 | + | **Mitigation**: | |
| 163 | + | - Test Wails installation immediately after dependency setup | |
| 164 | + | - Verify WebKit2GTK availability in integration tests | |
| 165 | + | - Document CGO requirement clearly (only for final Wails build) | |
| 166 | + | - Database layer can be developed/tested CGO-free independently | |
| 167 | + | ||
| 168 | + | ## Next Phase Requirements | |
| 169 | + | ||
| 170 | + | All technical unknowns resolved. Phase 1 can proceed with: | |
| 171 | + | - Data model design (SQLite schema) | |
| 172 | + | - Contract definitions (CLI commands) | |
| 173 | + | - Integration test scenarios | |
| 174 | + | - Configuration file generation | |
| 175 | + | ||
| 176 | + | **Status**: ✅ Complete - All NEEDS CLARIFICATION items resolved⏎̸ | |
| @@ -0,0 +1,176 @@ | |||||
| 1 | + | # Research: Project Initialization Dependencies | |||
| 2 | + | ||||
| 3 | + | **Date**: 2025-01-09 | |||
| 4 | + | **Context**: Resolve technical unknowns for dumb-browser project initialization | |||
| 5 | + | ||||
| 6 | + | ## Research Questions Resolved | |||
| 7 | + | ||||
| 8 | + | ### 1. Go Module Initialization | |||
| 9 | + | **Decision**: Use `go mod init dumb-browser` | |||
| 10 | + | **Rationale**: | |||
| 11 | + | - Simple module name matching the binary name | |||
| 12 | + | - Local development focus (no public import path needed) | |||
| 13 | + | - Follows Go module naming conventions | |||
| 14 | + | ||||
| 15 | + | **Alternatives considered**: | |||
| 16 | + | - `github.com/user/dumb-browser` - rejected (unnecessary complexity for local tool) | |||
| 17 | + | - `dumb-browser/v1` - rejected (premature versioning) | |||
| 18 | + | ||||
| 19 | + | ### 2. Wails v3-Alpha Compatibility | |||
| 20 | + | **Decision**: Use Wails v3.0.0-alpha.28 (latest available) | |||
| 21 | + | **Rationale**: | |||
| 22 | + | - Constitution specifically requires v3-alpha | |||
| 23 | + | - Alpha version provides newest WebKit2GTK integration | |||
| 24 | + | - Active development branch with Wayland improvements | |||
| 25 | + | - Breaking changes acceptable for new project | |||
| 26 | + | ||||
| 27 | + | **Alternatives considered**: | |||
| 28 | + | - Wails v2 stable - rejected (constitution mandates v3-alpha) | |||
| 29 | + | - Wait for v3 stable - rejected (delays development unnecessarily) | |||
| 30 | + | ||||
| 31 | + | **Integration approach**: | |||
| 32 | + | ```bash | |||
| 33 | + | go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28 | |||
| 34 | + | ``` | |||
| 35 | + | ||||
| 36 | + | ### 3. CLI Framework Selection | |||
| 37 | + | **Decision**: Cobra v1.8+ with Viper v1.18+ | |||
| 38 | + | **Rationale**: | |||
| 39 | + | - Constitution requirement: "Cobra + Viper for configuration" | |||
| 40 | + | - Mature, stable libraries with excellent Go ecosystem integration | |||
| 41 | + | - Perfect for dmenu/rofi integration via stdin/stdout | |||
| 42 | + | - Built-in flag parsing and configuration management | |||
| 43 | + | ||||
| 44 | + | **Key packages**: | |||
| 45 | + | - `github.com/spf13/cobra@latest` | |||
| 46 | + | - `github.com/spf13/viper@latest` | |||
| 47 | + | ||||
| 48 | + | ### 4. Database Stack | |||
| 49 | + | **Decision**: SQLite with ncruces/go-sqlite3 (CGO-free) + SQLC v1.25+ | |||
| 50 | + | **Rationale**: | |||
| 51 | + | - Constitution requirement: "SQLite + SQLC for type-safe SQL" | |||
| 52 | + | - `github.com/ncruces/go-sqlite3` is CGO-free (better performance, fewer build issues) | |||
| 53 | + | - Only Wails needs CGO, not database layer - cleaner separation | |||
| 54 | + | - SQLC generates type-safe Go code from SQL schemas | |||
| 55 | + | - Perfect for local history storage | |||
| 56 | + | ||||
| 57 | + | **Key packages**: | |||
| 58 | + | - `github.com/ncruces/go-sqlite3@latest` (CGO-free SQLite driver) | |||
| 59 | + | - Install SQLC CLI tool: `go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest` | |||
| 60 | + | ||||
| 61 | + | **Alternatives considered**: | |||
| 62 | + | - `github.com/mattn/go-sqlite3` - rejected (requires CGO unnecessarily) | |||
| 63 | + | - Pure Go implementations - rejected (ncruces is the modern standard) | |||
| 64 | + | ||||
| 65 | + | ### 5. Input Validation | |||
| 66 | + | **Decision**: go-playground/validator v10.16+ | |||
| 67 | + | **Rationale**: | |||
| 68 | + | - Constitution requirement | |||
| 69 | + | - Industry standard for Go struct validation | |||
| 70 | + | - URL validation capabilities for browser input | |||
| 71 | + | - Tag-based validation (clean code) | |||
| 72 | + | ||||
| 73 | + | **Key package**: | |||
| 74 | + | - `github.com/go-playground/validator/v10@latest` | |||
| 75 | + | ||||
| 76 | + | ### 6. Testing Framework | |||
| 77 | + | **Decision**: Standard Go testing + testify v1.8+ | |||
| 78 | + | **Rationale**: | |||
| 79 | + | - Standard library first approach (constitution: simplicity) | |||
| 80 | + | - testify for better assertions and test organization | |||
| 81 | + | - No need for heavyweight testing frameworks | |||
| 82 | + | ||||
| 83 | + | **Key package**: | |||
| 84 | + | - `github.com/stretchr/testify@latest` | |||
| 85 | + | ||||
| 86 | + | ### 7. Project Directory Structure | |||
| 87 | + | **Decision**: Follow constitution implementation order | |||
| 88 | + | ``` | |||
| 89 | + | / | |||
| 90 | + | ├── cmd/ # CLI entry point | |||
| 91 | + | ├── internal/ | |||
| 92 | + | │ ├── cli/ # Cobra commands | |||
| 93 | + | │ ├── db/ # SQLC generated code + migrations | |||
| 94 | + | │ ├── parser/ # URL parsing logic | |||
| 95 | + | │ └── browser/ # Wails integration | |||
| 96 | + | ├── migrations/ # SQL schema files | |||
| 97 | + | ├── configs/ # Configuration files (SQLC, Wails) | |||
| 98 | + | └── tests/ # Integration tests | |||
| 99 | + | ``` | |||
| 100 | + | ||||
| 101 | + | **Rationale**: | |||
| 102 | + | - `internal/` prevents external imports (Go convention) | |||
| 103 | + | - Matches constitution implementation order | |||
| 104 | + | - Separates concerns clearly | |||
| 105 | + | - Easy to test individual components | |||
| 106 | + | ||||
| 107 | + | ### 8. Build Configuration | |||
| 108 | + | **Decision**: Standard Go build with Wails embedding | |||
| 109 | + | **Rationale**: | |||
| 110 | + | - Single binary requirement from constitution | |||
| 111 | + | - Wails handles frontend asset embedding | |||
| 112 | + | - Standard go build for CLI-only functionality | |||
| 113 | + | ||||
| 114 | + | ## Dependency Installation Order | |||
| 115 | + | ||||
| 116 | + | Based on research, the installation sequence should be: | |||
| 117 | + | ||||
| 118 | + | 1. **Initialize Go module** | |||
| 119 | + | ```bash | |||
| 120 | + | go mod init dumb-browser | |||
| 121 | + | ``` | |||
| 122 | + | ||||
| 123 | + | 2. **Install CLI dependencies** | |||
| 124 | + | ```bash | |||
| 125 | + | go get github.com/spf13/cobra@latest | |||
| 126 | + | go get github.com/spf13/viper@latest | |||
| 127 | + | ``` | |||
| 128 | + | ||||
| 129 | + | 3. **Install database dependencies** | |||
| 130 | + | ```bash | |||
| 131 | + | go get github.com/ncruces/go-sqlite3@latest | |||
| 132 | + | go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest | |||
| 133 | + | ``` | |||
| 134 | + | ||||
| 135 | + | 4. **Install validation** | |||
| 136 | + | ```bash | |||
| 137 | + | go get github.com/go-playground/validator/v10@latest | |||
| 138 | + | ``` | |||
| 139 | + | ||||
| 140 | + | 5. **Install testing tools** | |||
| 141 | + | ```bash | |||
| 142 | + | go get github.com/stretchr/testify@latest | |||
| 143 | + | ``` | |||
| 144 | + | ||||
| 145 | + | 6. **Install Wails (last - most complex)** | |||
| 146 | + | ```bash | |||
| 147 | + | go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28 | |||
| 148 | + | # Wails will handle its own module dependencies during init | |||
| 149 | + | ``` | |||
| 150 | + | ||||
| 151 | + | ## Risk Assessment | |||
| 152 | + | ||||
| 153 | + | **Low Risk**: | |||
| 154 | + | - Standard Go dependencies (Cobra, Viper, SQLite) | |||
| 155 | + | - Well-established patterns | |||
| 156 | + | ||||
| 157 | + | **Medium Risk**: | |||
| 158 | + | - Wails v3-alpha stability (alpha software) | |||
| 159 | + | - WebKit2GTK system dependency availability | |||
| 160 | + | - CGO requirement for Wails (but not for database layer) | |||
| 161 | + | ||||
| 162 | + | **Mitigation**: | |||
| 163 | + | - Test Wails installation immediately after dependency setup | |||
| 164 | + | - Verify WebKit2GTK availability in integration tests | |||
| 165 | + | - Document CGO requirement clearly (only for final Wails build) | |||
| 166 | + | - Database layer can be developed/tested CGO-free independently | |||
| 167 | + | ||||
| 168 | + | ## Next Phase Requirements | |||
| 169 | + | ||||
| 170 | + | All technical unknowns resolved. Phase 1 can proceed with: | |||
| 171 | + | - Data model design (SQLite schema) | |||
| 172 | + | - Contract definitions (CLI commands) | |||
| 173 | + | - Integration test scenarios | |||
| 174 | + | - Configuration file generation | |||
| 175 | + | ||||
| 176 | + | **Status**: ✅ Complete - All NEEDS CLARIFICATION items resolved⏎̸ | |||
A specs/001-init-project/spec.md +103 -0
| @@ -0,0 +1,103 @@ | |||
| 1 | + | # Feature Specification: Project Initialization with Dependencies | |
| 2 | + | ||
| 3 | + | **Feature Branch**: `001-init-project` | |
| 4 | + | **Created**: 2025-01-09 | |
| 5 | + | **Status**: Draft | |
| 6 | + | **Input**: User description: "Lets init the project adding all deps" | |
| 7 | + | ||
| 8 | + | ## Execution Flow (main) | |
| 9 | + | ``` | |
| 10 | + | 1. Parse user description from Input | |
| 11 | + | → "Initialize project with all required dependencies" | |
| 12 | + | 2. Extract key concepts from description | |
| 13 | + | → Actors: developer, build system | |
| 14 | + | → Actions: initialize, add dependencies, configure | |
| 15 | + | → Data: project structure, dependency management | |
| 16 | + | → Constraints: follow constitution requirements | |
| 17 | + | 3. For each unclear aspect: | |
| 18 | + | → No major ambiguities - project structure defined in constitution | |
| 19 | + | 4. Fill User Scenarios & Testing section | |
| 20 | + | → Clear flow: developer initializes → dependencies installed → project ready | |
| 21 | + | 5. Generate Functional Requirements | |
| 22 | + | → Each requirement testable through build/run verification | |
| 23 | + | 6. Identify Key Entities: Go modules, dependencies, configuration files | |
| 24 | + | 7. Run Review Checklist | |
| 25 | + | → No [NEEDS CLARIFICATION] markers needed | |
| 26 | + | → No implementation details beyond necessary project structure | |
| 27 | + | 8. Return: SUCCESS (spec ready for planning) | |
| 28 | + | ``` | |
| 29 | + | ||
| 30 | + | --- | |
| 31 | + | ||
| 32 | + | ## ⚡ Quick Guidelines | |
| 33 | + | - ✅ Focus on WHAT users need and WHY | |
| 34 | + | - ❌ Avoid HOW to implement (no tech stack, APIs, code structure) | |
| 35 | + | - 👥 Written for business stakeholders, not developers | |
| 36 | + | ||
| 37 | + | --- | |
| 38 | + | ||
| 39 | + | ## User Scenarios & Testing *(mandatory)* | |
| 40 | + | ||
| 41 | + | ### Primary User Story | |
| 42 | + | As a developer starting work on the dumb-browser project, I need a properly initialized Go project with all required dependencies installed so that I can begin implementing features according to the project constitution without manual setup overhead. | |
| 43 | + | ||
| 44 | + | ### Acceptance Scenarios | |
| 45 | + | 1. **Given** an empty project directory, **When** project initialization is complete, **Then** the project has a valid Go module structure | |
| 46 | + | 2. **Given** the initialized project, **When** checking dependencies, **Then** all required packages from the constitution are available | |
| 47 | + | 3. **Given** the initialized project, **When** running basic build commands, **Then** no dependency resolution errors occur | |
| 48 | + | 4. **Given** the project structure, **When** examining the layout, **Then** it follows the planned architecture (CLI, database, browser components) | |
| 49 | + | ||
| 50 | + | ### Edge Cases | |
| 51 | + | - What happens when Go version is incompatible with selected dependencies? | |
| 52 | + | - How does system handle network failures during dependency installation? | |
| 53 | + | - What occurs if required system packages (WebKit2GTK) are missing? | |
| 54 | + | ||
| 55 | + | ## Requirements *(mandatory)* | |
| 56 | + | ||
| 57 | + | ### Functional Requirements | |
| 58 | + | - **FR-001**: System MUST initialize a valid Go module with appropriate module path | |
| 59 | + | - **FR-002**: System MUST install CLI framework dependencies (Cobra, Viper) | |
| 60 | + | - **FR-003**: System MUST install database dependencies (SQLite driver, SQLC tooling) | |
| 61 | + | - **FR-004**: System MUST install validation dependencies (go-playground/validator) | |
| 62 | + | - **FR-005**: System MUST install Wails v3-alpha framework for browser integration | |
| 63 | + | - **FR-006**: System MUST create basic project directory structure aligned with planned architecture | |
| 64 | + | - **FR-007**: System MUST configure SQLC for type-safe database code generation | |
| 65 | + | - **FR-008**: System MUST verify all dependencies are compatible and buildable | |
| 66 | + | - **FR-009**: System MUST create configuration files needed for the development workflow | |
| 67 | + | ||
| 68 | + | ### Key Entities | |
| 69 | + | - **Go Module**: The main project module with proper versioning and dependency management | |
| 70 | + | - **Configuration Files**: SQLC config, Wails config, and other tool configurations | |
| 71 | + | - **Project Structure**: Directory layout supporting CLI, database, and browser components | |
| 72 | + | - **Dependencies**: External packages required per the constitution (Cobra, Viper, SQLite, SQLC, Wails, validator) | |
| 73 | + | ||
| 74 | + | --- | |
| 75 | + | ||
| 76 | + | ## Review & Acceptance Checklist | |
| 77 | + | ||
| 78 | + | ### Content Quality | |
| 79 | + | - [x] No implementation details (languages, frameworks, APIs) | |
| 80 | + | - [x] Focused on user value and business needs | |
| 81 | + | - [x] Written for non-technical stakeholders | |
| 82 | + | - [x] All mandatory sections completed | |
| 83 | + | ||
| 84 | + | ### Requirement Completeness | |
| 85 | + | - [x] No [NEEDS CLARIFICATION] markers remain | |
| 86 | + | - [x] Requirements are testable and unambiguous | |
| 87 | + | - [x] Success criteria are measurable | |
| 88 | + | - [x] Scope is clearly bounded | |
| 89 | + | - [x] Dependencies and assumptions identified | |
| 90 | + | ||
| 91 | + | --- | |
| 92 | + | ||
| 93 | + | ## Execution Status | |
| 94 | + | ||
| 95 | + | - [x] User description parsed | |
| 96 | + | - [x] Key concepts extracted | |
| 97 | + | - [x] Ambiguities marked | |
| 98 | + | - [x] User scenarios defined | |
| 99 | + | - [x] Requirements generated | |
| 100 | + | - [x] Entities identified | |
| 101 | + | - [x] Review checklist passed | |
| 102 | + | ||
| 103 | + | ---⏎̸ | |
| @@ -0,0 +1,103 @@ | |||||
| 1 | + | # Feature Specification: Project Initialization with Dependencies | |||
| 2 | + | ||||
| 3 | + | **Feature Branch**: `001-init-project` | |||
| 4 | + | **Created**: 2025-01-09 | |||
| 5 | + | **Status**: Draft | |||
| 6 | + | **Input**: User description: "Lets init the project adding all deps" | |||
| 7 | + | ||||
| 8 | + | ## Execution Flow (main) | |||
| 9 | + | ``` | |||
| 10 | + | 1. Parse user description from Input | |||
| 11 | + | → "Initialize project with all required dependencies" | |||
| 12 | + | 2. Extract key concepts from description | |||
| 13 | + | → Actors: developer, build system | |||
| 14 | + | → Actions: initialize, add dependencies, configure | |||
| 15 | + | → Data: project structure, dependency management | |||
| 16 | + | → Constraints: follow constitution requirements | |||
| 17 | + | 3. For each unclear aspect: | |||
| 18 | + | → No major ambiguities - project structure defined in constitution | |||
| 19 | + | 4. Fill User Scenarios & Testing section | |||
| 20 | + | → Clear flow: developer initializes → dependencies installed → project ready | |||
| 21 | + | 5. Generate Functional Requirements | |||
| 22 | + | → Each requirement testable through build/run verification | |||
| 23 | + | 6. Identify Key Entities: Go modules, dependencies, configuration files | |||
| 24 | + | 7. Run Review Checklist | |||
| 25 | + | → No [NEEDS CLARIFICATION] markers needed | |||
| 26 | + | → No implementation details beyond necessary project structure | |||
| 27 | + | 8. Return: SUCCESS (spec ready for planning) | |||
| 28 | + | ``` | |||
| 29 | + | ||||
| 30 | + | --- | |||
| 31 | + | ||||
| 32 | + | ## ⚡ Quick Guidelines | |||
| 33 | + | - ✅ Focus on WHAT users need and WHY | |||
| 34 | + | - ❌ Avoid HOW to implement (no tech stack, APIs, code structure) | |||
| 35 | + | - 👥 Written for business stakeholders, not developers | |||
| 36 | + | ||||
| 37 | + | --- | |||
| 38 | + | ||||
| 39 | + | ## User Scenarios & Testing *(mandatory)* | |||
| 40 | + | ||||
| 41 | + | ### Primary User Story | |||
| 42 | + | As a developer starting work on the dumb-browser project, I need a properly initialized Go project with all required dependencies installed so that I can begin implementing features according to the project constitution without manual setup overhead. | |||
| 43 | + | ||||
| 44 | + | ### Acceptance Scenarios | |||
| 45 | + | 1. **Given** an empty project directory, **When** project initialization is complete, **Then** the project has a valid Go module structure | |||
| 46 | + | 2. **Given** the initialized project, **When** checking dependencies, **Then** all required packages from the constitution are available | |||
| 47 | + | 3. **Given** the initialized project, **When** running basic build commands, **Then** no dependency resolution errors occur | |||
| 48 | + | 4. **Given** the project structure, **When** examining the layout, **Then** it follows the planned architecture (CLI, database, browser components) | |||
| 49 | + | ||||
| 50 | + | ### Edge Cases | |||
| 51 | + | - What happens when Go version is incompatible with selected dependencies? | |||
| 52 | + | - How does system handle network failures during dependency installation? | |||
| 53 | + | - What occurs if required system packages (WebKit2GTK) are missing? | |||
| 54 | + | ||||
| 55 | + | ## Requirements *(mandatory)* | |||
| 56 | + | ||||
| 57 | + | ### Functional Requirements | |||
| 58 | + | - **FR-001**: System MUST initialize a valid Go module with appropriate module path | |||
| 59 | + | - **FR-002**: System MUST install CLI framework dependencies (Cobra, Viper) | |||
| 60 | + | - **FR-003**: System MUST install database dependencies (SQLite driver, SQLC tooling) | |||
| 61 | + | - **FR-004**: System MUST install validation dependencies (go-playground/validator) | |||
| 62 | + | - **FR-005**: System MUST install Wails v3-alpha framework for browser integration | |||
| 63 | + | - **FR-006**: System MUST create basic project directory structure aligned with planned architecture | |||
| 64 | + | - **FR-007**: System MUST configure SQLC for type-safe database code generation | |||
| 65 | + | - **FR-008**: System MUST verify all dependencies are compatible and buildable | |||
| 66 | + | - **FR-009**: System MUST create configuration files needed for the development workflow | |||
| 67 | + | ||||
| 68 | + | ### Key Entities | |||
| 69 | + | - **Go Module**: The main project module with proper versioning and dependency management | |||
| 70 | + | - **Configuration Files**: SQLC config, Wails config, and other tool configurations | |||
| 71 | + | - **Project Structure**: Directory layout supporting CLI, database, and browser components | |||
| 72 | + | - **Dependencies**: External packages required per the constitution (Cobra, Viper, SQLite, SQLC, Wails, validator) | |||
| 73 | + | ||||
| 74 | + | --- | |||
| 75 | + | ||||
| 76 | + | ## Review & Acceptance Checklist | |||
| 77 | + | ||||
| 78 | + | ### Content Quality | |||
| 79 | + | - [x] No implementation details (languages, frameworks, APIs) | |||
| 80 | + | - [x] Focused on user value and business needs | |||
| 81 | + | - [x] Written for non-technical stakeholders | |||
| 82 | + | - [x] All mandatory sections completed | |||
| 83 | + | ||||
| 84 | + | ### Requirement Completeness | |||
| 85 | + | - [x] No [NEEDS CLARIFICATION] markers remain | |||
| 86 | + | - [x] Requirements are testable and unambiguous | |||
| 87 | + | - [x] Success criteria are measurable | |||
| 88 | + | - [x] Scope is clearly bounded | |||
| 89 | + | - [x] Dependencies and assumptions identified | |||
| 90 | + | ||||
| 91 | + | --- | |||
| 92 | + | ||||
| 93 | + | ## Execution Status | |||
| 94 | + | ||||
| 95 | + | - [x] User description parsed | |||
| 96 | + | - [x] Key concepts extracted | |||
| 97 | + | - [x] Ambiguities marked | |||
| 98 | + | - [x] User scenarios defined | |||
| 99 | + | - [x] Requirements generated | |||
| 100 | + | - [x] Entities identified | |||
| 101 | + | - [x] Review checklist passed | |||
| 102 | + | ||||
| 103 | + | ---⏎̸ | |||
A specs/001-init-project/tasks.md +170 -0
| @@ -0,0 +1,170 @@ | |||
| 1 | + | # Tasks: Project Initialization with Dependencies | |
| 2 | + | ||
| 3 | + | **Input**: Design documents from `/home/brice/dev/projects/dumb-browser/specs/001-init-project/` | |
| 4 | + | **Prerequisites**: plan.md, research.md, data-model.md, contracts/ | |
| 5 | + | ||
| 6 | + | ## Execution Flow (main) | |
| 7 | + | Project initialization requires setting up Go module, installing dependencies with `go get @latest`, creating directory structure, and verifying installation. Tasks follow TDD principles with contract tests before implementation. | |
| 8 | + | ||
| 9 | + | ## Format: `[ID] [P?] Description` | |
| 10 | + | - **[P]**: Can run in parallel (different files, no dependencies) | |
| 11 | + | - Include exact file paths in descriptions | |
| 12 | + | ||
| 13 | + | ## Path Conventions | |
| 14 | + | Single project structure: `cmd/`, `internal/`, `tests/` at repository root per constitution | |
| 15 | + | ||
| 16 | + | ## Phase 3.1: Setup and Structure | |
| 17 | + | ||
| 18 | + | - [ ] T001 Initialize Go module with `go mod init dumb-browser` in project root | |
| 19 | + | - [ ] T002 Create project directory structure: `cmd/dumb-browser/`, `internal/{cli,db,parser,browser}/`, `migrations/`, `configs/`, `tests/{contract,integration,unit}/` | |
| 20 | + | - [ ] T003 [P] Configure Git repository with .gitignore for Go projects | |
| 21 | + | ||
| 22 | + | ## Phase 3.2: Dependency Installation | |
| 23 | + | ||
| 24 | + | - [ ] T004 [P] Install CLI dependencies: `go get github.com/spf13/cobra@latest github.com/spf13/viper@latest` | |
| 25 | + | - [ ] T005 [P] Install CGO-free database dependency: `go get github.com/ncruces/go-sqlite3@latest` | |
| 26 | + | - [ ] T006 [P] Install validation dependency: `go get github.com/go-playground/validator/v10@latest` | |
| 27 | + | - [ ] T007 [P] Install testing dependency: `go get github.com/stretchr/testify@latest` | |
| 28 | + | - [ ] T008 Install SQLC tool: `go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest` | |
| 29 | + | - [ ] T009 Install Wails v3-alpha tool: `go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28` | |
| 30 | + | ||
| 31 | + | ## Phase 3.3: Tests First (TDD) ⚠️ MUST COMPLETE BEFORE 3.4 | |
| 32 | + | ||
| 33 | + | **CRITICAL: These tests MUST be written and MUST FAIL before ANY implementation** | |
| 34 | + | ||
| 35 | + | - [ ] T010 [P] Contract test for ModuleConfig validation in `tests/contract/test_module_config.go` | |
| 36 | + | - [ ] T011 [P] Contract test for CLI init command in `tests/contract/test_cli_init.go` | |
| 37 | + | - [ ] T012 [P] Contract test for dependency installation in `tests/contract/test_deps_install.go` | |
| 38 | + | - [ ] T013 [P] Integration test for full project initialization in `tests/integration/test_full_init.go` | |
| 39 | + | - [ ] T014 [P] Integration test for CGO-free database build in `tests/integration/test_cgo_free_build.go` | |
| 40 | + | - [ ] T015 [P] Integration test for Wails build (CGO required) in `tests/integration/test_wails_build.go` | |
| 41 | + | ||
| 42 | + | ## Phase 3.4: Core Implementation (ONLY after tests are failing) | |
| 43 | + | ||
| 44 | + | - [ ] T016 [P] ModuleConfig model in `internal/models/module.go` | |
| 45 | + | - [ ] T017 [P] ProjectStructure model in `internal/models/structure.go` | |
| 46 | + | - [ ] T018 [P] InstallationStatus model in `internal/models/status.go` | |
| 47 | + | - [ ] T019 CLI root command setup in `cmd/dumb-browser/main.go` | |
| 48 | + | - [ ] T020 CLI init command implementation in `internal/cli/init.go` | |
| 49 | + | - [ ] T021 Dependency installer service in `internal/services/installer.go` | |
| 50 | + | - [ ] T022 Project structure creator in `internal/services/structure.go` | |
| 51 | + | - [ ] T023 Configuration file generator in `internal/services/config.go` | |
| 52 | + | ||
| 53 | + | ## Phase 3.5: Configuration Files | |
| 54 | + | ||
| 55 | + | - [ ] T024 [P] Generate SQLC configuration template in `configs/sqlc.yaml` | |
| 56 | + | - [ ] T025 [P] Generate Wails configuration template in `configs/wails.json` | |
| 57 | + | - [ ] T026 [P] Create initial database migration in `migrations/001_initial.sql` | |
| 58 | + | ||
| 59 | + | ## Phase 3.6: Verification and Integration | |
| 60 | + | ||
| 61 | + | - [ ] T027 Build verification with CGO_ENABLED=0 for core components | |
| 62 | + | - [ ] T028 Build verification with CGO_ENABLED=1 for Wails integration | |
| 63 | + | - [ ] T029 Dependency resolution verification with `go mod download` | |
| 64 | + | - [ ] T030 Tool availability verification: `sqlc version && wails version` | |
| 65 | + | ||
| 66 | + | ## Phase 3.7: Polish and Documentation | |
| 67 | + | ||
| 68 | + | - [ ] T031 [P] Unit tests for validation logic in `tests/unit/test_validation.go` | |
| 69 | + | - [ ] T032 [P] Unit tests for config generation in `tests/unit/test_config_gen.go` | |
| 70 | + | - [ ] T033 [P] Error handling and logging implementation | |
| 71 | + | - [ ] T034 Update quickstart.md with actual execution results | |
| 72 | + | - [ ] T035 Run full quickstart validation script | |
| 73 | + | ||
| 74 | + | ## Dependencies | |
| 75 | + | ||
| 76 | + | **Critical Path**: | |
| 77 | + | - Setup (T001-T003) before dependencies (T004-T009) | |
| 78 | + | - Dependencies before tests (T010-T015) | |
| 79 | + | - Tests (T010-T015) before implementation (T016-T023) | |
| 80 | + | - Core implementation before config files (T024-T026) | |
| 81 | + | - Everything before verification (T027-T030) | |
| 82 | + | ||
| 83 | + | **Specific Blockers**: | |
| 84 | + | - T001 blocks T004-T009 (need go.mod first) | |
| 85 | + | - T016-T018 block T021-T023 (need models for services) | |
| 86 | + | - T020 blocks T027-T030 (need CLI for verification) | |
| 87 | + | ||
| 88 | + | ## Parallel Execution Examples | |
| 89 | + | ||
| 90 | + | ### Install Dependencies Concurrently | |
| 91 | + | ```bash | |
| 92 | + | # Launch T004-T007 together (different packages): | |
| 93 | + | Task: "Install CLI dependencies: go get github.com/spf13/cobra@latest github.com/spf13/viper@latest" | |
| 94 | + | Task: "Install CGO-free database dependency: go get github.com/ncruces/go-sqlite3@latest" | |
| 95 | + | Task: "Install validation dependency: go get github.com/go-playground/validator/v10@latest" | |
| 96 | + | Task: "Install testing dependency: go get github.com/stretchr/testify@latest" | |
| 97 | + | ``` | |
| 98 | + | ||
| 99 | + | ### Write Tests Concurrently | |
| 100 | + | ```bash | |
| 101 | + | # Launch T010-T015 together (different test files): | |
| 102 | + | Task: "Contract test for ModuleConfig validation in tests/contract/test_module_config.go" | |
| 103 | + | Task: "Contract test for CLI init command in tests/contract/test_cli_init.go" | |
| 104 | + | Task: "Contract test for dependency installation in tests/contract/test_deps_install.go" | |
| 105 | + | Task: "Integration test for full project initialization in tests/integration/test_full_init.go" | |
| 106 | + | Task: "Integration test for CGO-free database build in tests/integration/test_cgo_free_build.go" | |
| 107 | + | Task: "Integration test for Wails build (CGO required) in tests/integration/test_wails_build.go" | |
| 108 | + | ``` | |
| 109 | + | ||
| 110 | + | ### Create Models Concurrently | |
| 111 | + | ```bash | |
| 112 | + | # Launch T016-T018 together (different model files): | |
| 113 | + | Task: "ModuleConfig model in internal/models/module.go" | |
| 114 | + | Task: "ProjectStructure model in internal/models/structure.go" | |
| 115 | + | Task: "InstallationStatus model in internal/models/status.go" | |
| 116 | + | ``` | |
| 117 | + | ||
| 118 | + | ## CGO Optimization Strategy | |
| 119 | + | ||
| 120 | + | **CGO-Free Development** (T004-T007, T010-T014, T016-T023): | |
| 121 | + | - Most tasks can run with `CGO_ENABLED=0` | |
| 122 | + | - Database layer uses ncruces/go-sqlite3 (CGO-free) | |
| 123 | + | - CLI and parser components don't need CGO | |
| 124 | + | - Faster development cycle for majority of work | |
| 125 | + | ||
| 126 | + | **CGO Required** (T009, T015, T028): | |
| 127 | + | - Only Wails installation and integration requires `CGO_ENABLED=1` | |
| 128 | + | - WebKit2GTK bindings need CGO for native rendering | |
| 129 | + | - Clear separation allows independent development | |
| 130 | + | ||
| 131 | + | ## Notes | |
| 132 | + | ||
| 133 | + | - [P] tasks = different files, no dependencies | |
| 134 | + | - Verify tests fail before implementing (TDD enforcement) | |
| 135 | + | - Use `go get @latest` for all dependencies per user requirements | |
| 136 | + | - Commit after each task completion | |
| 137 | + | - CGO-free SQLite driver (ncruces) allows faster development cycle | |
| 138 | + | - Only Wails final integration requires CGO | |
| 139 | + | ||
| 140 | + | ## Task Generation Rules Applied | |
| 141 | + | ||
| 142 | + | 1. **From Contracts**: | |
| 143 | + | - cli-commands.md → T011, T020 (CLI init command) | |
| 144 | + | - go-module.yaml → T010, T012 (module and dependency contracts) | |
| 145 | + | ||
| 146 | + | 2. **From Data Model**: | |
| 147 | + | - ModuleConfig → T016 (model creation) | |
| 148 | + | - ProjectStructure → T017 (model creation) | |
| 149 | + | - InstallationStatus → T018 (model creation) | |
| 150 | + | ||
| 151 | + | 3. **From Research Decisions**: | |
| 152 | + | - CGO-free SQLite → T005, T014 (specific driver selection) | |
| 153 | + | - Wails v3-alpha → T009, T015 (version-specific installation) | |
| 154 | + | ||
| 155 | + | 4. **From Quickstart Scenarios**: | |
| 156 | + | - Full initialization → T013 (integration test) | |
| 157 | + | - Build verification → T027, T028 (CGO separation tests) | |
| 158 | + | - Tool availability → T030 (verification scenario) | |
| 159 | + | ||
| 160 | + | ## Validation Checklist | |
| 161 | + | ||
| 162 | + | - [x] All contracts have corresponding tests (T010-T012) | |
| 163 | + | - [x] All entities have model tasks (T016-T018) | |
| 164 | + | - [x] All tests come before implementation (T010-T015 before T016-T023) | |
| 165 | + | - [x] Parallel tasks truly independent ([P] tasks use different files) | |
| 166 | + | - [x] Each task specifies exact file path | |
| 167 | + | - [x] No task modifies same file as another [P] task | |
| 168 | + | - [x] TDD principles enforced (tests must fail before implementation) | |
| 169 | + | - [x] CGO optimization strategy clearly defined | |
| 170 | + | - [x] Dependencies properly ordered and documented⏎̸ | |
| @@ -0,0 +1,170 @@ | |||||
| 1 | + | # Tasks: Project Initialization with Dependencies | |||
| 2 | + | ||||
| 3 | + | **Input**: Design documents from `/home/brice/dev/projects/dumb-browser/specs/001-init-project/` | |||
| 4 | + | **Prerequisites**: plan.md, research.md, data-model.md, contracts/ | |||
| 5 | + | ||||
| 6 | + | ## Execution Flow (main) | |||
| 7 | + | Project initialization requires setting up Go module, installing dependencies with `go get @latest`, creating directory structure, and verifying installation. Tasks follow TDD principles with contract tests before implementation. | |||
| 8 | + | ||||
| 9 | + | ## Format: `[ID] [P?] Description` | |||
| 10 | + | - **[P]**: Can run in parallel (different files, no dependencies) | |||
| 11 | + | - Include exact file paths in descriptions | |||
| 12 | + | ||||
| 13 | + | ## Path Conventions | |||
| 14 | + | Single project structure: `cmd/`, `internal/`, `tests/` at repository root per constitution | |||
| 15 | + | ||||
| 16 | + | ## Phase 3.1: Setup and Structure | |||
| 17 | + | ||||
| 18 | + | - [ ] T001 Initialize Go module with `go mod init dumb-browser` in project root | |||
| 19 | + | - [ ] T002 Create project directory structure: `cmd/dumb-browser/`, `internal/{cli,db,parser,browser}/`, `migrations/`, `configs/`, `tests/{contract,integration,unit}/` | |||
| 20 | + | - [ ] T003 [P] Configure Git repository with .gitignore for Go projects | |||
| 21 | + | ||||
| 22 | + | ## Phase 3.2: Dependency Installation | |||
| 23 | + | ||||
| 24 | + | - [ ] T004 [P] Install CLI dependencies: `go get github.com/spf13/cobra@latest github.com/spf13/viper@latest` | |||
| 25 | + | - [ ] T005 [P] Install CGO-free database dependency: `go get github.com/ncruces/go-sqlite3@latest` | |||
| 26 | + | - [ ] T006 [P] Install validation dependency: `go get github.com/go-playground/validator/v10@latest` | |||
| 27 | + | - [ ] T007 [P] Install testing dependency: `go get github.com/stretchr/testify@latest` | |||
| 28 | + | - [ ] T008 Install SQLC tool: `go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest` | |||
| 29 | + | - [ ] T009 Install Wails v3-alpha tool: `go install github.com/wailsapp/wails/v3/cmd/wails@v3.0.0-alpha.28` | |||
| 30 | + | ||||
| 31 | + | ## Phase 3.3: Tests First (TDD) ⚠️ MUST COMPLETE BEFORE 3.4 | |||
| 32 | + | ||||
| 33 | + | **CRITICAL: These tests MUST be written and MUST FAIL before ANY implementation** | |||
| 34 | + | ||||
| 35 | + | - [ ] T010 [P] Contract test for ModuleConfig validation in `tests/contract/test_module_config.go` | |||
| 36 | + | - [ ] T011 [P] Contract test for CLI init command in `tests/contract/test_cli_init.go` | |||
| 37 | + | - [ ] T012 [P] Contract test for dependency installation in `tests/contract/test_deps_install.go` | |||
| 38 | + | - [ ] T013 [P] Integration test for full project initialization in `tests/integration/test_full_init.go` | |||
| 39 | + | - [ ] T014 [P] Integration test for CGO-free database build in `tests/integration/test_cgo_free_build.go` | |||
| 40 | + | - [ ] T015 [P] Integration test for Wails build (CGO required) in `tests/integration/test_wails_build.go` | |||
| 41 | + | ||||
| 42 | + | ## Phase 3.4: Core Implementation (ONLY after tests are failing) | |||
| 43 | + | ||||
| 44 | + | - [ ] T016 [P] ModuleConfig model in `internal/models/module.go` | |||
| 45 | + | - [ ] T017 [P] ProjectStructure model in `internal/models/structure.go` | |||
| 46 | + | - [ ] T018 [P] InstallationStatus model in `internal/models/status.go` | |||
| 47 | + | - [ ] T019 CLI root command setup in `cmd/dumb-browser/main.go` | |||
| 48 | + | - [ ] T020 CLI init command implementation in `internal/cli/init.go` | |||
| 49 | + | - [ ] T021 Dependency installer service in `internal/services/installer.go` | |||
| 50 | + | - [ ] T022 Project structure creator in `internal/services/structure.go` | |||
| 51 | + | - [ ] T023 Configuration file generator in `internal/services/config.go` | |||
| 52 | + | ||||
| 53 | + | ## Phase 3.5: Configuration Files | |||
| 54 | + | ||||
| 55 | + | - [ ] T024 [P] Generate SQLC configuration template in `configs/sqlc.yaml` | |||
| 56 | + | - [ ] T025 [P] Generate Wails configuration template in `configs/wails.json` | |||
| 57 | + | - [ ] T026 [P] Create initial database migration in `migrations/001_initial.sql` | |||
| 58 | + | ||||
| 59 | + | ## Phase 3.6: Verification and Integration | |||
| 60 | + | ||||
| 61 | + | - [ ] T027 Build verification with CGO_ENABLED=0 for core components | |||
| 62 | + | - [ ] T028 Build verification with CGO_ENABLED=1 for Wails integration | |||
| 63 | + | - [ ] T029 Dependency resolution verification with `go mod download` | |||
| 64 | + | - [ ] T030 Tool availability verification: `sqlc version && wails version` | |||
| 65 | + | ||||
| 66 | + | ## Phase 3.7: Polish and Documentation | |||
| 67 | + | ||||
| 68 | + | - [ ] T031 [P] Unit tests for validation logic in `tests/unit/test_validation.go` | |||
| 69 | + | - [ ] T032 [P] Unit tests for config generation in `tests/unit/test_config_gen.go` | |||
| 70 | + | - [ ] T033 [P] Error handling and logging implementation | |||
| 71 | + | - [ ] T034 Update quickstart.md with actual execution results | |||
| 72 | + | - [ ] T035 Run full quickstart validation script | |||
| 73 | + | ||||
| 74 | + | ## Dependencies | |||
| 75 | + | ||||
| 76 | + | **Critical Path**: | |||
| 77 | + | - Setup (T001-T003) before dependencies (T004-T009) | |||
| 78 | + | - Dependencies before tests (T010-T015) | |||
| 79 | + | - Tests (T010-T015) before implementation (T016-T023) | |||
| 80 | + | - Core implementation before config files (T024-T026) | |||
| 81 | + | - Everything before verification (T027-T030) | |||
| 82 | + | ||||
| 83 | + | **Specific Blockers**: | |||
| 84 | + | - T001 blocks T004-T009 (need go.mod first) | |||
| 85 | + | - T016-T018 block T021-T023 (need models for services) | |||
| 86 | + | - T020 blocks T027-T030 (need CLI for verification) | |||
| 87 | + | ||||
| 88 | + | ## Parallel Execution Examples | |||
| 89 | + | ||||
| 90 | + | ### Install Dependencies Concurrently | |||
| 91 | + | ```bash | |||
| 92 | + | # Launch T004-T007 together (different packages): | |||
| 93 | + | Task: "Install CLI dependencies: go get github.com/spf13/cobra@latest github.com/spf13/viper@latest" | |||
| 94 | + | Task: "Install CGO-free database dependency: go get github.com/ncruces/go-sqlite3@latest" | |||
| 95 | + | Task: "Install validation dependency: go get github.com/go-playground/validator/v10@latest" | |||
| 96 | + | Task: "Install testing dependency: go get github.com/stretchr/testify@latest" | |||
| 97 | + | ``` | |||
| 98 | + | ||||
| 99 | + | ### Write Tests Concurrently | |||
| 100 | + | ```bash | |||
| 101 | + | # Launch T010-T015 together (different test files): | |||
| 102 | + | Task: "Contract test for ModuleConfig validation in tests/contract/test_module_config.go" | |||
| 103 | + | Task: "Contract test for CLI init command in tests/contract/test_cli_init.go" | |||
| 104 | + | Task: "Contract test for dependency installation in tests/contract/test_deps_install.go" | |||
| 105 | + | Task: "Integration test for full project initialization in tests/integration/test_full_init.go" | |||
| 106 | + | Task: "Integration test for CGO-free database build in tests/integration/test_cgo_free_build.go" | |||
| 107 | + | Task: "Integration test for Wails build (CGO required) in tests/integration/test_wails_build.go" | |||
| 108 | + | ``` | |||
| 109 | + | ||||
| 110 | + | ### Create Models Concurrently | |||
| 111 | + | ```bash | |||
| 112 | + | # Launch T016-T018 together (different model files): | |||
| 113 | + | Task: "ModuleConfig model in internal/models/module.go" | |||
| 114 | + | Task: "ProjectStructure model in internal/models/structure.go" | |||
| 115 | + | Task: "InstallationStatus model in internal/models/status.go" | |||
| 116 | + | ``` | |||
| 117 | + | ||||
| 118 | + | ## CGO Optimization Strategy | |||
| 119 | + | ||||
| 120 | + | **CGO-Free Development** (T004-T007, T010-T014, T016-T023): | |||
| 121 | + | - Most tasks can run with `CGO_ENABLED=0` | |||
| 122 | + | - Database layer uses ncruces/go-sqlite3 (CGO-free) | |||
| 123 | + | - CLI and parser components don't need CGO | |||
| 124 | + | - Faster development cycle for majority of work | |||
| 125 | + | ||||
| 126 | + | **CGO Required** (T009, T015, T028): | |||
| 127 | + | - Only Wails installation and integration requires `CGO_ENABLED=1` | |||
| 128 | + | - WebKit2GTK bindings need CGO for native rendering | |||
| 129 | + | - Clear separation allows independent development | |||
| 130 | + | ||||
| 131 | + | ## Notes | |||
| 132 | + | ||||
| 133 | + | - [P] tasks = different files, no dependencies | |||
| 134 | + | - Verify tests fail before implementing (TDD enforcement) | |||
| 135 | + | - Use `go get @latest` for all dependencies per user requirements | |||
| 136 | + | - Commit after each task completion | |||
| 137 | + | - CGO-free SQLite driver (ncruces) allows faster development cycle | |||
| 138 | + | - Only Wails final integration requires CGO | |||
| 139 | + | ||||
| 140 | + | ## Task Generation Rules Applied | |||
| 141 | + | ||||
| 142 | + | 1. **From Contracts**: | |||
| 143 | + | - cli-commands.md → T011, T020 (CLI init command) | |||
| 144 | + | - go-module.yaml → T010, T012 (module and dependency contracts) | |||
| 145 | + | ||||
| 146 | + | 2. **From Data Model**: | |||
| 147 | + | - ModuleConfig → T016 (model creation) | |||
| 148 | + | - ProjectStructure → T017 (model creation) | |||
| 149 | + | - InstallationStatus → T018 (model creation) | |||
| 150 | + | ||||
| 151 | + | 3. **From Research Decisions**: | |||
| 152 | + | - CGO-free SQLite → T005, T014 (specific driver selection) | |||
| 153 | + | - Wails v3-alpha → T009, T015 (version-specific installation) | |||
| 154 | + | ||||
| 155 | + | 4. **From Quickstart Scenarios**: | |||
| 156 | + | - Full initialization → T013 (integration test) | |||
| 157 | + | - Build verification → T027, T028 (CGO separation tests) | |||
| 158 | + | - Tool availability → T030 (verification scenario) | |||
| 159 | + | ||||
| 160 | + | ## Validation Checklist | |||
| 161 | + | ||||
| 162 | + | - [x] All contracts have corresponding tests (T010-T012) | |||
| 163 | + | - [x] All entities have model tasks (T016-T018) | |||
| 164 | + | - [x] All tests come before implementation (T010-T015 before T016-T023) | |||
| 165 | + | - [x] Parallel tasks truly independent ([P] tasks use different files) | |||
| 166 | + | - [x] Each task specifies exact file path | |||
| 167 | + | - [x] No task modifies same file as another [P] task | |||
| 168 | + | - [x] TDD principles enforced (tests must fail before implementation) | |||
| 169 | + | - [x] CGO optimization strategy clearly defined | |||
| 170 | + | - [x] Dependencies properly ordered and documented⏎̸ | |||
A sqlc.yaml +15 -0
| @@ -0,0 +1,15 @@ | |||
| 1 | + | version: "2" | |
| 2 | + | sql: | |
| 3 | + | - engine: "sqlite" | |
| 4 | + | queries: "./internal/db/queries/" | |
| 5 | + | schema: "./migrations/" | |
| 6 | + | gen: | |
| 7 | + | go: | |
| 8 | + | package: "db" | |
| 9 | + | out: "./internal/db" | |
| 10 | + | sql_package: "database/sql" | |
| 11 | + | emit_json_tags: true | |
| 12 | + | emit_empty_slices: true | |
| 13 | + | emit_exported_queries: true | |
| 14 | + | emit_interface: true | |
| 15 | + | query_parameter_limit: 5⏎̸ | |
| @@ -0,0 +1,15 @@ | |||||
| 1 | + | version: "2" | |||
| 2 | + | sql: | |||
| 3 | + | - engine: "sqlite" | |||
| 4 | + | queries: "./internal/db/queries/" | |||
| 5 | + | schema: "./migrations/" | |||
| 6 | + | gen: | |||
| 7 | + | go: | |||
| 8 | + | package: "db" | |||
| 9 | + | out: "./internal/db" | |||
| 10 | + | sql_package: "database/sql" | |||
| 11 | + | emit_json_tags: true | |||
| 12 | + | emit_empty_slices: true | |||
| 13 | + | emit_exported_queries: true | |||
| 14 | + | emit_interface: true | |||
| 15 | + | query_parameter_limit: 5⏎̸ | |||