gui: add Wails v3 desktop app skeleton
- Go upgraded to 1.25.10 (required by Wails v3) - Wails v3 installed (alpha.96) - Frontend: Svelte+Vite scaffold in frontend/ - guimain.go: Wails GUI entry point (compiled with -tags gui) - wails_service.go: stub service for Wails bindings - Verstak desktop binary builds: go build -tags gui -o verstak-gui . - CLI (./cmd/verstak/) unaffected - Legacy HTTP GUI (internal/gui/) preserved as prototype - Build: 24MB ELF binary with GTK4/WebKit2GTK-6 Build commands: CLI: go build -o verstak ./cmd/verstak/ GUI: cd frontend && npm run build && go build -tags gui -o verstak-gui .
This commit is contained in:
parent
537e8a126e
commit
600b67bc1e
|
|
@ -21,6 +21,9 @@ go.work
|
|||
# Wails
|
||||
frontend/dist/
|
||||
frontend/node_modules/
|
||||
frontend/bindings/
|
||||
verstak-gui
|
||||
verstak-cli
|
||||
|
||||
# VS Code
|
||||
.vscode/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,355 @@
|
|||
version: '3'
|
||||
|
||||
tasks:
|
||||
go:mod:tidy:
|
||||
summary: Runs `go mod tidy`
|
||||
internal: true
|
||||
cmds:
|
||||
- go mod tidy
|
||||
|
||||
install:frontend:deps:
|
||||
summary: Install frontend dependencies
|
||||
cmds:
|
||||
- task: install:frontend:deps:{{.PACKAGE_MANAGER}}
|
||||
|
||||
install:frontend:deps:npm:
|
||||
dir: frontend
|
||||
sources:
|
||||
- package.json
|
||||
- package-lock.json
|
||||
generates:
|
||||
- node_modules
|
||||
preconditions:
|
||||
- sh: npm version
|
||||
msg: "Looks like npm isn't installed. Npm is part of the Node installer: https://nodejs.org/en/download/"
|
||||
cmds:
|
||||
- npm install
|
||||
|
||||
install:frontend:deps:bun:
|
||||
dir: frontend
|
||||
sources:
|
||||
- package.json
|
||||
- bun.lock
|
||||
- bun.lockb
|
||||
generates:
|
||||
- node_modules
|
||||
preconditions:
|
||||
- sh: bun --version
|
||||
msg: "bun not found"
|
||||
cmds:
|
||||
- bun install
|
||||
|
||||
install:frontend:deps:pnpm:
|
||||
dir: frontend
|
||||
sources:
|
||||
- package.json
|
||||
- pnpm-lock.yaml
|
||||
generates:
|
||||
- node_modules
|
||||
preconditions:
|
||||
- sh: pnpm --version
|
||||
msg: "pnpm not found"
|
||||
cmds:
|
||||
- pnpm install
|
||||
|
||||
install:frontend:deps:yarn:
|
||||
dir: frontend
|
||||
sources:
|
||||
- package.json
|
||||
- yarn.lock
|
||||
status:
|
||||
- test -d node_modules || test -f .pnp.cjs
|
||||
preconditions:
|
||||
- sh: yarn --version
|
||||
msg: "yarn not found"
|
||||
cmds:
|
||||
- yarn install
|
||||
|
||||
build:frontend:
|
||||
label: build:frontend (DEV={{.DEV}} RUNNER={{.PACKAGE_MANAGER}})
|
||||
summary: Build the frontend project
|
||||
dir: frontend
|
||||
sources:
|
||||
- "**/*"
|
||||
- exclude: node_modules/**/*
|
||||
generates:
|
||||
- dist/**/*
|
||||
deps:
|
||||
- task: install:frontend:deps
|
||||
- task: generate:bindings
|
||||
vars:
|
||||
BUILD_FLAGS:
|
||||
ref: .BUILD_FLAGS
|
||||
OBFUSCATED:
|
||||
ref: .OBFUSCATED
|
||||
cmds:
|
||||
- task: frontend:run
|
||||
vars:
|
||||
SCRIPT: '{{if eq .DEV "true"}}build:dev{{else}}build{{end}}'
|
||||
env:
|
||||
PRODUCTION: '{{if eq .DEV "true"}}false{{else}}true{{end}}'
|
||||
|
||||
frontend:run:
|
||||
summary: Run a frontend script with selected runner
|
||||
cmds:
|
||||
- task: frontend:run:{{.PACKAGE_MANAGER}}
|
||||
vars:
|
||||
SCRIPT: "{{.SCRIPT}}"
|
||||
vars:
|
||||
SCRIPT: "{{.SCRIPT}}"
|
||||
|
||||
frontend:run:npm:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- npm run {{.SCRIPT}} -q
|
||||
vars:
|
||||
SCRIPT: "{{.SCRIPT}}"
|
||||
|
||||
frontend:run:yarn:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- yarn {{.SCRIPT}}
|
||||
vars:
|
||||
SCRIPT: "{{.SCRIPT}}"
|
||||
|
||||
frontend:run:pnpm:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- pnpm run {{.SCRIPT}}
|
||||
vars:
|
||||
SCRIPT: "{{.SCRIPT}}"
|
||||
|
||||
frontend:run:bun:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- bun run {{.SCRIPT}}
|
||||
vars:
|
||||
SCRIPT: "{{.SCRIPT}}"
|
||||
|
||||
frontend:vendor:puppertino:
|
||||
summary: Fetches Puppertino CSS into frontend/public for consistent mobile styling
|
||||
sources:
|
||||
- frontend/public/puppertino/puppertino.css
|
||||
generates:
|
||||
- frontend/public/puppertino/puppertino.css
|
||||
cmds:
|
||||
- |
|
||||
set -euo pipefail
|
||||
mkdir -p frontend/public/puppertino
|
||||
# If bundled Puppertino exists, prefer it. Otherwise, try to fetch, but don't fail build on error.
|
||||
if [ ! -f frontend/public/puppertino/puppertino.css ]; then
|
||||
echo "No bundled Puppertino found. Attempting to fetch from GitHub..."
|
||||
if curl -fsSL https://raw.githubusercontent.com/codedgar/Puppertino/main/dist/css/full.css -o frontend/public/puppertino/puppertino.css; then
|
||||
curl -fsSL https://raw.githubusercontent.com/codedgar/Puppertino/main/LICENSE -o frontend/public/puppertino/LICENSE || true
|
||||
echo "Puppertino CSS downloaded to frontend/public/puppertino/puppertino.css"
|
||||
else
|
||||
echo "Warning: Could not fetch Puppertino CSS. Proceeding without download since template may bundle it."
|
||||
fi
|
||||
else
|
||||
echo "Using bundled Puppertino at frontend/public/puppertino/puppertino.css"
|
||||
fi
|
||||
# Ensure index.html includes Puppertino CSS and button classes
|
||||
INDEX_HTML=frontend/index.html
|
||||
if [ -f "$INDEX_HTML" ]; then
|
||||
if ! grep -q 'href="/puppertino/puppertino.css"' "$INDEX_HTML"; then
|
||||
# Insert Puppertino link tag after style.css link
|
||||
awk '
|
||||
/href="\/style.css"\/?/ && !x { print; print " <link rel=\"stylesheet\" href=\"/puppertino/puppertino.css\"/>"; x=1; next }1
|
||||
' "$INDEX_HTML" > "$INDEX_HTML.tmp" && mv "$INDEX_HTML.tmp" "$INDEX_HTML"
|
||||
fi
|
||||
# Replace default .btn with Puppertino primary button classes if present
|
||||
sed -E -i'' 's/class=\"btn\"/class=\"p-btn p-prim-col\"/g' "$INDEX_HTML" || true
|
||||
fi
|
||||
|
||||
|
||||
|
||||
generate:bindings:
|
||||
label: generate:bindings (BUILD_FLAGS={{.BUILD_FLAGS}})
|
||||
summary: Generates bindings for the frontend
|
||||
deps:
|
||||
- task: go:mod:tidy
|
||||
sources:
|
||||
- "**/*.[jt]s"
|
||||
- exclude: frontend/**/*
|
||||
- frontend/bindings/**/* # Rerun when switching between dev/production mode causes changes in output
|
||||
- "**/*.go"
|
||||
- go.mod
|
||||
- go.sum
|
||||
generates:
|
||||
- frontend/bindings/**/*
|
||||
cmds:
|
||||
- wails3 generate bindings -f '{{.BUILD_FLAGS}}' -clean=true{{if eq .OBFUSCATED "true"}} -obfuscated{{end}}
|
||||
|
||||
generate:icons:
|
||||
summary: Generates Windows `.ico` and Mac `.icns` from an image; on macOS, `-iconcomposerinput appicon.icon -macassetdir darwin` also produces `Assets.car` from a `.icon` file (skipped on other platforms).
|
||||
dir: build
|
||||
sources:
|
||||
- "appicon.png"
|
||||
- "appicon.icon"
|
||||
generates:
|
||||
- "darwin/icons.icns"
|
||||
- "windows/icon.ico"
|
||||
cmds:
|
||||
- wails3 generate icons -input appicon.png -macfilename darwin/icons.icns -windowsfilename windows/icon.ico -iconcomposerinput appicon.icon -macassetdir darwin
|
||||
|
||||
dev:frontend:
|
||||
summary: Runs the frontend in development mode
|
||||
deps:
|
||||
- task: install:frontend:deps
|
||||
cmds:
|
||||
- task: frontend:dev:{{.PACKAGE_MANAGER}}
|
||||
|
||||
frontend:dev:npm:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- npm run dev -- --port {{.VITE_PORT}} --strictPort
|
||||
|
||||
frontend:dev:yarn:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- yarn dev --port {{.VITE_PORT}} --strictPort
|
||||
|
||||
frontend:dev:pnpm:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- pnpm dev --port {{.VITE_PORT}} --strictPort
|
||||
|
||||
frontend:dev:bun:
|
||||
dir: frontend
|
||||
cmds:
|
||||
- bun run dev --port {{.VITE_PORT}} --strictPort
|
||||
|
||||
update:build-assets:
|
||||
summary: Updates the build assets
|
||||
dir: build
|
||||
cmds:
|
||||
- wails3 update build-assets -name "{{.APP_NAME}}" -binaryname "{{.APP_NAME}}" -config config.yml -dir .
|
||||
|
||||
build:server:
|
||||
summary: Builds the application in server mode (no GUI, HTTP server only)
|
||||
desc: |
|
||||
Builds the application with the server build tag enabled.
|
||||
Server mode runs as a pure HTTP server without native GUI dependencies.
|
||||
Usage: task build:server
|
||||
deps:
|
||||
- task: build:frontend
|
||||
vars:
|
||||
BUILD_FLAGS:
|
||||
ref: .BUILD_FLAGS
|
||||
cmds:
|
||||
- go build -tags server {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}-server{{exeExt}}
|
||||
vars:
|
||||
BUILD_FLAGS: "{{.BUILD_FLAGS}}"
|
||||
|
||||
run:server:
|
||||
summary: Builds and runs the application in server mode
|
||||
deps:
|
||||
- task: build:server
|
||||
cmds:
|
||||
- ./{{.BIN_DIR}}/{{.APP_NAME}}-server{{exeExt}}
|
||||
|
||||
build:docker:
|
||||
summary: Builds a Docker image for server mode deployment
|
||||
desc: |
|
||||
Creates a minimal Docker image containing the server mode binary.
|
||||
The image is based on distroless for security and small size.
|
||||
Usage: task build:docker [TAG=myapp:latest]
|
||||
cmds:
|
||||
- docker build -t {{.TAG | default (printf "%s:latest" .APP_NAME)}} -f build/docker/Dockerfile.server .
|
||||
vars:
|
||||
TAG: "{{.TAG}}"
|
||||
preconditions:
|
||||
- sh: docker info > /dev/null 2>&1
|
||||
msg: "Docker is required. Please install Docker first."
|
||||
- sh: test -f build/docker/Dockerfile.server
|
||||
msg: "Dockerfile.server not found. Run 'wails3 update build-assets' to generate it."
|
||||
|
||||
run:docker:
|
||||
summary: Builds and runs the Docker image
|
||||
desc: |
|
||||
Builds the Docker image and runs it, exposing port 8080.
|
||||
Usage: task run:docker [TAG=myapp:latest] [PORT=8080]
|
||||
Note: The internal container port is always 8080. The PORT variable
|
||||
only changes the host port mapping. Ensure your app uses port 8080
|
||||
or modify the Dockerfile to match your ServerOptions.Port setting.
|
||||
deps:
|
||||
- task: build:docker
|
||||
vars:
|
||||
TAG:
|
||||
ref: .TAG
|
||||
cmds:
|
||||
- docker run --rm -p {{.PORT | default "8080"}}:8080 {{.TAG | default (printf "%s:latest" .APP_NAME)}}
|
||||
vars:
|
||||
TAG: "{{.TAG}}"
|
||||
PORT: "{{.PORT}}"
|
||||
|
||||
setup:docker:
|
||||
summary: Builds Docker image for cross-compilation (~800MB download)
|
||||
desc: |
|
||||
Builds the Docker image needed for cross-compiling to any platform.
|
||||
Run this once to enable cross-platform builds from any OS.
|
||||
cmds:
|
||||
- docker build -t wails-cross -f build/docker/Dockerfile.cross build/docker/
|
||||
preconditions:
|
||||
- sh: docker info > /dev/null 2>&1
|
||||
msg: "Docker is required. Please install Docker first."
|
||||
|
||||
ios:device:list:
|
||||
summary: Lists connected iOS devices (UDIDs)
|
||||
cmds:
|
||||
- xcrun xcdevice list
|
||||
|
||||
ios:run:device:
|
||||
summary: Build, install, and launch on a physical iPhone using Apple tools (xcodebuild/devicectl)
|
||||
vars:
|
||||
PROJECT: '{{.PROJECT}}' # e.g., build/ios/xcode/<YourProject>.xcodeproj
|
||||
SCHEME: '{{.SCHEME}}' # e.g., ios.dev
|
||||
CONFIG: '{{.CONFIG | default "Debug"}}'
|
||||
DERIVED: '{{.DERIVED | default "build/ios/DerivedData"}}'
|
||||
UDID: '{{.UDID}}' # from `task ios:device:list`
|
||||
BUNDLE_ID: '{{.BUNDLE_ID}}' # e.g., com.yourco.wails.ios.dev
|
||||
TEAM_ID: '{{.TEAM_ID}}' # optional, if your project is not already set up for signing
|
||||
preconditions:
|
||||
- sh: xcrun -f xcodebuild
|
||||
msg: "xcodebuild not found. Please install Xcode."
|
||||
- sh: xcrun -f devicectl
|
||||
msg: "devicectl not found. Please update to Xcode 15+ (which includes devicectl)."
|
||||
- sh: test -n '{{.PROJECT}}'
|
||||
msg: "Set PROJECT to your .xcodeproj path (e.g., PROJECT=build/ios/xcode/App.xcodeproj)."
|
||||
- sh: test -n '{{.SCHEME}}'
|
||||
msg: "Set SCHEME to your app scheme (e.g., SCHEME=ios.dev)."
|
||||
- sh: test -n '{{.UDID}}'
|
||||
msg: "Set UDID to your device UDID (see: task ios:device:list)."
|
||||
- sh: test -n '{{.BUNDLE_ID}}'
|
||||
msg: "Set BUNDLE_ID to your app's bundle identifier (e.g., com.yourco.wails.ios.dev)."
|
||||
cmds:
|
||||
- |
|
||||
set -euo pipefail
|
||||
echo "Building for device: UDID={{.UDID}} SCHEME={{.SCHEME}} PROJECT={{.PROJECT}}"
|
||||
XCB_ARGS=(
|
||||
-project "{{.PROJECT}}"
|
||||
-scheme "{{.SCHEME}}"
|
||||
-configuration "{{.CONFIG}}"
|
||||
-destination "id={{.UDID}}"
|
||||
-derivedDataPath "{{.DERIVED}}"
|
||||
-allowProvisioningUpdates
|
||||
-allowProvisioningDeviceRegistration
|
||||
)
|
||||
# Optionally inject signing identifiers if provided
|
||||
if [ -n '{{.TEAM_ID}}' ]; then XCB_ARGS+=(DEVELOPMENT_TEAM={{.TEAM_ID}}); fi
|
||||
if [ -n '{{.BUNDLE_ID}}' ]; then XCB_ARGS+=(PRODUCT_BUNDLE_IDENTIFIER={{.BUNDLE_ID}}); fi
|
||||
xcodebuild "${XCB_ARGS[@]}" build | xcpretty || true
|
||||
# If xcpretty isn't installed, run without it
|
||||
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
|
||||
xcodebuild "${XCB_ARGS[@]}" build
|
||||
fi
|
||||
# Find built .app
|
||||
APP_PATH=$(find "{{.DERIVED}}/Build/Products" -type d -name "*.app" -maxdepth 3 | head -n 1)
|
||||
if [ -z "$APP_PATH" ]; then
|
||||
echo "Could not locate built .app under {{.DERIVED}}/Build/Products" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Installing: $APP_PATH"
|
||||
xcrun devicectl device install app --device "{{.UDID}}" "$APP_PATH"
|
||||
echo "Launching: {{.BUNDLE_ID}}"
|
||||
xcrun devicectl device process launch --device "{{.UDID}}" --stderr console --stdout console "{{.BUNDLE_ID}}"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 583 533" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-246,-251)">
|
||||
<g id="Ebene1">
|
||||
<path d="M246,251L265,784L401,784L506,450L507,450L505,784L641,784L829,251L682,251L596,567L595,567L596,251L478,251L378,568L391,251L246,251Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 698 B |
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"fill" : {
|
||||
"automatic-gradient" : "extended-gray:1.00000,1.00000"
|
||||
},
|
||||
"groups" : [
|
||||
{
|
||||
"layers" : [
|
||||
{
|
||||
"fill-specializations" : [
|
||||
{
|
||||
"appearance" : "dark",
|
||||
"value" : {
|
||||
"solid" : "srgb:0.92143,0.92145,0.92144,1.00000"
|
||||
}
|
||||
},
|
||||
{
|
||||
"appearance" : "tinted",
|
||||
"value" : {
|
||||
"solid" : "srgb:0.83742,0.83744,0.83743,1.00000"
|
||||
}
|
||||
}
|
||||
],
|
||||
"image-name" : "wails_icon_vector.svg",
|
||||
"name" : "wails_icon_vector",
|
||||
"position" : {
|
||||
"scale" : 1.25,
|
||||
"translation-in-points" : [
|
||||
36.890625,
|
||||
4.96875
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"shadow" : {
|
||||
"kind" : "neutral",
|
||||
"opacity" : 0.5
|
||||
},
|
||||
"specular" : true,
|
||||
"translucency" : {
|
||||
"enabled" : true,
|
||||
"value" : 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"supported-platforms" : {
|
||||
"circles" : [
|
||||
"watchOS"
|
||||
],
|
||||
"squares" : "shared"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 130 KiB |
|
|
@ -0,0 +1,79 @@
|
|||
# This file contains the configuration for this project.
|
||||
# When you update `info` or `fileAssociations`, run `wails3 task common:update:build-assets` to update the assets.
|
||||
# Note that this will overwrite any changes you have made to the assets.
|
||||
version: '3'
|
||||
|
||||
# This information is used to generate the build assets.
|
||||
info:
|
||||
companyName: "My Company" # The name of the company
|
||||
productName: "My Product" # The name of the application
|
||||
productIdentifier: "com.mycompany.myproduct" # The unique product identifier
|
||||
description: "A program that does X" # The application description
|
||||
copyright: "(c) 2025, My Company" # Copyright text
|
||||
comments: "Some Product Comments" # Comments
|
||||
version: "0.0.1" # The application version
|
||||
# cfBundleIconName: "appicon" # The macOS icon name in Assets.car icon bundles (optional)
|
||||
# # Should match the name of your .icon file without the extension
|
||||
# # If not set and Assets.car exists, defaults to "appicon"
|
||||
|
||||
# iOS build configuration (uncomment to customise iOS project generation)
|
||||
# Note: Keys under `ios` OVERRIDE values under `info` when set.
|
||||
# ios:
|
||||
# # The iOS bundle identifier used in the generated Xcode project (CFBundleIdentifier)
|
||||
# bundleID: "com.mycompany.myproduct"
|
||||
# # The display name shown under the app icon (CFBundleDisplayName/CFBundleName)
|
||||
# displayName: "My Product"
|
||||
# # The app version to embed in Info.plist (CFBundleShortVersionString/CFBundleVersion)
|
||||
# version: "0.0.1"
|
||||
# # The company/organisation name for templates and project settings
|
||||
# company: "My Company"
|
||||
# # Additional comments to embed in Info.plist metadata
|
||||
# comments: "Some Product Comments"
|
||||
|
||||
# Dev mode configuration
|
||||
dev_mode:
|
||||
root_path: .
|
||||
log_level: warn
|
||||
debounce: 1000
|
||||
ignore:
|
||||
dir:
|
||||
- .git
|
||||
- node_modules
|
||||
- frontend
|
||||
- bin
|
||||
file:
|
||||
- .DS_Store
|
||||
- .gitignore
|
||||
- .gitkeep
|
||||
- "*_test.go"
|
||||
watched_extension:
|
||||
- "*.go"
|
||||
- "*.js" # Watch for changes to JS/TS files included using the //wails:include directive.
|
||||
- "*.ts" # The frontend directory will be excluded entirely by the setting above.
|
||||
git_ignore: true
|
||||
executes:
|
||||
- cmd: wails3 build DEV=true
|
||||
type: blocking
|
||||
- cmd: wails3 task common:dev:frontend
|
||||
type: background
|
||||
- cmd: wails3 task run
|
||||
type: primary
|
||||
|
||||
# File Associations
|
||||
# More information at: https://v3.wails.io/noit/done/yet
|
||||
fileAssociations:
|
||||
# - ext: wails
|
||||
# name: Wails
|
||||
# description: Wails Application File
|
||||
# iconName: wailsFileIcon
|
||||
# role: Editor
|
||||
# - ext: jpg
|
||||
# name: JPEG
|
||||
# description: Image File
|
||||
# iconName: jpegFileIcon
|
||||
# role: Editor
|
||||
# mimeType: image/jpeg # (optional)
|
||||
|
||||
# Other data
|
||||
other:
|
||||
- name: My Other Data
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
# Cross-compile Wails v3 apps to any platform
|
||||
#
|
||||
# Darwin: Zig + macOS SDK
|
||||
# Linux: Native GCC when host matches target, Zig for cross-arch
|
||||
# Windows: Zig + bundled mingw
|
||||
#
|
||||
# Usage:
|
||||
# docker build -t wails-cross -f Dockerfile.cross .
|
||||
# docker run --rm -v $(pwd):/app wails-cross darwin arm64
|
||||
# docker run --rm -v $(pwd):/app wails-cross darwin amd64
|
||||
# docker run --rm -v $(pwd):/app wails-cross linux amd64
|
||||
# docker run --rm -v $(pwd):/app wails-cross linux arm64
|
||||
# docker run --rm -v $(pwd):/app wails-cross windows amd64
|
||||
# docker run --rm -v $(pwd):/app wails-cross windows arm64
|
||||
|
||||
FROM golang:1.26-bookworm
|
||||
|
||||
ARG TARGETARCH
|
||||
ARG GARBLE_VERSION=v0.16.0
|
||||
|
||||
# Install base tools, GCC, and GTK/WebKit dev packages
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl xz-utils nodejs npm pkg-config gcc libc6-dev \
|
||||
libgtk-3-dev libwebkit2gtk-4.1-dev \
|
||||
libgtk-4-dev libwebkitgtk-6.0-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN go install mvdan.cc/garble@${GARBLE_VERSION}
|
||||
|
||||
# Install Zig - automatically selects correct binary for host architecture
|
||||
ARG ZIG_VERSION=0.14.0
|
||||
RUN ZIG_ARCH=$(case "${TARGETARCH}" in arm64) echo "aarch64" ;; *) echo "x86_64" ;; esac) && \
|
||||
curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" \
|
||||
| tar -xJ -C /opt \
|
||||
&& ln -s /opt/zig-linux-${ZIG_ARCH}-${ZIG_VERSION}/zig /usr/local/bin/zig
|
||||
|
||||
# Download macOS SDK (required for darwin targets)
|
||||
ARG MACOS_SDK_VERSION=14.5
|
||||
RUN curl -L "https://github.com/joseluisq/macosx-sdks/releases/download/${MACOS_SDK_VERSION}/MacOSX${MACOS_SDK_VERSION}.sdk.tar.xz" \
|
||||
| tar -xJ -C /opt \
|
||||
&& mv /opt/MacOSX${MACOS_SDK_VERSION}.sdk /opt/macos-sdk
|
||||
|
||||
ENV MACOS_SDK_PATH=/opt/macos-sdk
|
||||
|
||||
# Create Zig CC wrappers for cross-compilation targets
|
||||
# Darwin and Windows use Zig; Linux uses native GCC (run with --platform for cross-arch)
|
||||
|
||||
# Darwin arm64
|
||||
COPY <<'ZIGWRAP' /usr/local/bin/zcc-darwin-arm64
|
||||
#!/bin/sh
|
||||
ARGS=""
|
||||
SKIP_NEXT=0
|
||||
for arg in "$@"; do
|
||||
if [ $SKIP_NEXT -eq 1 ]; then
|
||||
SKIP_NEXT=0
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-target) SKIP_NEXT=1 ;;
|
||||
-mmacosx-version-min=*) ;;
|
||||
*) ARGS="$ARGS $arg" ;;
|
||||
esac
|
||||
done
|
||||
exec zig cc -fno-sanitize=all -target aarch64-macos-none -isysroot /opt/macos-sdk -I/opt/macos-sdk/usr/include -L/opt/macos-sdk/usr/lib -F/opt/macos-sdk/System/Library/Frameworks -w $ARGS
|
||||
ZIGWRAP
|
||||
RUN chmod +x /usr/local/bin/zcc-darwin-arm64
|
||||
|
||||
# Darwin amd64
|
||||
COPY <<'ZIGWRAP' /usr/local/bin/zcc-darwin-amd64
|
||||
#!/bin/sh
|
||||
ARGS=""
|
||||
SKIP_NEXT=0
|
||||
for arg in "$@"; do
|
||||
if [ $SKIP_NEXT -eq 1 ]; then
|
||||
SKIP_NEXT=0
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-target) SKIP_NEXT=1 ;;
|
||||
-mmacosx-version-min=*) ;;
|
||||
*) ARGS="$ARGS $arg" ;;
|
||||
esac
|
||||
done
|
||||
exec zig cc -fno-sanitize=all -target x86_64-macos-none -isysroot /opt/macos-sdk -I/opt/macos-sdk/usr/include -L/opt/macos-sdk/usr/lib -F/opt/macos-sdk/System/Library/Frameworks -w $ARGS
|
||||
ZIGWRAP
|
||||
RUN chmod +x /usr/local/bin/zcc-darwin-amd64
|
||||
|
||||
# Windows amd64 - uses Zig's bundled mingw
|
||||
COPY <<'ZIGWRAP' /usr/local/bin/zcc-windows-amd64
|
||||
#!/bin/sh
|
||||
ARGS=""
|
||||
SKIP_NEXT=0
|
||||
for arg in "$@"; do
|
||||
if [ $SKIP_NEXT -eq 1 ]; then
|
||||
SKIP_NEXT=0
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-target) SKIP_NEXT=1 ;;
|
||||
-Wl,*) ;;
|
||||
*) ARGS="$ARGS $arg" ;;
|
||||
esac
|
||||
done
|
||||
exec zig cc -target x86_64-windows-gnu $ARGS
|
||||
ZIGWRAP
|
||||
RUN chmod +x /usr/local/bin/zcc-windows-amd64
|
||||
|
||||
# Windows arm64 - uses Zig's bundled mingw
|
||||
COPY <<'ZIGWRAP' /usr/local/bin/zcc-windows-arm64
|
||||
#!/bin/sh
|
||||
ARGS=""
|
||||
SKIP_NEXT=0
|
||||
for arg in "$@"; do
|
||||
if [ $SKIP_NEXT -eq 1 ]; then
|
||||
SKIP_NEXT=0
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-target) SKIP_NEXT=1 ;;
|
||||
-Wl,*) ;;
|
||||
*) ARGS="$ARGS $arg" ;;
|
||||
esac
|
||||
done
|
||||
exec zig cc -target aarch64-windows-gnu $ARGS
|
||||
ZIGWRAP
|
||||
RUN chmod +x /usr/local/bin/zcc-windows-arm64
|
||||
|
||||
# Build script
|
||||
COPY <<'SCRIPT' /usr/local/bin/build.sh
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
OS=${1:-darwin}
|
||||
ARCH=${2:-arm64}
|
||||
|
||||
case "${OS}-${ARCH}" in
|
||||
darwin-arm64|darwin-aarch64)
|
||||
export CC=zcc-darwin-arm64
|
||||
export GOARCH=arm64
|
||||
export GOOS=darwin
|
||||
;;
|
||||
darwin-amd64|darwin-x86_64)
|
||||
export CC=zcc-darwin-amd64
|
||||
export GOARCH=amd64
|
||||
export GOOS=darwin
|
||||
;;
|
||||
linux-arm64|linux-aarch64)
|
||||
export CC=gcc
|
||||
export GOARCH=arm64
|
||||
export GOOS=linux
|
||||
;;
|
||||
linux-amd64|linux-x86_64)
|
||||
export CC=gcc
|
||||
export GOARCH=amd64
|
||||
export GOOS=linux
|
||||
;;
|
||||
windows-arm64|windows-aarch64)
|
||||
export CC=zcc-windows-arm64
|
||||
export GOARCH=arm64
|
||||
export GOOS=windows
|
||||
;;
|
||||
windows-amd64|windows-x86_64)
|
||||
export CC=zcc-windows-amd64
|
||||
export GOARCH=amd64
|
||||
export GOOS=windows
|
||||
;;
|
||||
*)
|
||||
echo "Usage: <os> <arch>"
|
||||
echo " os: darwin, linux, windows"
|
||||
echo " arch: amd64, arm64"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
export CGO_ENABLED=1
|
||||
export CGO_CFLAGS="-w"
|
||||
|
||||
# Build frontend if exists and not already built (host may have built it)
|
||||
if [ -d "frontend" ] && [ -f "frontend/package.json" ] && [ ! -d "frontend/dist" ]; then
|
||||
(cd frontend && npm install --silent && npm run build --silent)
|
||||
fi
|
||||
|
||||
# Build
|
||||
APP=${APP_NAME:-$(basename $(pwd))}
|
||||
mkdir -p bin
|
||||
|
||||
EXT=""
|
||||
LDFLAGS="-s -w"
|
||||
if [ "$GOOS" = "windows" ]; then
|
||||
EXT=".exe"
|
||||
LDFLAGS="-s -w -H windowsgui"
|
||||
fi
|
||||
|
||||
TAGS="production"
|
||||
if [ -n "$EXTRA_TAGS" ]; then
|
||||
TAGS="${TAGS},${EXTRA_TAGS}"
|
||||
fi
|
||||
|
||||
COMPILER="go build"
|
||||
if [ "$OBFUSCATED" = "true" ]; then
|
||||
COMPILER="garble ${GARBLE_ARGS} build"
|
||||
TAGS="${TAGS},wails_obfuscated"
|
||||
fi
|
||||
|
||||
${COMPILER} -tags "$TAGS" -trimpath -buildvcs=false -ldflags="$LDFLAGS" -o bin/${APP}-${GOOS}-${GOARCH}${EXT} .
|
||||
echo "Built: bin/${APP}-${GOOS}-${GOARCH}${EXT}"
|
||||
SCRIPT
|
||||
RUN chmod +x /usr/local/bin/build.sh
|
||||
|
||||
WORKDIR /app
|
||||
ENTRYPOINT ["/usr/local/bin/build.sh"]
|
||||
CMD ["darwin", "arm64"]
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# Wails Server Mode Dockerfile
|
||||
# Multi-stage build for minimal image size
|
||||
|
||||
# Build stage
|
||||
FROM golang:alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Remove local replace directive if present (for production builds)
|
||||
RUN sed -i '/^replace/d' go.mod || true
|
||||
|
||||
# Download dependencies
|
||||
RUN go mod tidy
|
||||
|
||||
# Build the server binary
|
||||
RUN go build -tags server -ldflags="-s -w" -o server .
|
||||
|
||||
# Runtime stage - minimal image
|
||||
FROM gcr.io/distroless/static-debian12
|
||||
|
||||
# Copy the binary
|
||||
COPY --from=builder /app/server /server
|
||||
|
||||
# Copy frontend assets
|
||||
COPY --from=builder /app/frontend/dist /frontend/dist
|
||||
|
||||
# Expose the default port
|
||||
EXPOSE 8080
|
||||
|
||||
# Bind to all interfaces (required for Docker)
|
||||
# Can be overridden at runtime with -e WAILS_SERVER_HOST=...
|
||||
ENV WAILS_SERVER_HOST=0.0.0.0
|
||||
|
||||
# Run the server
|
||||
ENTRYPOINT ["/server"]
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
version: '3'
|
||||
|
||||
includes:
|
||||
common: ../Taskfile.yml
|
||||
|
||||
vars:
|
||||
# Signing configuration - edit these values for your project
|
||||
# PGP_KEY: "path/to/signing-key.asc"
|
||||
# SIGN_ROLE: "builder" # Options: origin, maint, archive, builder
|
||||
#
|
||||
# Password is stored securely in system keychain. Run: wails3 setup signing
|
||||
|
||||
# Docker image for cross-compilation (used when building on non-Linux or no CC available)
|
||||
CROSS_IMAGE: wails-cross
|
||||
|
||||
tasks:
|
||||
build:
|
||||
summary: Builds the application for Linux
|
||||
cmds:
|
||||
# Linux requires CGO - use Docker when:
|
||||
# 1. Cross-compiling from non-Linux, OR
|
||||
# 2. No C compiler is available, OR
|
||||
# 3. Target architecture differs from host architecture (cross-arch compilation)
|
||||
- task: '{{if and (eq OS "linux") (eq .HAS_CC "true") (eq .TARGET_ARCH ARCH)}}build:native{{else}}build:docker{{end}}'
|
||||
vars:
|
||||
ARCH: '{{.ARCH}}'
|
||||
DEV: '{{.DEV}}'
|
||||
OUTPUT: '{{.OUTPUT}}'
|
||||
EXTRA_TAGS: '{{.EXTRA_TAGS}}'
|
||||
OBFUSCATED: '{{.OBFUSCATED}}'
|
||||
GARBLE_ARGS: '{{.GARBLE_ARGS}}'
|
||||
vars:
|
||||
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
|
||||
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
|
||||
# Determine target architecture (defaults to host ARCH if not specified)
|
||||
TARGET_ARCH: '{{.ARCH | default ARCH}}'
|
||||
# Check if a C compiler is available (gcc or clang) — cross-platform via wails3 tool
|
||||
HAS_CC:
|
||||
sh: 'wails3 tool has-cc'
|
||||
|
||||
build:native:
|
||||
summary: Builds the application natively on Linux
|
||||
internal: true
|
||||
deps:
|
||||
- task: common:go:mod:tidy
|
||||
- task: common:build:frontend
|
||||
vars:
|
||||
BUILD_FLAGS:
|
||||
ref: .BUILD_FLAGS
|
||||
OBFUSCATED:
|
||||
ref: .OBFUSCATED
|
||||
DEV:
|
||||
ref: .DEV
|
||||
- task: common:generate:icons
|
||||
- task: generate:dotdesktop
|
||||
preconditions:
|
||||
- sh: '{{if eq .OBFUSCATED "true"}}command -v garble >/dev/null 2>&1{{else}}true{{end}}'
|
||||
msg: "garble is required for obfuscated builds. Install it with: go install mvdan.cc/garble@v0.16.0 (requires Go 1.24+). See https://github.com/burrowers/garble/releases for version/toolchain compatibility."
|
||||
cmds:
|
||||
- '{{if eq .OBFUSCATED "true"}}garble {{.GARBLE_ARGS}} build{{else}}go build{{end}} {{.BUILD_FLAGS}} -o {{.OUTPUT}}'
|
||||
vars:
|
||||
BUILD_FLAGS: '{{if eq .DEV "true"}}{{if or .EXTRA_TAGS (eq .OBFUSCATED "true")}}-tags {{if eq .OBFUSCATED "true"}}wails_obfuscated{{if .EXTRA_TAGS}},{{end}}{{end}}{{.EXTRA_TAGS}} {{end}}-buildvcs=false -gcflags=all="-l"{{else}}-tags production{{if eq .OBFUSCATED "true"}},wails_obfuscated{{end}}{{if .EXTRA_TAGS}},{{.EXTRA_TAGS}}{{end}} -trimpath -buildvcs=false -ldflags="-w -s"{{end}}'
|
||||
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
|
||||
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
|
||||
env:
|
||||
GOOS: linux
|
||||
CGO_ENABLED: 1
|
||||
GOARCH: '{{.ARCH | default ARCH}}'
|
||||
|
||||
build:docker:
|
||||
summary: Builds for Linux using Docker (for non-Linux hosts or when no C compiler available)
|
||||
internal: true
|
||||
deps:
|
||||
- task: common:build:frontend
|
||||
vars:
|
||||
OBFUSCATED:
|
||||
ref: .OBFUSCATED
|
||||
- task: common:generate:icons
|
||||
- task: generate:dotdesktop
|
||||
preconditions:
|
||||
- sh: docker info > /dev/null 2>&1
|
||||
msg: "Docker is required for cross-compilation to Linux. Please install Docker."
|
||||
- sh: docker image inspect {{.CROSS_IMAGE}} > /dev/null 2>&1
|
||||
msg: |
|
||||
Docker image '{{.CROSS_IMAGE}}' not found.
|
||||
Build it first: wails3 task setup:docker
|
||||
cmds:
|
||||
- docker run --rm -v "{{.ROOT_DIR}}:/app" {{.DOCKER_MOUNTS}} -e APP_NAME="{{.APP_NAME}}" {{if .EXTRA_TAGS}}-e EXTRA_TAGS="{{.EXTRA_TAGS}}"{{end}} {{if eq .OBFUSCATED "true"}}-e OBFUSCATED=true{{end}} {{if .GARBLE_ARGS}}-e GARBLE_ARGS="{{.GARBLE_ARGS}}"{{end}} "{{.CROSS_IMAGE}}" linux {{.DOCKER_ARCH}}
|
||||
- cmd: docker run --rm -v "{{.ROOT_DIR}}:/app" alpine chown -R $(id -u):$(id -g) /app/bin
|
||||
platforms: [linux, darwin]
|
||||
- mkdir -p {{.BIN_DIR}}
|
||||
- mv "bin/{{.APP_NAME}}-linux-{{.DOCKER_ARCH}}" "{{.OUTPUT}}"
|
||||
vars:
|
||||
DOCKER_ARCH: '{{.ARCH | default "amd64"}}'
|
||||
DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}'
|
||||
OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}'
|
||||
# Generate Docker volume mounts: Go module cache + go.mod replace directives
|
||||
# Uses wails3 tool docker-mounts for cross-platform compatibility (Windows/Linux/macOS)
|
||||
DOCKER_MOUNTS:
|
||||
sh: 'wails3 tool docker-mounts'
|
||||
|
||||
package:
|
||||
summary: Packages the application for Linux
|
||||
deps:
|
||||
- task: build
|
||||
cmds:
|
||||
- task: create:appimage
|
||||
- task: create:deb
|
||||
- task: create:rpm
|
||||
- task: create:aur
|
||||
|
||||
create:appimage:
|
||||
summary: Creates an AppImage
|
||||
dir: build/linux/appimage
|
||||
deps:
|
||||
- task: build
|
||||
- task: generate:dotdesktop
|
||||
cmds:
|
||||
- cp "{{.APP_BINARY}}" "{{.APP_NAME}}"
|
||||
- cp ../../appicon.png "{{.APP_NAME}}.png"
|
||||
- wails3 generate appimage -binary "{{.APP_NAME}}" -icon {{.ICON}} -desktopfile {{.DESKTOP_FILE}} -outputdir {{.OUTPUT_DIR}} -builddir {{.ROOT_DIR}}/build/linux/appimage/build
|
||||
vars:
|
||||
APP_NAME: '{{.APP_NAME}}'
|
||||
APP_BINARY: '../../../bin/{{.APP_NAME}}'
|
||||
ICON: '{{.APP_NAME}}.png'
|
||||
DESKTOP_FILE: '../{{.APP_NAME}}.desktop'
|
||||
OUTPUT_DIR: '../../../bin'
|
||||
|
||||
create:deb:
|
||||
summary: Creates a deb package
|
||||
deps:
|
||||
- task: build
|
||||
cmds:
|
||||
- task: generate:dotdesktop
|
||||
- task: generate:deb
|
||||
|
||||
create:rpm:
|
||||
summary: Creates a rpm package
|
||||
deps:
|
||||
- task: build
|
||||
cmds:
|
||||
- task: generate:dotdesktop
|
||||
- task: generate:rpm
|
||||
|
||||
create:aur:
|
||||
summary: Creates a arch linux packager package
|
||||
deps:
|
||||
- task: build
|
||||
cmds:
|
||||
- task: generate:dotdesktop
|
||||
- task: generate:aur
|
||||
|
||||
generate:deb:
|
||||
summary: Creates a deb package
|
||||
cmds:
|
||||
- wails3 tool package -name "{{.APP_NAME}}" -format deb -config ./build/linux/nfpm/nfpm.yaml -out {{.ROOT_DIR}}/bin
|
||||
|
||||
generate:rpm:
|
||||
summary: Creates a rpm package
|
||||
cmds:
|
||||
- wails3 tool package -name "{{.APP_NAME}}" -format rpm -config ./build/linux/nfpm/nfpm.yaml -out {{.ROOT_DIR}}/bin
|
||||
|
||||
generate:aur:
|
||||
summary: Creates a arch linux packager package
|
||||
cmds:
|
||||
- wails3 tool package -name "{{.APP_NAME}}" -format archlinux -config ./build/linux/nfpm/nfpm.yaml -out {{.ROOT_DIR}}/bin
|
||||
|
||||
generate:dotdesktop:
|
||||
summary: Generates a `.desktop` file
|
||||
dir: build
|
||||
cmds:
|
||||
- mkdir -p {{.ROOT_DIR}}/build/linux/appimage
|
||||
- wails3 generate .desktop -name "{{.APP_NAME}}" -exec "{{.EXEC}}" -icon "{{.ICON}}" -outputfile "{{.ROOT_DIR}}/build/linux/{{.APP_NAME}}.desktop" -categories "{{.CATEGORIES}}"
|
||||
vars:
|
||||
APP_NAME: '{{.APP_NAME}}'
|
||||
EXEC: '{{.APP_NAME}}'
|
||||
ICON: '{{.APP_NAME}}'
|
||||
CATEGORIES: 'Development;'
|
||||
OUTPUTFILE: '{{.ROOT_DIR}}/build/linux/{{.APP_NAME}}.desktop'
|
||||
|
||||
run:
|
||||
cmds:
|
||||
- '{{.BIN_DIR}}/{{.APP_NAME}}'
|
||||
|
||||
sign:deb:
|
||||
summary: Signs the DEB package
|
||||
desc: |
|
||||
Signs the .deb package with a PGP key.
|
||||
Configure PGP_KEY in the vars section at the top of this file.
|
||||
Password is retrieved from system keychain (run: wails3 setup signing)
|
||||
deps:
|
||||
- task: create:deb
|
||||
cmds:
|
||||
- wails3 tool sign --input "{{.BIN_DIR}}/{{.APP_NAME}}*.deb" --pgp-key {{.PGP_KEY}} {{if .SIGN_ROLE}}--role {{.SIGN_ROLE}}{{end}}
|
||||
preconditions:
|
||||
- sh: '[ -n "{{.PGP_KEY}}" ]'
|
||||
msg: "PGP_KEY is required. Set it in the vars section at the top of build/linux/Taskfile.yml"
|
||||
|
||||
sign:rpm:
|
||||
summary: Signs the RPM package
|
||||
desc: |
|
||||
Signs the .rpm package with a PGP key.
|
||||
Configure PGP_KEY in the vars section at the top of this file.
|
||||
Password is retrieved from system keychain (run: wails3 setup signing)
|
||||
deps:
|
||||
- task: create:rpm
|
||||
cmds:
|
||||
- wails3 tool sign --input "{{.BIN_DIR}}/{{.APP_NAME}}*.rpm" --pgp-key {{.PGP_KEY}}
|
||||
preconditions:
|
||||
- sh: '[ -n "{{.PGP_KEY}}" ]'
|
||||
msg: "PGP_KEY is required. Set it in the vars section at the top of build/linux/Taskfile.yml"
|
||||
|
||||
sign:packages:
|
||||
summary: Signs all Linux packages (DEB and RPM)
|
||||
desc: |
|
||||
Signs both .deb and .rpm packages with a PGP key.
|
||||
Configure PGP_KEY in the vars section at the top of this file.
|
||||
Password is retrieved from system keychain (run: wails3 setup signing)
|
||||
cmds:
|
||||
- task: sign:deb
|
||||
- task: sign:rpm
|
||||
preconditions:
|
||||
- sh: '[ -n "{{.PGP_KEY}}" ]'
|
||||
msg: "PGP_KEY is required. Set it in the vars section at the top of build/linux/Taskfile.yml"
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2018-Present Lea Anthony
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Fail script on any error
|
||||
set -euxo pipefail
|
||||
|
||||
# Define variables
|
||||
APP_DIR="${APP_NAME}.AppDir"
|
||||
|
||||
# Create AppDir structure
|
||||
mkdir -p "${APP_DIR}/usr/bin"
|
||||
cp -r "${APP_BINARY}" "${APP_DIR}/usr/bin/"
|
||||
cp "${ICON_PATH}" "${APP_DIR}/"
|
||||
cp "${DESKTOP_FILE}" "${APP_DIR}/"
|
||||
|
||||
if [[ $(uname -m) == *x86_64* ]]; then
|
||||
# Download linuxdeploy and make it executable
|
||||
wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
|
||||
# Run linuxdeploy to bundle the application
|
||||
./linuxdeploy-x86_64.AppImage --appdir "${APP_DIR}" --output appimage
|
||||
else
|
||||
# Download linuxdeploy and make it executable (arm64)
|
||||
wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-aarch64.AppImage
|
||||
chmod +x linuxdeploy-aarch64.AppImage
|
||||
|
||||
# Run linuxdeploy to bundle the application (arm64)
|
||||
./linuxdeploy-aarch64.AppImage --appdir "${APP_DIR}" --output appimage
|
||||
fi
|
||||
|
||||
# Rename the generated AppImage
|
||||
mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage"
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=My Product
|
||||
Comment=A verstak application
|
||||
# The Exec line includes %u to pass the URL to the application
|
||||
Exec=/usr/local/bin/verstak %u
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=verstak
|
||||
Categories=Utility;
|
||||
StartupWMClass=verstak
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
# Feel free to remove those if you don't want/need to use them.
|
||||
# Make sure to check the documentation at https://nfpm.goreleaser.com
|
||||
#
|
||||
# The lines below are called `modelines`. See `:help modeline`
|
||||
|
||||
name: "verstak"
|
||||
arch: ${GOARCH}
|
||||
platform: "linux"
|
||||
version: "0.1.0"
|
||||
section: "default"
|
||||
priority: "extra"
|
||||
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
|
||||
description: "A verstak application"
|
||||
vendor: "My Company"
|
||||
homepage: "https://wails.io"
|
||||
license: "MIT"
|
||||
release: "1"
|
||||
|
||||
contents:
|
||||
- src: "./bin/verstak"
|
||||
dst: "/usr/local/bin/verstak"
|
||||
- src: "./build/appicon.png"
|
||||
dst: "/usr/share/icons/hicolor/128x128/apps/verstak.png"
|
||||
- src: "./build/linux/verstak.desktop"
|
||||
dst: "/usr/share/applications/verstak.desktop"
|
||||
|
||||
# Default dependencies for the GTK4 + WebKitGTK 6.0 stack (Ubuntu 24.04+ / Debian 13+)
|
||||
depends:
|
||||
- libgtk-4-1
|
||||
- libwebkitgtk-6.0-4
|
||||
|
||||
# Distribution-specific overrides for different package formats
|
||||
overrides:
|
||||
# RPM packages for Fedora / RHEL / AlmaLinux / Rocky Linux
|
||||
rpm:
|
||||
depends:
|
||||
- gtk4
|
||||
- webkitgtk6.0
|
||||
|
||||
# Arch Linux packages
|
||||
archlinux:
|
||||
depends:
|
||||
- gtk4
|
||||
- webkitgtk-6.0
|
||||
|
||||
# scripts section to ensure desktop database is updated after install
|
||||
scripts:
|
||||
postinstall: "./build/linux/nfpm/scripts/postinstall.sh"
|
||||
# You can also add preremove, postremove if needed
|
||||
# preremove: "./build/linux/nfpm/scripts/preremove.sh"
|
||||
# postremove: "./build/linux/nfpm/scripts/postremove.sh"
|
||||
|
||||
# If you build your app with -tags gtk3 (legacy WebKit2GTK 4.1 stack — supported through v3.0.x, removed in v3.1),
|
||||
# replace the depends/overrides above with these:
|
||||
#
|
||||
# depends:
|
||||
# - libgtk-3-0
|
||||
# - libwebkit2gtk-4.1-0
|
||||
# overrides:
|
||||
# rpm:
|
||||
# depends:
|
||||
# - gtk3
|
||||
# - webkit2gtk4.1
|
||||
# archlinux:
|
||||
# depends:
|
||||
# - gtk3
|
||||
# - webkit2gtk-4.1
|
||||
#
|
||||
# replaces:
|
||||
# - foobar
|
||||
# provides:
|
||||
# - bar
|
||||
# recommends:
|
||||
# - whatever
|
||||
# suggests:
|
||||
# - something-else
|
||||
# conflicts:
|
||||
# - not-foo
|
||||
# - not-bar
|
||||
# changelog: "changelog.yaml"
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Update desktop database for .desktop file changes
|
||||
# This makes the application appear in application menus and registers its capabilities.
|
||||
if command -v update-desktop-database >/dev/null 2>&1; then
|
||||
echo "Updating desktop database..."
|
||||
update-desktop-database -q /usr/share/applications
|
||||
else
|
||||
echo "Warning: update-desktop-database command not found. Desktop file may not be immediately recognized." >&2
|
||||
fi
|
||||
|
||||
# Update MIME database for custom URL schemes (x-scheme-handler)
|
||||
# This ensures the system knows how to handle your custom protocols.
|
||||
if command -v update-mime-database >/dev/null 2>&1; then
|
||||
echo "Updating MIME database..."
|
||||
update-mime-database -n /usr/share/mime
|
||||
else
|
||||
echo "Warning: update-mime-database command not found. Custom URL schemes may not be immediately recognized." >&2
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -0,0 +1 @@
|
|||
#!/bin/bash
|
||||
|
|
@ -0,0 +1 @@
|
|||
#!/bin/bash
|
||||
|
|
@ -0,0 +1 @@
|
|||
#!/bin/bash
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
//go:build gui
|
||||
// +build gui
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
gui "verstak/internal/gui"
|
||||
"verstak/internal/core/storage"
|
||||
)
|
||||
|
||||
func main() {
|
||||
vaultPath := "."
|
||||
if len(os.Args) > 1 {
|
||||
vaultPath = os.Args[1]
|
||||
}
|
||||
|
||||
abs, err := filepath.Abs(vaultPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
dbPath := filepath.Join(abs, ".verstak", "index.db")
|
||||
db, err := storage.Open(dbPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Open vault: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
srv := gui.NewServer(db, abs)
|
||||
addr, err := srv.Start()
|
||||
if err != nil {
|
||||
log.Fatalf("Start GUI: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("Верстак GUI:", addr)
|
||||
openBrowser(addr)
|
||||
|
||||
// Wait for interrupt.
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sig
|
||||
|
||||
srv.Stop()
|
||||
deferFunc()
|
||||
}
|
||||
|
||||
func openBrowser(url string) {
|
||||
var cmd *exec.Cmd
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
cmd = exec.Command("xdg-open", url)
|
||||
case "darwin":
|
||||
cmd = exec.Command("open", url)
|
||||
case "windows":
|
||||
cmd = exec.Command("cmd", "/c", "start", "", url)
|
||||
}
|
||||
if cmd != nil {
|
||||
go cmd.Start()
|
||||
}
|
||||
}
|
||||
|
||||
func deferFunc() {}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
Copyright 2020 The Inter Project Authors (https://github.com/rsms/inter)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
//@ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore: Unused imports
|
||||
import { Create as $Create } from "@wailsio/runtime";
|
||||
|
||||
Object.freeze($Create.Events);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/wails.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<title>Wails + Svelte</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build:dev": "vite build --minify false --mode development",
|
||||
"build": "vite build --mode production",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@wailsio/runtime": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
||||
"svelte": "^5.46.4",
|
||||
"vite": "^8.0.5"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,157 @@
|
|||
:root {
|
||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
|
||||
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 400;
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: rgba(27, 38, 54, 1);
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local(""),
|
||||
url("./Inter-Medium.ttf") format("truetype");
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 3em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-radius: 3px;
|
||||
border: none;
|
||||
margin: 0 0 0 20px;
|
||||
padding: 0 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.result {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
place-content: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
#app {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #e80000aa);
|
||||
}
|
||||
|
||||
.logo.vanilla:hover {
|
||||
filter: drop-shadow(0 0 2em #f7df1eaa);
|
||||
}
|
||||
|
||||
.result {
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin: 1.5rem auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 1rem;
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.input-box .btn:hover {
|
||||
background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%);
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.input-box .input {
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
outline: none;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 10px;
|
||||
color: black;
|
||||
background-color: rgba(240, 240, 240, 1);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
.input-box .input:hover {
|
||||
border: none;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.input-box .input:focus {
|
||||
border: none;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="26.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 308"><path fill="#FF3E00" d="M239.682 40.707C211.113-.182 154.69-12.301 113.895 13.69L42.247 59.356a82.198 82.198 0 0 0-37.135 55.056a86.566 86.566 0 0 0 8.536 55.576a82.425 82.425 0 0 0-12.296 30.719a87.596 87.596 0 0 0 14.964 66.244c28.574 40.893 84.997 53.007 125.787 27.016l71.648-45.664a82.182 82.182 0 0 0 37.135-55.057a86.601 86.601 0 0 0-8.53-55.577a82.409 82.409 0 0 0 12.29-30.718a87.573 87.573 0 0 0-14.963-66.244"></path><path fill="#FFF" d="M106.889 270.841c-23.102 6.007-47.497-3.036-61.103-22.648a52.685 52.685 0 0 1-9.003-39.85a49.978 49.978 0 0 1 1.713-6.693l1.35-4.115l3.671 2.697a92.447 92.447 0 0 0 28.036 14.007l2.663.808l-.245 2.659a16.067 16.067 0 0 0 2.89 10.656a17.143 17.143 0 0 0 18.397 6.828a15.786 15.786 0 0 0 4.403-1.935l71.67-45.672a14.922 14.922 0 0 0 6.734-9.977a15.923 15.923 0 0 0-2.713-12.011a17.156 17.156 0 0 0-18.404-6.832a15.78 15.78 0 0 0-4.396 1.933l-27.35 17.434a52.298 52.298 0 0 1-14.553 6.391c-23.101 6.007-47.497-3.036-61.101-22.649a52.681 52.681 0 0 1-9.004-39.849a49.428 49.428 0 0 1 22.34-33.114l71.664-45.677a52.218 52.218 0 0 1 14.563-6.398c23.101-6.007 47.497 3.036 61.101 22.648a52.685 52.685 0 0 1 9.004 39.85a50.559 50.559 0 0 1-1.713 6.692l-1.35 4.116l-3.67-2.693a92.373 92.373 0 0 0-28.037-14.013l-2.664-.809l.246-2.658a16.099 16.099 0 0 0-2.89-10.656a17.143 17.143 0 0 0-18.398-6.828a15.786 15.786 0 0 0-4.402 1.935l-71.67 45.674a14.898 14.898 0 0 0-6.73 9.975a15.9 15.9 0 0 0 2.709 12.012a17.156 17.156 0 0 0 18.404 6.832a15.841 15.841 0 0 0 4.402-1.935l27.345-17.427a52.147 52.147 0 0 1 14.552-6.397c23.101-6.006 47.497 3.037 61.102 22.65a52.681 52.681 0 0 1 9.003 39.848a49.453 49.453 0 0 1-22.34 33.12l-71.664 45.673a52.218 52.218 0 0 1-14.563 6.398"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
|
|
@ -0,0 +1,10 @@
|
|||
<script>
|
||||
// Stub — will be replaced with actual UI
|
||||
</script>
|
||||
|
||||
<div style="display:flex;align-items:center;justify-content:center;height:100vh;background:#13131f;color:#e4e4ef;font-family:sans-serif">
|
||||
<div style="text-align:center">
|
||||
<h1 style="font-size:28px;margin-bottom:8px">⚒ Верстак</h1>
|
||||
<p style="color:#8888a4">Wails desktop app — under construction</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { mount } from 'svelte'
|
||||
import App from './App.svelte'
|
||||
|
||||
mount(App, { target: document.getElementById('app') })
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
/// <reference types="svelte" />
|
||||
/// <reference types="vite/client" />
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* This file tells your IDE where the root of your JavaScript project is, and sets some
|
||||
* options that it can use to provide autocompletion and other features.
|
||||
*/
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"moduleResolution": "bundler",
|
||||
/**
|
||||
* The target and module can be set to ESNext to allow writing modern JavaScript,
|
||||
* and Vite will compile down to the level of "build.target" specified in the vite config file.
|
||||
* Builds will error if you use a feature that cannot be compiled down to the target level.
|
||||
*/
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"resolveJsonModule": true,
|
||||
/**
|
||||
* Enable checkJs if you'd like type checking in `.svelte` and `.js` files.
|
||||
*/
|
||||
"checkJs": false,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
},
|
||||
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte", "bindings"]
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { defineConfig } from "vite";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import wails from "@wailsio/runtime/plugins/vite";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
server: {
|
||||
host: "127.0.0.1",
|
||||
port: Number(process.env.WAILS_VITE_PORT) || 9245,
|
||||
strictPort: true,
|
||||
},
|
||||
plugins: [svelte(), wails("./bindings")],
|
||||
});
|
||||
42
go.mod
42
go.mod
|
|
@ -1,8 +1,48 @@
|
|||
module verstak
|
||||
|
||||
go 1.22
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/adrg/xdg v0.5.3 // indirect
|
||||
github.com/bep/debounce v1.2.1 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/coder/websocket v1.8.14 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
|
||||
github.com/ebitengine/purego v0.9.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.9.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.19.1 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/godbus/dbus/v5 v5.2.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 // indirect
|
||||
github.com/kevinburke/ssh_config v1.4.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
|
||||
github.com/leaanthony/u v1.1.1 // indirect
|
||||
github.com/lmittmann/tint v1.1.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.44 // indirect
|
||||
github.com/pjbgf/sha1cd v0.6.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/samber/lo v1.52.0 // indirect
|
||||
github.com/sergi/go-diff v1.4.0 // indirect
|
||||
github.com/skeema/knownhosts v1.3.2 // indirect
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.96 // indirect
|
||||
github.com/wailsapp/wails/webview2 v1.0.24 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/crypto v0.50.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
111
go.sum
111
go.sum
|
|
@ -1,5 +1,116 @@
|
|||
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
|
||||
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
|
||||
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
|
||||
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
|
||||
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
|
||||
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
||||
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||
github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g=
|
||||
github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=
|
||||
github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
|
||||
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmmBPA=
|
||||
github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw=
|
||||
github.com/go-git/go-git/v5 v5.19.1 h1:nX27AnaU43/K5bKktKwgBmR9lawoYVe1Ckg0rgzzN00=
|
||||
github.com/go-git/go-git/v5 v5.19.1/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
|
||||
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1 h1:njuLRcjAuMKr7kI3D85AXWkw6/+v9PwtV6M6o11sWHQ=
|
||||
github.com/jchv/go-winloader v0.0.0-20250406163304-c1995be93bd1/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ=
|
||||
github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A=
|
||||
github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
|
||||
github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M=
|
||||
github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
|
||||
github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=
|
||||
github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.44 h1:3VSe+xafpbzsLbdr2AWlAZk9yRHiBhTBakioXaCKTF8=
|
||||
github.com/mattn/go-sqlite3 v1.14.44/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
|
||||
github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU=
|
||||
github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw=
|
||||
github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg=
|
||||
github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.96 h1:FmZdo4LiUkFUvz8rZO8f4nGLm5af9J+D3sr3Flset2g=
|
||||
github.com/wailsapp/wails/v3 v3.0.0-alpha.96/go.mod h1:p1MUZwFPPQyx81cgejDvKIwU1+x/hndR+4z1uG5bw6s=
|
||||
github.com/wailsapp/wails/webview2 v1.0.24 h1:uULnjCSaRfMlU84mS3kjLgPsRosEOIusVK1nFOHZHzs=
|
||||
github.com/wailsapp/wails/webview2 v1.0.24/go.mod h1:sdf+s0nAdxlzVWf9SCxC15XaxnQPJeY+uU1Ucn3jHQM=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
// This file is only compiled with -tags gui.
|
||||
//go:build gui
|
||||
// +build gui
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
_ "embed"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"verstak/internal/core/storage"
|
||||
"verstak/internal/core/nodes"
|
||||
"verstak/internal/core/files"
|
||||
"verstak/internal/core/notes"
|
||||
"verstak/internal/core/actions"
|
||||
"verstak/internal/core/worklog"
|
||||
"verstak/internal/core/search"
|
||||
"verstak/internal/core/plugins"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
//go:embed all:frontend/dist
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
vaultPath := "."
|
||||
if len(os.Args) > 1 {
|
||||
vaultPath = os.Args[1]
|
||||
}
|
||||
|
||||
abs, err := filepath.Abs(vaultPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
dbPath := filepath.Join(abs, ".verstak", "index.db")
|
||||
db, err := storage.Open(dbPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Open vault: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Initialize core services (registered for Wails bindings).
|
||||
_ = nodes.NewRepository(db)
|
||||
_ = files.NewService(db, abs)
|
||||
_ = notes.NewService(db, abs, nil, nil)
|
||||
_ = actions.NewService(db)
|
||||
_ = worklog.NewService(db)
|
||||
_ = search.NewService(db)
|
||||
plugins.NewManager(abs).Discover()
|
||||
|
||||
app := application.New(application.Options{
|
||||
Name: "verstak",
|
||||
Description: "Verstak — local-first working vault",
|
||||
Assets: application.AssetOptions{
|
||||
Handler: application.AssetFileServerFS(assets),
|
||||
},
|
||||
})
|
||||
|
||||
app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Верстак",
|
||||
Width: 1200,
|
||||
Height: 800,
|
||||
})
|
||||
|
||||
if err := app.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
BIN
verstak-gui
BIN
verstak-gui
Binary file not shown.
|
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"verstak/internal/core/nodes"
|
||||
)
|
||||
|
||||
// WailsService exposes core methods to the Wails frontend.
|
||||
type WailsService struct{}
|
||||
|
||||
// ListRootNodes returns root-level nodes.
|
||||
func (s *WailsService) ListRootNodes(ctx context.Context) string {
|
||||
// This is a stub — actual implementation will use injected DB
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// ListChildren returns children of a node.
|
||||
func (s *WailsService) ListChildren(ctx context.Context, parentID string) string {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// CreateNode creates a new node.
|
||||
func (s *WailsService) CreateNode(ctx context.Context, parentID, nodeType, title, section string) string {
|
||||
return "{}"
|
||||
}
|
||||
|
||||
// ListFiles returns files for a node.
|
||||
func (s *WailsService) ListFiles(ctx context.Context, nodeID string) string {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// ListActions returns actions for a node.
|
||||
func (s *WailsService) ListActions(ctx context.Context, nodeID string) string {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// ListWorklog returns worklog entries for a node.
|
||||
func (s *WailsService) ListWorklog(ctx context.Context, nodeID string) string {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// Search performs a search query.
|
||||
func (s *WailsService) Search(ctx context.Context, query string) string {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// ListTemplates returns available templates.
|
||||
func (s *WailsService) ListTemplates(ctx context.Context) string {
|
||||
return "[]"
|
||||
}
|
||||
|
||||
// ListSections returns available sections.
|
||||
func (s *WailsService) ListSections(ctx context.Context) string {
|
||||
sections := []map[string]string{
|
||||
{"id": "today", "label": "Сегодня"},
|
||||
{"id": "inbox", "label": "Неразобранное"},
|
||||
{"id": "clients", "label": "Клиенты"},
|
||||
{"id": "projects", "label": "Проекты"},
|
||||
{"id": "recipes", "label": "Рецепты"},
|
||||
{"id": "documents", "label": "Документы"},
|
||||
{"id": "archive", "label": "Архив"},
|
||||
}
|
||||
data, _ := json.Marshal(sections)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// GetCurrentSelection returns current selection state.
|
||||
func (s *WailsService) GetCurrentSelection(ctx context.Context) string {
|
||||
sel := map[string]string{"kind": "section", "section": "today"}
|
||||
data, _ := json.Marshal(sel)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// OpenFile opens a file with the system application.
|
||||
func (s *WailsService) OpenFile(ctx context.Context, fileID string) string {
|
||||
return fmt.Sprintf("opened file %s", fileID)
|
||||
}
|
||||
|
||||
// OpenFolder opens a folder in the system file manager.
|
||||
func (s *WailsService) OpenFolder(ctx context.Context, nodeID string) string {
|
||||
return fmt.Sprintf("opened folder %s", nodeID)
|
||||
}
|
||||
|
||||
// Silence unused import.
|
||||
var _ = nodes.TypeCase
|
||||
Loading…
Reference in New Issue