Skip to content

Latest commit

 

History

48 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Daymark Work Log

A personal desktop work-log client (Flutter + Rust core, macOS / Linux / Windows).

license platform build

中文文档:README_cn.md

Implemented based on the design in DESIGN.md.

Features

  • Quick notes: global hotkey (default Ctrl/Cmd+Shift+L) pops up a small window anytime; press Enter to save
  • Auto collection: GitLab/GitHub commits, directory file changes, and meeting audio transcripts collected automatically; per code instance you can pick which repositories' commits are merged into the daily report (issue #31)
  • AI summarization: dynamic provider list (Claude / DeepSeek / Ollama / OpenAI-compatible; cc-switch-style "add provider" flow, issue #25) with automatic fallback; the add-provider dialog can fetch the model list via the provider's official API and pick from a dropdown (issue #27)
  • Auto update: checks for new releases at startup, downloads in the background and notifies; the update completes automatically on app restart
  • About section: settings page shows version, build time, OS and other diagnostics with one-click copy for bug reports
  • Pure Markdown storage: 日报/ 周报/ 月报/ inbox/ are all .md files

Directory Layout

<log root directory>/
├── 日报/2026-08-11-工作日报.md     # finalized daily report
├── 周报/2026-W33-工作周报.md
├── 月报/2026-08-工作月报.md
├── inbox/2026-08-11.md             # today's quick notes (append)
├── 转写/<meeting>_转写.txt          # audio transcript cache
└── .daymark/
    ├── settings.json               # config (tokens stored in system keychain)
    ├── 素材缓存/<date>.json        # per-date collection cache
    └── 草稿/<date>.md              # unfinalized drafts

Development

Dependencies

  • Flutter (≥3.24, desktop platforms)
  • Rust stable (cargo)
  • flutter_rust_bridge_codegen (cargo install flutter_rust_bridge_codegen)
  • Linux extras: libayatana-appindicator3-dev (tray_manager), libsecret-1-dev, ninja-build, clang, cmake, pkg-config

Common Commands

# Generate FFI bindings (run after modifying rust/src/api/)
flutter_rust_bridge_codegen generate

# Rust tests
cd rust && cargo test

# Dart tests
flutter test

# Build
flutter build linux --release

# Package installers
./scripts/build_appimage.sh                        # Linux AppImage (hand-written AppDir + appimagetool)
./scripts/sign_macos.sh                            # macOS build + ad-hoc signing (dmg via CI)
powershell -File scripts/build_windows_installer.ps1 # Windows exe installer (NSIS)

Architecture

UI layer (Flutter)          main window / hotkey popup / settings page / tray
Application layer (Dart)    SettingsService / RecordService / CollectService / ReportService
Domain layer (Dart)         material models / LLM adapters / transcription engine / report engine
Infrastructure (Rust core)  document parsing (pptx/xlsx/docx/pdf) / file watching (notify) / global hotkey (global-hotkey)

The Rust core is bound to Dart bidirectionally via flutter_rust_bridge v2 FFI; events (hotkey triggers, file changes) are delivered to Dart via Stream callbacks.

macOS Signing & Distribution

For personal use (ad-hoc signing, no developer certificate needed):

flutter build macos --release
./scripts/sign_macos.sh          # ad-hoc by default
open build/macos/Build/Products/Release/daymark.app

First launch requires right-click → "Open" (ad-hoc signatures do not pass Gatekeeper; trusted locally only).

For external distribution (requires an Apple Developer account): sign with a developer certificate + notarization, see the header comments in scripts/sign_macos.sh.

CI Builds

GitLab CI (.gitlab-ci.yml): runs fully on every push —

Job Artifact
rust-test / dart-test Rust core and Flutter tests
prepare-version computes release version (latest GitLab releases tag patch+1) and generates auto-update dart-defines (passed to build jobs via dotenv)
linux-build Linux AppImage installer (scripts/build_appimage.sh)
macos-build macOS arm64 dmg (ad-hoc signed, runner: mac)
windows-build Windows exe installer (NSIS, runner: windows)
push-to-github syncs source to GitHub on every main push (excludes .gitlab-ci.yml, scripts/sync_github.py)
publish-release publishes three-platform releases after all jobs succeed (full archive on GitLab + rolling 5 on GitHub, scripts/publish_release.py)

Artifacts are uploaded as GitLab CI artifacts (retained 30 days). macOS notarization requires a developer certificate; CI only does ad-hoc signing by default (trusted locally).

GitHub source sync: after every push to main, the source is synced automatically to the public GitHub repository CodeFuckee/daymark, with .gitlab-ci.yml redacted (GitHub uses its own Actions workflow). The sync goes through the GitHub REST API (scripts/sync_github.py; the github.com git endpoint suffers intermittent SNI interference in mainland networks, making git push unreliable). Authentication requires the GitLab CI variable GITHUB_TOKEN (GitHub PAT with Contents: write / repo API permissions); this job is independent of the three platform builds (needs: []), so a build failure does not block the sync and vice versa.

GitHub Actions (.github/workflows/build.yml): triggered on v* tags or manually; matrix builds on three platforms (Linux tar.gz / macOS dmg / Windows zip); artifacts uploaded to GitHub Actions artifacts, suitable for external distribution. Tag-triggered runs inject the version (tag minus v) and the GitHub update source (detection URL = GitHub releases of CodeFuckee/daymark).

Auto Update (issue #5)

Mechanism: update source addresses are baked into the app at packaging time via --dart-define (build-time injection, read-only at runtime). GitLab CI packaging → checks GitLab repository releases (prepare-version job generates DAYMARK_UPDATE_SOURCES_B64, scripts/update_defines.py); GitHub Actions packaging → checks GitHub repository releases. When both are injected, the highest version wins.

Flow: background check at startup (or when "Check for updates" is clicked) → auto download (sha256 verification, asset digest for GitHub releases) → when the download completes a dialog pops up automatically asking the user to restart now or later ("Restart later" keeps the manual "Restart & update" button on the settings page) → update completes automatically when the app restarts:

  • Linux: new AppImage atomically replaces the file $APPIMAGE points to → launches the new version
  • macOS: mounts the dmg → ditto overwrites Daymark.app → clears quarantine → launches the new version
  • Windows: launches the NSIS installer with /S /UPDATE for silent overwrite install and auto-start of the new version

Update packages are cached in <app support dir>/update/ (manifest.json + installer) and installed by main() on restart. When a download completes, a "Restart now / Restart later" dialog pops up automatically (a single completed download only prompts once; a later re-check with another completed download prompts again; the window switches back to the main-window form so the dialog is visible even in quick-note mode or when hidden to the tray). The settings page has "Check for updates / Restart & update" buttons, the tray menu has "Check for updates", and the "check at startup" toggle can be disabled in settings. Local dev builds (no update source injected) have the whole update feature disabled.

Version consistency: release versions are computed by scripts/next_version.py (latest GitLab releases tag patch+1); build artifacts embed the same version via --build-name, and publish-release publishes the same tag — artifact versions strictly match release tags, and update detection compares semver.

Public repository anonymous access: daymark's GitLab repository is public (confirmed by the user in issue #5); update detection (releases API) and artifact downloads (generic packages) are all anonymous, and no token is embedded in artifacts. The historically configured CI variable GITLAB_READ_API_TOKEN is no longer read and can be deleted. If the repository ever goes back to private, the token injection mechanism must be restored.

Known Limitations

  • Linux global hotkey depends on X11 (may not work under Wayland)
  • The transcription endpoint is OpenAI-compatible (Groq / Volcano / Qwen all work; configure base_url)
  • Cloud-synced directory mtime refreshes can cause false positives; daily reports use the wording "changes detected today". Historical-date rescanning attributes files to natural days by disk mtime — for a file modified on the target day and modified again later (mtime overwritten), files inside git repositories are recovered from git history (issue #32), while non-git files cannot be recovered (generate the daily report on the day itself, or use quick notes for important changes, when the app was not running that day)
  • Auto update only applies to installer-form artifacts (AppImage / dmg install / NSIS install); GitHub Actions tar.gz / zip artifacts are not auto-installable — download them manually after a new version is detected

Contributing

Contributions are welcome! See CONTRIBUTING.md for issue reporting, the development workflow, commit conventions, and test requirements.

License

This project is licensed under the MIT License.

About

个人自用工作日志桌面客户端:随手记录、GitLab/GitHub 提交与文件变更自动收集、AI 汇总生成日报(Flutter + Rust core)

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages