Development
Two independent toolchains
The desktop application uses Go 1.27.2+ and the MyGo 0.4.8 tool pinned in go.mod. The documentation uses Node.js 22+, pnpm 12.11.2 and VitePress 2.0 alpha. Node is not needed to build the application.
go mod download
make dev
make run
make buildChecks
make fmt
make check
make race
go tool mygo vet
make snapshots
go run ./tools/versionSnapshots run the internal/app tests and render the real MyGo views in light and dark mode to the ignored snapshots/ directory. UI tests also render all five languages at the minimum window size. Tests never connect to OSS.
An optional native capture starts a real window, writes a screenshot and exits:
OSS_BROWSER_CAPTURE=/tmp/oss-browser.png go run . --config /tmp/oss-browser-settings.jsonDocumentation
pnpm install --frozen-lockfile
cd docs
pnpm dev
pnpm typecheck
pnpm build
pnpm previewVitePress validates internal links during production builds. The docs package belongs to the root pnpm workspace; commit the root pnpm-lock.yaml with dependency changes. Build output is docs/.vitepress/dist; caches, dependencies and build products are ignored.
Keep internal article links relative to the current language directory (for example, ./design). Every root article requires a complete translation in all four locale directories. pnpm check:translations checks for missing pages and verbatim English copies and runs before typecheck and build. The [locale]/[page].paths.ts loader can serve missing translations with an English-content notice during development, but fallback pages do not satisfy the pre-release completeness check. Adding a translated Markdown file automatically replaces its fallback page. Shared images stay at root paths such as /design/workspace.png.
The documentation GitHub Actions workflow has been removed. Pushes and pull requests no longer build or typecheck the site or upload a Pages artifact, and manual Pages deployment is no longer available through that workflow. Run pnpm typecheck and pnpm build locally from docs/ after documentation changes. See releasing.
Icon assets
The approved cloud-and-storage icon source is resources/icon-oss-v3.png. Run make icon from the repository root to export the 1024px application icon, 512px documentation logo, 64px favicon and 180px Apple touch icon. All exports preserve transparency. MyGo packages resources/icon.png; all five READMEs use that same application icon. The documentation navigation and localized home pages use /icon.png.
Source layout
| Location | Responsibility |
|---|---|
| main.go, cli.go | CLI parsing and launch options passed to the native app |
| internal/app | MyGo lifecycle, grouped window state, actions, views and UI fixtures |
| internal/buildinfo | Desktop version passed to CLI and native app |
| internal/transfers | Batch scheduler, journals, recovery, cleanup and transfer planning |
| internal/ossclient | OSS SDK boundary, object operations and resumable transfers |
| tools/version | Desktop/package version synchronization and consistency check |
| internal/config | Validated settings and safe persistence |
| internal/i18n | Five embedded message catalogs and locale resolution |
| internal/desktop | Native service boundaries |
| internal/tasks | Cancellation and stale-callback protection |
| internal/files | Existing local text/checksum utilities, reserved for later features |
| internal/storage | Atomic file writes |
| resources, tools/genicon | Application assets and icon generation |
| docs | Independent VitePress package |
Add new business services when their feature is implemented rather than creating empty layers. Read the repository AGENTS.md before contributing.
Performance checks
go test ./internal/transfers -run '^$' -bench 'BenchmarkQueue(AddBatch|Drain)' -benchmem
go test ./internal/app -run '^$' -bench BenchmarkObjectRowsCached -benchmemThe queue benchmarks cover 1,000/10,000/100,000 jobs for insertion and 1,000/10,000 completions. Keep scheduler work independent of completed history. Browser row slices are immutable after publication; replace a listing when refreshing or merging so its cached sort is invalidated.