Commit Graph
100 Commits
Author SHA1 Message Date
mirivlad d6ef3a973a feat: model inbox capture artifacts 2026-06-05 01:40:08 +08:00
mirivlad 2e86229350 fix: restrict inbox to captured artifacts 2026-06-05 01:35:27 +08:00
mirivlad 58a74acbf6 test: capture inbox and trash gui smoke 2026-06-05 01:07:51 +08:00
mirivlad cc83cd3476 feat: expose trash in gui 2026-06-05 01:05:57 +08:00
mirivlad 035f877280 feat: add interactive inbox view 2026-06-05 00:59:57 +08:00
mirivlad 02d68ca3f4 feat: edit suggestions before accepting worklog 2026-06-05 00:53:13 +08:00
mirivlad eb6a861310 feat: edit and delete worklog entries 2026-06-05 00:48:12 +08:00
mirivlad 272a7f870b docs: update gui verification workflow 2026-06-04 19:50:44 +08:00
mirivlad 644ec0ed00 test: cover sync conflict warnings 2026-06-04 19:48:02 +08:00
mirivlad cc59f928a8 test: harden file manager regressions 2026-06-04 19:44:28 +08:00
mirivlad 2284f893f8 test: exercise gui smoke actions 2026-06-04 19:39:27 +08:00
mirivlad cb6c06fdc5 fix: style workspace settings actions 2026-06-04 19:34:03 +08:00
mirivlad 767c03ba8c test: add rendered gui smoke harness 2026-06-04 18:59:07 +08:00
mirivlad 20e605bab7 chore: add gui smoke check 2026-06-04 07:49:34 +08:00
mirivlad cc157a2d36 fix: stabilize settings icons and back label 2026-06-04 07:47:40 +08:00
mirivlad c40d8c9dd3 fix: show sync warnings in settings 2026-06-04 03:53:17 +08:00
mirivlad 7641a311cc build: clean embedded assets before copy 2026-06-04 03:50:38 +08:00
mirivlad 7e709e140d build: refresh embedded gui assets 2026-06-04 03:49:12 +08:00
mirivlad 3a20e1b093 docs: update roadmap status from current code 2026-06-04 03:47:31 +08:00
mirivlad bb0bb608e3 chore: sync english locale keys 2026-06-04 03:44:25 +08:00
mirivlad 3c6bc097e1 fix: show manual sync conflicts in gui 2026-06-04 03:39:52 +08:00
mirivlad e2aad19cc4 fix: avoid outgoing ops during remote template apply 2026-06-04 03:36:44 +08:00
mirivlad 0c0b0d98c7 fix: keep plugin templates separate from system templates 2026-06-04 03:34:18 +08:00
mirivlad a526661825 docs: align vault storage documentation with code 2026-06-04 03:32:02 +08:00
mirivlad 58795b66b2 fix: keep default templates and plugins folder working 2026-06-04 03:28:32 +08:00
mirivlad 9d14ba50af test: restore vault and worklog test baseline 2026-06-04 03:25:04 +08:00
mirivlad a69dc845e6 fix: vault init on startup; add nil guards to all bindings; fix SA_ONSTACK signal crash; deduplicate settings button; add i18n for vault error 2026-06-04 00:37:14 +08:00
mirivlad f92394e3d7 feat: settings window polish, sync widget fix, dark form controls
- Fix: settings overlay uses on:click|self so sidebar clicks don't close it
- Fix: openSettings(section) supports opening at specific tab
- Fix: 'Настроить' opens Settings → Синхронизация instead of Общие
- Style: dark theme select with custom arrow, global :global() CSS
- Style: settings cards, section descriptions, button/layout polish
- Style: settings gear buttons (icon-button pattern, 32px, soft hover)
- Style: settings sidebar with disabled stubs, consistent icons
- i18n: add generalDesc, workspaceDesc, appearance, localization keys
2026-06-03 23:09:40 +08:00
mirivlad 23b3d07071 fix: tree DnD — correct cycle detection, reactive indicators, canonical reload
Backend:
- Fix MoveNode validation: wouldCreateCycle walks from newParentID up
  toward root, rejects if nodeID is encountered (parent into descendant)
- Allow moving descendant to ancestor (C into A) and child to root
- Add isContainerType validation for new parent
- Add 8 tests covering all scenarios + duplicate ID invariant

Frontend TreeNode.svelte:
- Build parent map from full tree (not just loaded children)
- canDrop uses parent map for cycle detection
- Reactive drop-valid/drop-invalid CSS via pre-computed dropAllowed map
- Keyed {#each nodes as node (node.id)} for correct identity tracking
- Auto-expand container on 600ms drag-over hover
- Proper dragleave detection (ignore transitions to child elements)
- Clean up state on dragend

Frontend App.svelte:
- reloadTreePreservingExpanded: fresh roots + children (no patching)
- Root area visual drop indicator (dashed outline)
- dragleave handler for root area

Clean up stale GUI dist assets
2026-06-03 05:27:20 +08:00
mirivlad 8cbf23a74d docs: update PLAN.md — mark steps 1-14 done, unpause 15-23, sync with current state 2026-06-03 05:15:46 +08:00
mirivlad b6a3a2238d fix: tab highlight reactivity, cleanup docs and build scripts
- Fix tab highlight not updating visually — switch from class={tabClass()}
  to Svelte's class:active directive for proper reactive class binding
- Rewrite README.md with full project structure, architecture, build guide
- Rewrite build.sh to build both GUI and server, output to build/
- Add scripts/build.sh for granular builds (gui/server/all)
- Add build/, frontend-dist/, and test vault dirs to .gitignore
- Remove stale binaries from project root
- Update AGENTS.md session summary
2026-06-03 05:08:58 +08:00
mirivlad 105657400b fix: context menu close, OpenFolder for TypeFile nodes, tab highlight visibility
- FileTreeRow handleShowInFolder now closes the menu (menuOpen = false)
- OpenFolder: TypeFile nodes with empty FsPath fall back to file record path
- Active tab background increased to rgba(99,102,241,0.12), weight 600, border #818cf8
2026-06-03 04:56:11 +08:00
mirivlad cc3500c14f fix: sidebar refresh, context menu position, show-in-explorer for all items
Sidebar refresh:
- addFile/addFolder now use currentFolderId || selectedNode.id as parent
- startImport stores pendingImportParent; confirmImport uses it
- setNodeChildren also updates node.has_children for toggle arrow reactivity
- navigateToFolder expands the folder node in sidebar tree

Context menu position:
- FileTreeRow stores menuX/menuY from contextmenu event coords
- Menu uses position:fixed with cursor-relative left/top and window clamp

Show in explorer:
- Sidebar context menu uses file.showInExplorer label
- en.js: add file.showInExplorer key
2026-06-03 04:46:42 +08:00
mirivlad 3c9b9edf8c fix: dynamic sidebar tree refresh after import
- reloadTreePreservingExpanded no longer replaces the whole tree,
  only patches children of expanded nodes in-place
- New refreshParentNode(nodeId) function updates a single parent's children
- createFile, duplicateItem, confirmImport use refreshParentNode instead of reloadTreePreservingExpanded
- No intermediate render where children are lost
2026-06-03 04:34:27 +08:00
mirivlad 81405ed61b fix: refresh sidebar tree after import/create/duplicate in files tab
- Call reloadTreePreservingExpanded after createFile, confirmImport, duplicateItem
- New folders created inside a case now appear in sidebar without restart
- Add AGENTS.md with build instructions
2026-06-03 04:28:41 +08:00
mirivlad baf57e993d feat: move-to-root, active tab highlight, show-in-explorer for all file items
- Add 'Move to root' context menu item for non-root sidebar tree nodes
- Improve active tab visual contrast (background + font-weight)
- FileTreeRow: show-in-explorer inline button & context menu for all items
- OpenFolder now resolves file-type nodes to parent directory
- handleShowInFolder uses item.nodeId || item.id for FileDTO compatibility
- Add i18n key nav.moveToRoot (ru/en)
2026-06-03 04:01:55 +08:00
mirivlad c941f05dab gui: sidebar tree UX fixes — has_children, preserve expanded, double-click, DnD visual
- Backend: add HasChildren field to NodeDTO; ListWorkspaceTree/ListChildren
  populate it by querying CountChildren for container types
- Node repository: add CountChildren(parentID, types...) method
- TreeNode: toggle shown only when has_children (not isContainer); double-click
  on row = expand/collapse; icon click = expand/collapse; drop-valid class via
  DOM classList for DnD highlight; auto-expand collapsed container on 500ms
  hover during drag; auto-scroll near edge during drag
- App.svelte: selectNode no longer resets workspaceTree/expanded; new
  reloadTreePreservingExpanded() helper re-fetches children for all expanded
  nodes after DnD move / delete; deleteWorkspaceNode preserves expanded state
2026-06-03 03:48:53 +08:00
mirivlad 9260582072 gui: sidebar tree model fix — only container nodes, improved DnD + context menu
- Backend: ListWorkspaceTree/ListWorkspaceChildren filter to container types
  only (case, client, project, folder, document, recipe)
- TreeNode: full-row context menu (removed label stopPropagation),
  double-click toggles expand, icon-click toggles expand, DnD auto-expand
  on 500ms hover, auto-scroll near edges, drag-over highlight via classList
- App.svelte: toggleExpand uses ListWorkspaceChildren, submitCreateNode uses
  ListWorkspaceChildren for child tree population
- Note/file nodes no longer appear in the sidebar workspace tree
2026-06-03 03:33:13 +08:00
mirivlad b2dcb116c9 gui: drag-and-drop sidebar, tree expand, localization fixes
TreeNode.svelte:
- Native HTML5 drag-and-drop with move effect
- Lazy tree expand/collapse (arrow for container types only)
- Drop validation: no self-drop, container-only, descendant check
- 'case' icon kind added

App.svelte:
- toggleExpand loads children via ListChildren into tree
- handleNodeDrop calls MoveNode(draggedId, targetId), refreshes tree
- Root workspace area is a drop target (handleDropRoot)
- Overview section shows nodeKindLabel instead of raw type enum
- Context menu shows Create only for container types
- Create modal title uses 'Создать элемент'
- submitCreateNode expands parent after child creation

TemplateIcon.svelte: added 'case' icon (folder-like with dividers)
i18n: added nav.createNode key (ru+en)
2026-06-03 03:18:04 +08:00
mirivlad f022f46909 gui: fix sidebar icons, create modal, and type display
- TreeNode.svelte: no white spacer for leaf nodes, iconKind maps node.type
  directly, 32px rows with hover/selected states
- App.svelte: header shows localized nodeKindLabel, auto-select created
  node, create modal with Пустое дело card + template descriptions,
  disable button until name+type chosen
- i18n: add kind.folder/note/file, template descriptions,
  template.optionNone → Пустое дело / Empty case
2026-06-03 02:58:27 +08:00
mirivlad a6b0f9d7e6 Rebuild GUI binary with updated frontend assets 2026-06-03 02:40:43 +08:00
mirivlad b26b757d80 GUI: fix sidebar icons and create modal with template selection
- Add TemplateIcon.svelte with SVG icons for folder/project/client/document/recipe
- TreeNode.svelte: render type-based icon before each node label
- Create modal: show template selection cards (translate titles via t())
- Context menu: use TemplateIcon + translated template names
- i18n (ru/en): add template.* translation keys
- Fix white capsule issue: tree-toggle arrow at 10px rendered oddly
  without icon presence; replaced with proper SVG icons
2026-06-03 02:29:11 +08:00
mirivlad d285f9ad8b sync_apply FS-first rewrite; CreateNodeFromTemplate rollback; DeleteNodeAndChildren fail on trash errors; PLAN.md update
- applyRemoteNodeUpdate: FS-first with SafeVaultPath validation, must-fail os.Rename
- applyRemoteNodeMove: FS-first for folders and notes/files
- moveNodeFiles: rewritten FS-first with atomic DB transaction
- applyRemoteNoteMove: delegates to moveNodeFiles
- CreateNodeFromTemplate: rollbackChildren on any child creation failure
- DeleteToTrash: skip rename if source file already missing
- DeleteNodeAndChildren: fail on deleteFileRecords errors and trash move failures
- docs/PLAN.md: update step 14 status with known gaps
2026-06-03 02:22:49 +08:00
mirivlad 7e38ffed7b bindings_nodes: fix parent variable redeclaration (rename to parentVal) 2026-06-03 02:18:10 +08:00
mirivlad a31f5fd702 fix: third stabilization pass — template children as nodes, atomicity, fs_path validation, sync_apply compat, smoke test 2026-06-03 02:05:53 +08:00
mirivlad 49c0fda61c chore: add wails.json, remove wails3 artifacts, rebuild binaries
- Add wails.json for Wails v2 build
- Remove wails3 boilerplate (build/Taskfile.yml, build/config.yml, etc.)
- Add server-data/ to .gitignore
- Rebuild frontend-dist and GUI binary
2026-06-03 01:48:12 +08:00
mirivlad 7b2a1da529 fix: note/file move ops, rename/move atomicity, importDir folder creation
- importDir: create physical folder for imported directories
- RenameNode/MoveNode: os.Rename before DB updates (atomicity)
- RenameNode note/file: fail if physical file missing
- MoveNode: file renames before DB updates
- applyRemoteNoteOp: handle OpMove for notes/files
- applyRemoteNodeMove: handle notes/files with empty FsPath
- MoveNode sync payload: no fs_path for notes/files
- Add 7 tests covering all fixes
2026-06-03 01:32:47 +08:00
mirivlad 50e7e95844 test(sync): add end-to-end two-client sync smoke test
TestE2ESync starts a real server process, registers user, pairs two devices,
pushes a node op from client A, pulls on client B, verifies payload content,
and confirms /api/auth/test does not create devices.
2026-06-02 08:02:19 +08:00
mirivlad 4a96aa3468 fix(sync): expand payloads, implement ApplyRemoteOp, fix SyncTestConnection and auto sync
- Expand all RecordOp payloads with full entity data needed for reconstruction
- Add applyRemoteOp with handlers for node/note/file/action/worklog CRUD
- SyncNow() now applies pulled ops to real DB tables + sets LastSeenServerSeq
- SyncTestConnection uses /api/auth/test instead of PairDevice
- autoSyncLoop respects configured interval with lastSync timing
- Add helper functions: nodePayload, notePayload, filePayload, actionPayload, worklogPayload
2026-06-02 08:02:15 +08:00
mirivlad f8f9510e2a fix(sync): add /api/auth/test endpoint, fix CSS %& vet warnings
- Add handleAuthTest endpoint that validates credentials without creating a device
- Fix resetPasswordHTML to use {TOKEN} placeholder instead of %s
- Remove fmt.Sprintf from admin dashboard (no format args needed)
2026-06-02 08:02:11 +08:00
mirivlad 852d6d373c fix(sync): send LastSeenServerSeq from CLI push, report conflicts 2026-06-02 08:02:07 +08:00
mirivlad 3c7e9d1d56 fix(sync): add ClientSequence and LastSeenServerSeq to Op struct and Push
- Add ClientSequence and LastSeenServerSeq fields to sync.Op struct
- Fix Client.Push() to copy these fields to PushOp
- Add GetDeviceID() method to sync.Service
2026-06-02 08:02:03 +08:00
mirivlad 87c8dfcbea sync: overhaul sync system — device pairing, server_sequence, auto-sync, dashboards
BREAKING: replace legacy API keys with device tokens via pairing flow.
- Server: /api/client/pair, revoke, me endpoints; server_sequence + tombstones + idempotency
- Desktop client: PairDevice, GetMe, RevokeCurrent; auto-sync loop every 60s
- Config: device_token stored in separate file (0600), not config.yml
- Client DB: last_pull_seq migration for incremental pull
- Frontend (Svelte): settings modal with connect/disconnect/interval
- User dashboard (/dashboard): device list with status, revoke with password
- Admin dashboard (/admin/dashboard): devices table from /admin/api/devices
- CLI (cmd/verstak): updated for ServerSequence/GetState changes
- Fix: autoSyncLoop falls back to SQLite sync_state for server URL
- Fix: SyncSetInterval preserves server_url/device_id from SQLite
2026-06-02 02:26:05 +08:00
mirivlad 7fe02fc8df feat: forgot/reset password pages, login link, consistent error page helper, fix reset URL bug 2026-06-02 00:43:28 +08:00
mirivlad b0d992b0d6 fix: rebuild GUI with login/password sync fields, make sync buttons more visible 2026-06-02 00:37:31 +08:00
mirivlad e5860ca076 feat: styled registration/confirm pages with login link, consistent theme 2026-06-02 00:31:53 +08:00
mirivlad daed8e0aba feat: SMTP security selector (none/STARTTLS/TLS) instead of port-based detection 2026-06-02 00:18:04 +08:00
mirivlad fa6f988368 fix: SMTP test send JSON instead of multipart FormData (ParseForm can't read multipart) 2026-06-02 00:14:52 +08:00
mirivlad c8cdb089a6 feat: SMTP test button in admin modal — sends real test email, shows result 2026-06-02 00:12:41 +08:00
mirivlad 4afcc0e135 feat: add SMTP/logging — log.Printf for smtpSend errors, fix confirm URL logic 2026-06-02 00:10:04 +08:00
mirivlad 61928cf28e fix: restore side-by-side layout for stat counters 2026-06-02 00:04:56 +08:00
mirivlad 04af88940b refactor: SMTP form and health check into modals with toolbar buttons 2026-06-02 00:03:35 +08:00
mirivlad 015c8fdec7 docs: update sync server guide with user registration flow and full API 2026-06-02 00:00:53 +08:00
mirivlad 0f5c584c50 fix: admin dashboard format errors — use JS for stats, string concat for SMTP values, fix layout overlap 2026-06-01 23:59:15 +08:00
mirivlad 99e47fcb17 feat: add user registration web form at /register 2026-06-01 23:46:25 +08:00
mirivlad 0ef54c31f8 feat: user web GUI — login, dashboard with devices/keys, logout 2026-06-01 23:40:48 +08:00
mirivlad b3662d4876 test: update smoke test for user auth flow 2026-06-01 23:36:38 +08:00
mirivlad f8dc436709 feat: client auth — login/password flow, auto device reg, sync interval + improved sync UI 2026-06-01 23:36:19 +08:00
mirivlad 241a9d8c06 feat: user registration, email confirmation, login, device management + SMTP config UI in admin panel 2026-06-01 23:33:58 +08:00
mirivlad 5db3da3618 fix: protect device register with admin auth; improve admin UI (full API key, copy button, styling) 2026-06-01 23:22:19 +08:00
mirivlad e828ebd44e docs: add sync server installation and usage guide 2026-06-01 23:13:59 +08:00
mirivlad 84c0bcbcab test: add E2E smoke test for sync 2026-06-01 23:07:24 +08:00
mirivlad a1a50863c5 gui: add sync settings panel in Svelte 2026-06-01 22:58:12 +08:00
mirivlad 1abe8c4fa0 cli: add sync push/pull/status commands 2026-06-01 22:56:05 +08:00
mirivlad 5b2cec5bcc sync: fix SyncStatus binding — remove invalid type assertion, use config for device ID 2026-06-01 22:55:50 +08:00
mirivlad 1a20edac44 feat: sync — client ops recording in core services
- internal/core/sync/: Service, Client, Blob packages

- RecordOp creates sync_ops entries for all mutations

- Client for push/pull/blob HTTP to server

- Blob SHA-256 hashing and local storage

- Wired into app.go alongside activity recording

- Device ID from config or fallback
2026-06-01 22:54:23 +08:00
mirivlad ad684eb118 feat: sync — push/pull API endpoints
- POST /api/v1/sync/push — accepts ops, assigns revisions, returns accepted list

- POST /api/v1/sync/pull — returns ops since given revision with server_revision
2026-06-01 22:51:30 +08:00
mirivlad 10c6d06e38 feat: sync — blob upload/download with SHA-256 storage
- POST /api/v1/blobs/ — multipart upload, stored as blobs/ab/cd/sha256

- GET /api/v1/blobs/{sha256} — download by hash

- server_blobs table for tracking stored blobs
2026-06-01 22:50:38 +08:00
mirivlad ec928e3be6 feat: sync — systemd unit and install.sh for server deployment
- verstak-server.service — systemd unit with sandboxing, configurable port via env

- install.sh — creates user, installs binary, sets up admin, enables service

  Usage: sudo ./install.sh --admin-user admin --admin-pass secret [--port 47732]
2026-06-01 22:49:40 +08:00
mirivlad c5e0060fee chore: add verstak-server to gitignore 2026-06-01 22:49:10 +08:00
mirivlad 834b5ef0d4 feat: sync — server skeleton with health, admin login/dashboard, device registration
- cmd/verstak-server/main.go — flags: --port, --data, --admin-user, --admin-pass

- Server DB schema: server_devices, server_revisions, server_ops

- Health endpoint GET /api/v1/health

- Admin login page + session cookie auth

- Admin dashboard with device stats and API key management

- Device registration POST /api/v1/device/register

- Stub push/pull/blob endpoints
2026-06-01 22:49:02 +08:00
mirivlad 4145b4d74a feat: sync — migration 010 for sync_ops and sync_state tables 2026-06-01 22:45:12 +08:00
mirivlad edc708a106 chore: add spaces/ to gitignore (vault data) 2026-06-01 22:17:39 +08:00
mirivlad ee708d30bb docs: sync documentation with current codebase state
- Architecture: Wails v3→v2, removed TUI/sync/security from diagram

- UI/UX: layout updated to sidebar+header, sync marked future

- Roadmap: Wails v3→v2 migration note, milestones 10+ PAUSED

- MVP Checklist: mark implemented features as done

- PLAN.md: bindings list synced, repo structure fixed, progress updated

- Medium-term steps documented (sync, scanner, TUI, Lua, etc.)
2026-06-01 22:17:29 +08:00
mirivlad 305158ecc6 test: MVP smoke test for core workflow
Covers: vault init, node tree, notes CRUD, file import, actions CRUD, worklog, search (FTS5 optional), reopen persistence, soft delete, worklog report
2026-06-01 22:17:25 +08:00
mirivlad 996322f3a9 gui: actions CRUD + FromTemplate bindings + UI
- CreateAction / DeleteAction Wails bindings

- FromTemplate / ListTemplates bindings with recursive tree creation

- Plugin manager stored in App struct for template access

- Action creation modal (title, kind, data) in Overview and Actions tabs

- Delete action button on action cards

- Template selector in new-node dialog
2026-06-01 22:17:18 +08:00
mirivlad a098cf721c add missing Wails bindings for ListActivityFeed, ListActivityByNode, CountActivityByNode 2026-06-01 22:00:58 +08:00
mirivlad 3672e3133b activity: global feed, per-case log, sidebar section, today UX
- migration 009: target_type, target_id, target_path columns
- new Event fields: TargetType, TargetID, TargetPath
- ListActivityFeed (paginated global), ListActivityByNode (per-case)
- all Record() callsites pass target info
- frontend: Активность sidebar section with chronological feed
- per-case Активность tab with real data (was placeholder)
- today events: clickable, target-type badges, event counts
2026-06-01 02:53:56 +08:00
mirivlad 5a1c4c6d7f simplify ListTodayView: remove fallback table queries, pure activity_events + ListTodayNodes
TodayView now uses only activity_events (source of truth) + ListTodayNodes (ensure changed cases appear). Removed direct queries to nodes (notes) and files tables — those will come from activity_events going forward.
2026-06-01 02:45:55 +08:00
mirivlad 08c9d5dbea gitignore: fix verstak-gui pattern to root-only, add .verstak/ 2026-06-01 02:16:25 +08:00
mirivlad c74fa3ad43 today dashboard: activity_events, ListTodayView with events timeline, frontend TodayDashboard separated from sidebar 2026-06-01 02:16:13 +08:00
mirivlad 69891e395c Today view and Inbox section: dynamic query, not stored sections
- ListTodayView() on backend: queries nodes created or updated today
  using local timezone day boundaries
- todayBoundaries() helper returns start/end of current day in RFC3339
- Section validation: Create() rejects today and inbox as node sections
- validSections moved from repository.go to types.go with IsValidSection
  and IsServiceSection helpers
- Frontend selectSection('today') calls ListTodayView instead of
  ListNodesBySection('today')
- FAB (create node) hidden in today and inbox sections
- CreateNode in app.go guarded against today/inbox sections
- types.go: today/inbox defined as service sections (sidebar only)
2026-06-01 01:39:02 +08:00
mirivlad a4ae22c445 File manager: selection, keyboard shortcuts, rename modal, security, localization
- Selection model: click=select, dblclick=open, Ctrl+click toggle,
  Shift+click range select, Ctrl+A, Esc to clear
- Keyboard shortcuts: Enter, Ctrl+Enter, F2, Backspace (navigate up),
  Delete/Backspace (delete with confirm)
- Rename modal replaces prompt() with validation via backend ValidateName
- Context menu: Open, Open External, Show in Folder, Rename, Duplicate,
  Copy, Cut, Delete — all with SVG icons and Russian labels
- Backend security: vaultPath/absPathSafe helpers prevent path traversal,
  validateName rejects .. / \ null bytes empty overlong names
- MoveNode auto-renames on name conflict (copy style)
- Duplicate uses (copy) (copy 2) suffix pattern
- Russian localization: all file type labels, preview messages, tooltips
- FilePreviewModal: fixed broken {/if} tag
2026-06-01 01:35:45 +08:00
mirivlad 2487d3bbaa Files tab: multi-selection, drag-and-drop, keyboard shortcuts, custom confirm modal, SVG icons 2026-06-01 01:16:51 +08:00
mirivlad 645d8878cc gui: complete Wails v2 vertical MVP — fixes, search, polished UI
Backend fixes:
- Wire search service in App struct, implement Search() bindings
- Fix OpenFile to use files.Service.Open() instead of stub
- Fix OpenFolder to open spaces/<slug>/ instead of vault root
- Remove unused imports and dead code in app.go

Frontend fixes:
- Add missing Svelte plugin to vite.config.js (blocking build error)
- Fix optional catch binding for compatibility
- Fix select dropdown rendering on Linux (appearance: none + custom arrow)
- Switch api/verstak.js to use generated Wails v2 bindings
- Include hand-written wailsjs bindings in repository
- Add build.sh to repository

Build:
  cd frontend && npm run build
  rm -rf cmd/verstak-gui/frontend-dist && cp -r frontend/dist cmd/verstak-gui/frontend-dist
  go build -tags 'gui production webkit2_41' -o verstak-gui ./cmd/verstak-gui
2026-05-31 23:48:38 +08:00
mirivlad b4010a5a24 gui: Wails v2 vertical MVP — bindings + UI
Go bindings (cmd/verstak-gui/app.go):
- Wire notes.Service, files.Service, actions.Service, worklog.Service
- CreateNote, ListNotes, ReadNote, SaveNote
- ListFiles, ListActions, RunAction
- ListWorklog, CreateWorklog
- Fix DTO mappings for core types

Frontend (frontend/src/):
- api/verstak.js: Wails v2 API wrapper (window.go.main.App)
- App.svelte: full rewrite with sidebar + 6 tabs + notes editor
- Section filtering → nodes by section
- Notes: create, open textarea editor, save, dirty tracking
- Quick actions, worklog entries, empty states
- Node creation modal with section select

Build:
  cd frontend && npm run build
  rm -rf cmd/verstak-gui/frontend-dist && cp -r frontend/dist cmd/verstak-gui/frontend-dist
  go build -tags 'gui production webkit2_41' -o verstak-gui ./cmd/verstak-gui
  ./verstak-gui
2026-05-31 20:37:46 +08:00
mirivlad 4a8f4e3319 docs: mark Wails vertical MVP as current stage 2026-05-31 20:15:45 +08:00
mirivlad ee503c338f gui: fix layout — full viewport, dark theme, sidebar+main
Problem: UI appeared as narrow dark panel on white background with scrollbar.

Root causes:
- html/body had no reset — default browser margin/padding = white borders
- index.html referenced non-existent /style.css
- .app used height:100vh but no width:100vw or overflow:hidden
- sidebar used fixed width instead of flexbox

Fixed:
- index.html: added critical CSS reset (html/body/#app = 100%, margin:0, overflow:hidden, dark bg)
- index.html: removed /style.css ref, changed lang to ru, title to Верстак
- App.svelte: complete layout rewrite
  - .app = flex, 100vw x 100vh, overflow:hidden
  - sidebar = 260px width, full height, flex column
  - main = flex:1, full height, flex column (header + content)
  - sidebar nav with sections + nodes using <button> elements
  - content area fills remaining space
  - proper dark theme colors throughout
- Rebuilt frontend/dist and cmd/verstak-gui/frontend-dist
2026-05-31 19:54:07 +08:00
mirivlad 3e07e611dd docs: update PLAN.md with Wails v2 build instructions 2026-05-31 19:42:43 +08:00
mirivlad 77a7918569 gui: port frontend to Wails v2
Frontend build failure root cause:
- Vite 8 uses rolldown with Wails v3 typed-events plugin
- @wailsio/runtime (Wails v3) in frontend dependencies
- vite.config.js had wails('./bindings') plugin from Wails v3 template
- main.js used Svelte 5 mount() API but Svelte 4 required

Fixes:
- Remove @wailsio/runtime dependency
- Remove wails('./bindings') plugin from vite.config.js
- Replace Vite 8 with Vite 5.4.21 + Rollup (stable)
- Downgrade Svelte 5 to Svelte 4.2.19
- Downgrade @sveltejs/vite-plugin-svelte to v3.1.2
- Fix main.js: mount() -> new App({ target })
- Rewrite App.svelte with Wails v2 binding calls (window.go.main.App.*)
- UI: sidebar with sections, nodes, basic navigation

Build: cd frontend && npm run build -> dist/ (476ms)
Build GUI: go build -tags 'gui production webkit2_41' -o verstak-gui ./cmd/verstak-gui
Run: ./verstak-gui (window opens, no SIGSEGV)
2026-05-31 19:39:49 +08:00