Compare commits
No commits in common. "600b67bc1edea18885bbb31501ea641cb51b7a63" and "752b1bb4b8c3aba8a322f8ead9776a5a4a4eda4a" have entirely different histories.
600b67bc1e
...
752b1bb4b8
|
|
@ -21,9 +21,6 @@ go.work
|
||||||
# Wails
|
# Wails
|
||||||
frontend/dist/
|
frontend/dist/
|
||||||
frontend/node_modules/
|
frontend/node_modules/
|
||||||
frontend/bindings/
|
|
||||||
verstak-gui
|
|
||||||
verstak-cli
|
|
||||||
|
|
||||||
# VS Code
|
# VS Code
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
|
||||||
|
|
@ -1,355 +0,0 @@
|
||||||
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}}"
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?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>
|
|
||||||
|
Before Width: | Height: | Size: 698 B |
|
|
@ -1,51 +0,0 @@
|
||||||
{
|
|
||||||
"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.
|
Before Width: | Height: | Size: 130 KiB |
|
|
@ -1,79 +0,0 @@
|
||||||
# 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
|
|
||||||
|
|
@ -1,212 +0,0 @@
|
||||||
# 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"]
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
# 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"]
|
|
||||||
|
|
@ -1,224 +0,0 @@
|
||||||
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"
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
#!/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"
|
|
||||||
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
[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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
# 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"
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
#!/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
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
//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() {}
|
||||||
566
docs/PLAN.md
566
docs/PLAN.md
|
|
@ -1,4 +1,4 @@
|
||||||
# Верстак — Пошаговый план разработки
|
# Верстак — Пошаговый план реализации
|
||||||
|
|
||||||
## Принципы работы
|
## Принципы работы
|
||||||
|
|
||||||
|
|
@ -16,246 +16,359 @@
|
||||||
| 3 | Nodes Repository + CRUD + CLI Node | ✅ выполнен |
|
| 3 | Nodes Repository + CRUD + CLI Node | ✅ выполнен |
|
||||||
| 4 | Vault Files: Trash + File Service + CLI File | ✅ выполнен |
|
| 4 | Vault Files: Trash + File Service + CLI File | ✅ выполнен |
|
||||||
| 5 | Markdown Notes: Create/Read/Save + CLI Note | ✅ выполнен |
|
| 5 | Markdown Notes: Create/Read/Save + CLI Note | ✅ выполнен |
|
||||||
| 6 | GUI (browser prototype): Sidebar + Main Panel | ✅ выполнен |
|
| 6 | Wails GUI MVP: Sidebar + Main Panel | ✅ выполнен (Go HTTP SPA) |
|
||||||
| 7 | Actions + Worklog | ✅ выполнен |
|
| 7 | Actions: Run URL/File/Command + GUI Tab | ✅ выполнен |
|
||||||
| 8 | FTS5 Search | ✅ выполнен |
|
| 8 | Worklog: Entries + Report + GUI Tab | ✅ выполнен |
|
||||||
| 9 | Section assignment + Sidebar filtering | ✅ выполнен |
|
| 9 | FTS5 Search: Rebuild Index + GUI Search Bar | ✅ выполнен |
|
||||||
| 10 | Plugin Manager (discovery + templates) | ✅ выполнен |
|
| 10 | Plugins System (Lua + Templates) | ✅ выполнен |
|
||||||
| 11 | **Wails Desktop GUI** | ⬜ не начат |
|
| 11 | Sync Server Skeleton | ⬜ не начат |
|
||||||
| 12 | **Files/Folders full workflow** | ⬜ не начат |
|
| 12 | Sync Client MVP | ⬜ не начат |
|
||||||
| 13 | **Drag-and-drop** | ⬜ не начат |
|
| 13 | Activity + File Scanner/Watcher | ⬜ не начат |
|
||||||
| 14 | **MVP stabilization** | ⬜ не начат |
|
| 14 | TUI MVP (Bubble Tea) | ⬜ не начат |
|
||||||
| 15 | Sync Server Skeleton | 🔒 приостановлен |
|
| 15 | Integrity Check + Repair + Vault Restore | ⬜ не начат |
|
||||||
| 16 | Sync Client MVP | 🔒 приостановлен |
|
| 16 | Plugins System (Lua + Templates) | ⬜ не начат |
|
||||||
| 17 | Activity + File Scanner/Watcher | 🔒 приостановлен |
|
|
||||||
| 18 | TUI MVP (Bubble Tea) | 🔒 приостановлен |
|
|
||||||
| 19 | Integrity Check + Repair | 🔒 приостановлен |
|
|
||||||
| 20 | Plugins: Lua runtime | 🔒 приостановлен |
|
|
||||||
| 21 | DokuWiki Importer (plugin) | 🔒 приостановлен |
|
|
||||||
|
|
||||||
> 🔒 = **PAUSED** — не начинать до завершения шага 14 (MVP stabilization).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Выполненные шаги (1-10)
|
## ШАГ 1 — Git Init + Skeleton
|
||||||
|
|
||||||
### ШАГ 1 — Git Init + Skeleton
|
**Цель:** репозиторий создан, пустая структура, "hello world" билдится.
|
||||||
- go module `verstak`, структура cmd/internal/migrations
|
|
||||||
- CLI `verstak --version`
|
**Acceptance:**
|
||||||
|
- `go build ./...` проходит
|
||||||
|
- `go test ./...` проходит
|
||||||
|
- `verstak --version` выводит версию
|
||||||
|
- Повторный init безопасен
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- git init, .gitignore (Go, Wails)
|
||||||
|
- `go mod init verstak`
|
||||||
|
- Структура: `cmd/verstak/`, `internal/core/`, `migrations/`
|
||||||
|
- `cmd/verstak/main.go`: --version flag
|
||||||
- README.md
|
- README.md
|
||||||
|
|
||||||
### ШАГ 2 — Init + SQLite
|
**Commit:** `step 1: skeleton`
|
||||||
- storage.go: DB wrapper, migration runner
|
|
||||||
- vault.go: Init() создаёт .verstak/ + index.db
|
|
||||||
- config.go: YAML config
|
|
||||||
|
|
||||||
### ШАГ 3 — Nodes Repository
|
|
||||||
- Node struct + CRUD (Create, Get, ListChildren, ListRoots, UpdateTitle, Move, SoftDelete)
|
|
||||||
- Meta KV + tests
|
|
||||||
|
|
||||||
### ШАГ 4 — Files
|
|
||||||
- FileService: AddExternal, CopyIntoVault, Get, ListByNode, MarkMissing, DeleteToTrash, Open
|
|
||||||
- file_test.go: 5 tests
|
|
||||||
|
|
||||||
### ШАГ 5 — Notes
|
|
||||||
- NoteService: Create, Read, Save (с backup), Delete
|
|
||||||
- note_test.go: 3 tests
|
|
||||||
|
|
||||||
### ШАГ 6 — GUI (browser prototype)
|
|
||||||
- Go HTTP SPA на случайном порту
|
|
||||||
- Sidebar tree + разделы (Сегодня, Неразобранное, Клиенты, Проекты...)
|
|
||||||
- Dashboard дела + вкладки (Обзор, Заметки, Файлы, Действия, Журнал, Активность)
|
|
||||||
- Модальное окно "+ Добавить" с выбором типа
|
|
||||||
- Поиск по корневым нодам
|
|
||||||
- **Это legacy prototype — не развивать как основной GUI**
|
|
||||||
|
|
||||||
### ШАГ 7 — Actions + Worklog
|
|
||||||
- ActionService: Create, Get, ListByNode, Delete, Run (open_url/file/folder, run_command)
|
|
||||||
- WorklogService: Add, Update, ListByNode, Delete, SumMinutes, Report
|
|
||||||
- CLI: `action add/list/run/delete`, `log add/list/report`
|
|
||||||
- GUI вкладки с кнопками действий и журналом работ
|
|
||||||
|
|
||||||
### ШАГ 8 — FTS5 Search
|
|
||||||
- SearchService: Index, Remove, Rebuild, Search (FTS5 MATCH)
|
|
||||||
- FTS5 virtual table создаётся лениво (работает с/без FTS5)
|
|
||||||
- Fallback на LIKE по заголовкам нод
|
|
||||||
- CLI: `verstak index rebuild`
|
|
||||||
- GUI search bar
|
|
||||||
|
|
||||||
### ШАГ 9 — Section assignment
|
|
||||||
- Колонка `section` в nodes (clients/projects/recipes/documents/archive/inbox)
|
|
||||||
- Фильтрация разделов по `?section=` в API
|
|
||||||
- Root-ноды без section → inbox
|
|
||||||
|
|
||||||
### ШАГ 10 — Plugin Manager
|
|
||||||
- Discovery: `.verstak/plugins/<name>/plugin.json`
|
|
||||||
- Enable/disable, templates → pre-filled node trees
|
|
||||||
- Built-in шаблон "Клиент" (Overview + Документы/Переписка/Скриншоты)
|
|
||||||
- Template selector в модалке создания дела
|
|
||||||
- POST /api/nodes/from-template
|
|
||||||
- CLI: `plugin list/enable/disable/templates`
|
|
||||||
- Lua runtime — stub (placeholder)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Текущий этап: ШАГ 11 — Wails Desktop GUI
|
## ШАГ 2 — Init + SQLite + First Migration
|
||||||
|
|
||||||
**Целевой commit:** `gui/wails-file-workflow`
|
**Цель:** `verstak init --vault ./test` создаёт vault с index.db.
|
||||||
|
|
||||||
Архитектура:
|
**Acceptance:**
|
||||||
|
- `go test ./...` проходит
|
||||||
|
- init создаёт `.verstak/index.db`
|
||||||
|
- повторный init безопасен
|
||||||
|
|
||||||
```
|
**Действия:**
|
||||||
┌─────────────────────────────────────────────────┐
|
- migration runner (cmd + SQL migrations/)
|
||||||
│ Frontend (Wails) │
|
- миграция 001_init.sql (таблица nodes)
|
||||||
│ frontend/src/ │
|
- `_ "github.com/mattn/go-sqlite3"` или modernc driver
|
||||||
│ App.svelte │
|
- CLI `init`: vault dir + `.verstak/` + `index.db`
|
||||||
│ components/Sidebar, TopBar, CaseView, ... │
|
|
||||||
│ stores/selection, nodes, files, ui │
|
|
||||||
│ styles/theme.css │
|
|
||||||
└──────────────────┬──────────────────────────────┘
|
|
||||||
│ Wails bindings
|
|
||||||
┌──────────────────▼──────────────────────────────┐
|
|
||||||
│ Go Core (internal/core/) │
|
|
||||||
│ nodes, vault, storage, notes, files, │
|
|
||||||
│ actions, worklog, search, plugins │
|
|
||||||
└──────────────────┬──────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌──────────────────▼──────────────────────────────┐
|
|
||||||
│ Vault filesystem + SQLite │
|
|
||||||
└─────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### Действия
|
**Commit:** `step 2: init + sqlite + first migration`
|
||||||
|
|
||||||
1. Создать Wails app skeleton (`wails init`)
|
|
||||||
2. Структура frontend/ — Svelte/Vue/vanilla TS
|
|
||||||
3. Backend bindings — методы Wails над core services
|
|
||||||
4. Перенести текущий UI shell из inline HTML в frontend
|
|
||||||
5. Оставить текущий `internal/gui/` как legacy (не удалять, но не развивать)
|
|
||||||
|
|
||||||
### Backend bindings (минимум)
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Nodes
|
|
||||||
ListSections() ([]SectionDTO, error)
|
|
||||||
ListNodes(section string) ([]NodeDTO, error)
|
|
||||||
GetNodeDetail(nodeID string) (NodeDetailDTO, error)
|
|
||||||
CreateNode(parentID, section, typ, title string) (NodeDTO, error)
|
|
||||||
FromTemplate(parentID, section, typ, title, template string) (NodeDTO, error)
|
|
||||||
DeleteNode(id string) error
|
|
||||||
MoveNode(id, parentID string) error
|
|
||||||
|
|
||||||
// Notes
|
|
||||||
CreateNote(parentID, title string) (NodeDTO, error)
|
|
||||||
ReadNote(noteID string) (string, error)
|
|
||||||
SaveNote(noteID, content string) error
|
|
||||||
|
|
||||||
// Files
|
|
||||||
ListFiles(nodeID string) ([]FileDTO, error)
|
|
||||||
AddPathCopy(nodeID, sourcePath string) ([]NodeDTO, error) // файл или папка
|
|
||||||
AddPathLink(nodeID, sourcePath string) ([]NodeDTO, error)
|
|
||||||
DeleteFileOrFolder(id string) error
|
|
||||||
OpenFile(id string) error
|
|
||||||
OpenFolder(id string) error
|
|
||||||
PickFile() (string, error)
|
|
||||||
PickDirectory() (string, error)
|
|
||||||
|
|
||||||
// Actions/Worklog/Search
|
|
||||||
ListActions(nodeID string) ([]ActionDTO, error)
|
|
||||||
RunAction(id string) error
|
|
||||||
CreateWorklog(nodeID, summary string, minutes int) (WorklogDTO, error)
|
|
||||||
Search(query string) ([]SearchResultDTO, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ШАГ 12 — Files/Folders full workflow
|
## ШАГ 3 — Nodes Repository + CRUD + CLI Node
|
||||||
|
|
||||||
### Core service extensions
|
**Цель:** можно создать/прочитать/переместить/удалить дело через CLI.
|
||||||
|
|
||||||
Расширить `files.Service`:
|
**Acceptance:**
|
||||||
|
- nodes + node_meta таблицы
|
||||||
|
- NodeRepository: Create, Get, ListChildren, UpdateTitle, Move, SoftDelete
|
||||||
|
- CLI: `node create`, `node list`, `node move`, `node delete`
|
||||||
|
- unit tests проходят
|
||||||
|
|
||||||
```go
|
**Действия:**
|
||||||
AddPathCopy(nodeID string, sourcePath string) ([]Node, error)
|
- Полная схема nodes (id, parent_id, type, title, slug, path, sort_order, created_at, updated_at, deleted_at, revision, device_id)
|
||||||
AddPathLink(nodeID string, sourcePath string) ([]Node, error)
|
- node_meta (node_id, key, value)
|
||||||
```
|
- Node struct + Repository
|
||||||
|
- UUID вместо auto-increment
|
||||||
|
- Soft delete (deleted_at)
|
||||||
|
- безопасный slug для path
|
||||||
|
- Tests: in-memory SQLite
|
||||||
|
|
||||||
Логика:
|
**Commit:** `step 3: nodes repository + CRUD`
|
||||||
- `os.Stat(sourcePath)` → если директория → рекурсивный обход
|
|
||||||
- Каждый файл → File node + file record
|
|
||||||
- Каждая папка → Folder node
|
|
||||||
- Структура сохраняется через parent_id
|
|
||||||
|
|
||||||
### Folder model
|
|
||||||
|
|
||||||
Папка = node type `folder` (не file record с mime=directory).
|
|
||||||
|
|
||||||
При импорте `romashka-docs/`:
|
|
||||||
```
|
|
||||||
Folder node: romashka-docs (type=folder)
|
|
||||||
File node: dogovor.docx (type=file)
|
|
||||||
Folder node: screenshots (type=folder)
|
|
||||||
File node: error.png (type=file)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Name conflict resolution
|
|
||||||
|
|
||||||
Если в target уже есть `docs`:
|
|
||||||
```
|
|
||||||
docs
|
|
||||||
docs (2)
|
|
||||||
docs (3)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Safety checks
|
|
||||||
|
|
||||||
При добавлении папки показать summary:
|
|
||||||
- количество файлов/папок
|
|
||||||
- общий размер
|
|
||||||
- предупреждение если > 1000 файлов, > 1 GB, содержит `.git`/`node_modules`/`.cache`
|
|
||||||
|
|
||||||
### Trash
|
|
||||||
|
|
||||||
- Soft delete node + children
|
|
||||||
- Vault files → `.verstak/trash`
|
|
||||||
- External files — только удалить связь
|
|
||||||
- Не `rm -rf`
|
|
||||||
|
|
||||||
### Tests
|
|
||||||
|
|
||||||
1. Copy single file → vault, record created, source intact
|
|
||||||
2. Link single file → no copy, external path saved
|
|
||||||
3. Copy folder → tree created, files in vault
|
|
||||||
4. Link folder → node created, no content copied
|
|
||||||
5. Delete vault file → soft-deleted, file in trash
|
|
||||||
6. Delete vault folder → children soft-deleted
|
|
||||||
7. Name conflict → no overwrite, safe suffix
|
|
||||||
8. Open file → mocked opener (no real app launch)
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ШАГ 13 — Drag-and-drop
|
## ШАГ 4 — Vault Files: Trash + File Service + CLI File
|
||||||
|
|
||||||
### External D&D
|
**Цель:** можно добавить файл в дело, открыть системным приложением, удалить в trash.
|
||||||
|
|
||||||
Drop target: активное дело / вкладка Файлы / Неразобранное.
|
**Acceptance:**
|
||||||
|
- `.verstak/trash/` создаётся при init
|
||||||
|
- copy file into vault работает
|
||||||
|
- open with system app работает
|
||||||
|
- delete-to-trash работает
|
||||||
|
- тесты проходят
|
||||||
|
|
||||||
После drop → диалог:
|
**Действия:**
|
||||||
```
|
- Таблица files (id, node_id, filename, path, storage_mode, size, sha256, mime, ...)
|
||||||
Добавить в "ООО Ромашка / Сайт"
|
- VaultService: CopyFile, LinkExternal, OpenFile, DeleteToTrash, RestoreFromTrash
|
||||||
Файлов: 3, Папок: 1, 240 MB
|
- CLI: `file add`, `file list`, `file open`, `file trash`
|
||||||
[Скопировать] [Переместить] [Привязать] [Отмена]
|
|
||||||
```
|
**Commit:** `step 4: vault files + trash + CLI`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ШАГ 14 — MVP stabilization
|
## ШАГ 5 — Markdown Notes: Create/Read/Save + CLI Note
|
||||||
|
|
||||||
- Smoke tests базовых сценариев
|
**Цель:** можно создать заметку, писать в неё, читать обратно.
|
||||||
- Проверка: дело → заметка → файл → папка → trash → перезапуск
|
|
||||||
- go test ./... pass
|
**Acceptance:**
|
||||||
- Обновление документации
|
- type "note" для nodes
|
||||||
- Остановка перед следующими фичами
|
- создать .md файл в vault
|
||||||
|
- save делает backup старой версии
|
||||||
|
- тесты проходят
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Таблица notes (node_id, file_id, format, original_format, encrypted)
|
||||||
|
- NoteService: CreateNote, ReadNote, SaveNote (с backup)
|
||||||
|
- CLI: `note create`, `note read`, `note write`
|
||||||
|
- Backup старой версии перед перезаписью
|
||||||
|
|
||||||
|
**Commit:** `step 5: markdown notes`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 6 — Wails GUI MVP
|
||||||
|
|
||||||
|
**Цель:** GUI запускается, видно дерево дел, можно создать дело и заметку.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- sidebar tree показывает дела
|
||||||
|
- create node работает
|
||||||
|
- markdown textarea editor с save
|
||||||
|
- file list + add file + open file
|
||||||
|
- главный пользовательский поток работает
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Wails app init (Go backend + Svelte/Vue)
|
||||||
|
- Backend bindings: NodeService, VaultService, NoteService
|
||||||
|
- Frontend: sidebar tree, main panel, modals, markdown editor
|
||||||
|
- Поток: дело → заметка → файл → открыть файл
|
||||||
|
|
||||||
|
**Commit:** `step 6: Wails GUI MVP`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 7 — Actions
|
||||||
|
|
||||||
|
**Цель:** можно создать кнопку "Открыть сайт", нажать, сайт открылся.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- open_url, open_file, open_folder, run_command
|
||||||
|
- confirm_required диалог
|
||||||
|
- action log
|
||||||
|
- GUI вкладка "Действия"
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Таблица actions
|
||||||
|
- ActionService: Run с confirm, exec.Command БЕЗ shell, args массивом
|
||||||
|
- CLI: `action add`, `action list`, `action run`
|
||||||
|
- GUI: вкладка с кнопками
|
||||||
|
|
||||||
|
**Commit:** `step 7: actions`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 8 — Worklog
|
||||||
|
|
||||||
|
**Цель:** можно записать "3ч обновил витрину", скопировать отчёт.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- add/edit/delete entry
|
||||||
|
- approximate minutes + billable flag
|
||||||
|
- copy report копирует в буфер
|
||||||
|
- GUI вкладка "Журнал"
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Таблица worklog_entries
|
||||||
|
- WorklogService: Add, Edit, Delete, CopyReport
|
||||||
|
- CLI: `worklog add`, `worklog list`, `worklog report`
|
||||||
|
- GUI: вкладка журнал + кнопка copy report
|
||||||
|
|
||||||
|
**Commit:** `step 8: worklog`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 9 — FTS5 Search
|
||||||
|
|
||||||
|
**Цель:** можно найти "витрину" по заметкам, файлам, журналу.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- `verstak index rebuild` перестраивает индекс
|
||||||
|
- поиск по node titles, note content, filenames, worklog summaries
|
||||||
|
- GUI search bar + результаты с type/path
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Таблица search_index (FTS5): node_id, title, content, path, tags, type
|
||||||
|
- Триггеры для автоматического обновления или manual rebuild
|
||||||
|
- SearchService: RebuildIndex, Search(query)
|
||||||
|
- CLI: `index rebuild`
|
||||||
|
- GUI: search bar в header
|
||||||
|
|
||||||
|
**Commit:** `step 9: FTS5 search`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 10 — Система плагинов (Lua + шаблоны дел)
|
||||||
|
|
||||||
|
**Цель:** можно положить Lua-скрипт в `.verstak/plugins/` — и он работает.
|
||||||
|
Без перекомпиляции программы.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- `.verstak/plugins/<name>/plugin.json` — мета
|
||||||
|
- `main.lua` — загрузка через gopher-lua
|
||||||
|
- `on_init`, `on_vault_open`, `on_node_create` хуки
|
||||||
|
- `verstak.node.register_type()` — новые типы дел
|
||||||
|
- `verstak.http.route()` — API для GUI
|
||||||
|
- шаблоны дела (JSON) → предзаполненное дерево
|
||||||
|
- песочница: нет io/os.execute, только API
|
||||||
|
- CLI: `verstak plugin list / install / enable`
|
||||||
|
- DokuWiki импортер — пример плагина в `contrib/plugins/importer-dokuwiki/`
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- `internal/core/plugins/manager.go` — сканирование, загрузка, валидация
|
||||||
|
- Lua runtime (gopher-lua) с песочницей
|
||||||
|
- Plugin API: node, config, activity, http, ui, vault
|
||||||
|
- Миграции плагинов (SQL)
|
||||||
|
- Реестр типов дел → GUI рендерит разные карточки
|
||||||
|
- CLI: plugin list/install/enable
|
||||||
|
- Базовый шаблон дела (client.json)
|
||||||
|
- Пример плагина: DokuWiki importerв `contrib/`
|
||||||
|
|
||||||
|
**Commit:** `step 10: plugins system`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 11 — Sync Server Skeleton
|
||||||
|
|
||||||
|
**Цель:** verstak-server отвечает на /health, /sync/push, /sync/pull, /blobs.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- HTTP server на отдельном порту
|
||||||
|
- API key auth
|
||||||
|
- blob storage by sha256
|
||||||
|
- GET /health, POST /sync/push, POST /sync/pull, POST /blobs/upload, GET /blobs/{sha256}
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- `cmd/verstak-server/main.go`
|
||||||
|
- SQLite server db
|
||||||
|
- Push/pull operations endpoints
|
||||||
|
- Blob upload/download with sha256 naming
|
||||||
|
|
||||||
|
**Commit:** `step 11: sync server skeleton`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 12 — Sync Client MVP
|
||||||
|
|
||||||
|
**Цель:** `verstak sync` отправляет локальные операции на сервер и получает обратно.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- sync_ops таблица
|
||||||
|
- операции создаются при каждом изменении
|
||||||
|
- push local ops + pull remote ops
|
||||||
|
- upload/download blobs
|
||||||
|
- conflict copy при неуверенности
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Таблица sync_ops (опционально добавить триггеры в repository)
|
||||||
|
- SyncClient: Push, Pull, UploadBlob, DownloadBlob
|
||||||
|
- CLI: `verstak sync`
|
||||||
|
- Server URL + API key в .verstak/config
|
||||||
|
|
||||||
|
**Commit:** `step 12: sync client MVP`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 13 — Activity + File Scanner/Watcher
|
||||||
|
|
||||||
|
**Цель:** фиксируется открытие/редактирование, scanner видит новые файлы.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- activity_events таблица
|
||||||
|
- scanner сравнивает реальность с SQLite
|
||||||
|
- watcher (fsnotify) ускоряет обнаружение
|
||||||
|
- экран "Активность" с группировкой по делу
|
||||||
|
- можно создать worklog из events
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- Таблица activity_events
|
||||||
|
- Запись событий из nodes/notes/files/actions
|
||||||
|
- Snapshot scanner (источник правды)
|
||||||
|
- fsnotify watcher (ускоритель)
|
||||||
|
- CLI: `scan`, `activity list`
|
||||||
|
- GUI: экран "Активность"
|
||||||
|
|
||||||
|
**Commit:** `step 13: activity + scanner/watcher`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 14 — TUI MVP (Bubble Tea)
|
||||||
|
|
||||||
|
**Цель:** быстрый поиск дела, добавление worklog, запуск action.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- fuzzy search tree
|
||||||
|
- open node
|
||||||
|
- add worklog
|
||||||
|
- run action
|
||||||
|
- sync now
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- `cmd/verstak-tui/main.go` с Bubble Tea
|
||||||
|
- Модели: search, node view, worklog form, action runner
|
||||||
|
- Не повторяет весь GUI — только быстрые действия
|
||||||
|
|
||||||
|
**Commit:** `step 14: TUI MVP`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 15 — Integrity Check + Repair + Vault Restore
|
||||||
|
|
||||||
|
**Цель:** `verstak vault check` находит проблемы, repair чинит, restore восстанавливает.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- check: missing files, orphan files, SQLite references, hash mismatch
|
||||||
|
- repair: устраняет найденные проблемы
|
||||||
|
- restore с сервера восстанавливает vault
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- CLI: `vault check` — сканирует и отчитывается
|
||||||
|
- CLI: `vault repair` — чинит найденное
|
||||||
|
- CLI: `restore --server <url> --api-key <key> --target <path>`
|
||||||
|
|
||||||
|
**Commit:** `step 15: integrity + restore`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ШАГ 16 — Система плагинов (Lua + шаблоны дел)
|
||||||
|
|
||||||
|
**Цель:** можно положить Lua-скрипт в `.verstak/plugins/` — и он работает.
|
||||||
|
|
||||||
|
**Acceptance:**
|
||||||
|
- `.verstak/plugins/<name>/plugin.json` — мета
|
||||||
|
- `main.lua` — загрузка через gopher-lua
|
||||||
|
- `on_init`, `on_vault_open`, `on_node_create` хуки
|
||||||
|
- `verstak.node.register_type()` — новые типы дел
|
||||||
|
- `verstak.http.route()` — API для GUI
|
||||||
|
- шаблоны дела (JSON) → предзаполненное дерево
|
||||||
|
- CLI: `verstak plugin list / install / enable`
|
||||||
|
|
||||||
|
**Действия:**
|
||||||
|
- `internal/core/plugins/manager.go` — сканирование, загрузка, валидация
|
||||||
|
- Lua runtime (gopher-lua) с песочницей
|
||||||
|
- Plugin API: node, config, activity, http, ui, vault
|
||||||
|
- Миграции плагинов (SQL)
|
||||||
|
- Реестр типов дел → GUI рендерит разные карточки
|
||||||
|
- CLI: plugin list/install/enable
|
||||||
|
- Базовый шаблон дела (client.json)
|
||||||
|
|
||||||
|
**Commit:** `step 10: plugins system`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -269,19 +382,10 @@ verstak/
|
||||||
|
|
||||||
cmd/
|
cmd/
|
||||||
verstak/ # CLI
|
verstak/ # CLI
|
||||||
verstak-gui/ # Wails GUI main
|
verstak-gui/ # Wails GUI
|
||||||
verstak-tui/ # Bubble Tea TUI
|
verstak-tui/ # Bubble Tea TUI
|
||||||
verstak-server/ # Sync server
|
verstak-server/ # Sync server
|
||||||
|
|
||||||
frontend/ # Wails frontend
|
|
||||||
package.json
|
|
||||||
wails.json
|
|
||||||
src/
|
|
||||||
App.svelte
|
|
||||||
components/
|
|
||||||
stores/
|
|
||||||
styles/
|
|
||||||
|
|
||||||
internal/
|
internal/
|
||||||
core/
|
core/
|
||||||
nodes/
|
nodes/
|
||||||
|
|
@ -296,11 +400,9 @@ verstak/
|
||||||
sync/
|
sync/
|
||||||
security/
|
security/
|
||||||
config/
|
config/
|
||||||
plugins/ # manager, lua (stub)
|
|
||||||
|
|
||||||
contrib/
|
|
||||||
plugins/
|
plugins/
|
||||||
importer-dokuwiki/
|
|
||||||
|
frontend/ # Wails frontend (Svelte/Vue)
|
||||||
|
|
||||||
migrations/
|
migrations/
|
||||||
001_init.sql
|
001_init.sql
|
||||||
|
|
@ -309,11 +411,15 @@ verstak/
|
||||||
004_add_notes.sql
|
004_add_notes.sql
|
||||||
005_add_actions.sql
|
005_add_actions.sql
|
||||||
006_add_worklog.sql
|
006_add_worklog.sql
|
||||||
|
007_add_activity.sql
|
||||||
|
008_add_fts.sql
|
||||||
|
009_add_sync.sql
|
||||||
```
|
```
|
||||||
|
|
||||||
## RAID
|
## RAID (Risks, Assumptions, Issues, Dependencies)
|
||||||
|
|
||||||
- **Критично:** Wails требует Node.js для frontend-сборки
|
- **Критично:** Wails v3 может быть нестабилен — проверить перед шагом 6
|
||||||
- **Критично:** go-sqlite3 + cgo; gcc уже установлен
|
- **Критично:** go-sqlite3 нужен cgo; modernc — чистый Go, выбрать до шага 2
|
||||||
- **Зависимость:** Steps 15+ ждут завершения step 14
|
- **Зависимость:** Шаги 12 (sync client) зависят от 11 (server)
|
||||||
- **Риск:** Wails v3 может быть нестабилен — проверить перед шагом 11
|
- **Зависимость:** Шаг 6 (GUI) лучше откладывать до стабильности core
|
||||||
|
- **Риск:** Svelte/Vue фронтенд потребует node/npm — подготовить
|
||||||
|
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
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.
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
//@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);
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
|
||||||
// This file is automatically generated. DO NOT EDIT
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
<!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
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"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.
|
|
@ -1,157 +0,0 @@
|
||||||
: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);
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<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>
|
|
||||||
|
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 8.8 KiB |
|
|
@ -1,10 +0,0 @@
|
||||||
<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>
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
import { mount } from 'svelte'
|
|
||||||
import App from './App.svelte'
|
|
||||||
|
|
||||||
mount(App, { target: document.getElementById('app') })
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
/// <reference types="svelte" />
|
|
||||||
/// <reference types="vite/client" />
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
/**
|
|
||||||
* 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"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
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,48 +1,8 @@
|
||||||
module verstak
|
module verstak
|
||||||
|
|
||||||
go 1.25.0
|
go 1.22
|
||||||
|
|
||||||
require (
|
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/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
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
111
go.sum
111
go.sum
|
|
@ -1,116 +1,5 @@
|
||||||
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 h1:3VSe+xafpbzsLbdr2AWlAZk9yRHiBhTBakioXaCKTF8=
|
||||||
github.com/mattn/go-sqlite3 v1.14.44/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
|
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 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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
||||||
73
guimain.go
73
guimain.go
|
|
@ -1,73 +0,0 @@
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
|
@ -1,88 +0,0 @@
|
||||||
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