Imported from VioletGiraffe/file-commander (
AGENTS.md). Install upstream withnpx skills add VioletGiraffe/file-commander. Copyright stays with the author.
File Commander project guidance
Project essentials
- File Commander is a cross-platform orthodox dual-panel file manager. Windows is the primary target; macOS and Linux are also supported. FreeBSD is best-effort only: support it where the Linux implementation works unchanged, but do not add FreeBSD-specific code or compatibility work.
- The codebase is C++23 with Qt 6.8+ and uses qmake (
file-commander.proplus.pro/.prifiles), not CMake. - The main dependency direction is
qt-app/(Qt Widgets GUI) ->file-commander-core/(controller, panels, filesystem and operations). Native plugins underplugins/depend on the core interface but are loaded dynamically. Keep UI access to panels and filesystem objects behindCController. - Several top-level dependency directories are Git submodules. Treat them as separate repositories.
Documentation routing
- Start with
doc/README.md, then read the documents relevant to the change. The documentation is an architecture map, not a substitute for checking the current code. - Writing code in any area:
doc/coding-style.mdfor this repo's authoring preferences, including the mandatory review pass for anything touching concurrency. - Core, filesystem, file operations, or concurrency:
doc/core-engine.mdanddoc/threading.md. - GUI or tabs:
doc/qt-ui.mdanddoc/tabs.md. - Settings or session restoration:
doc/persistence.md. - Plugins:
doc/plugins.md. - Build, tests, CI, or dependencies:
doc/build-ci-deps.md. - Installer, version, vendor, license, or other release identity:
doc/release-metadata-audit.md. - Do not build or compile the project; the user performs build verification.
Invariants to preserve
- Each side always has at least one tab, and each tab owns a
CPanel.CController::panel(side)returns that side's active tab. Tabs have stable IDs independent of their display positions. - Each UI tab has its own model/proxy/selection triplet, but those models resolve data through the active
CPanel; only the active tab's triplet may be queried or attached to the shared view. - Filesystem items are identified throughout the core, UI, selection state, and plugin API by their deterministic
qulonglongpath hash, not directly by path. - Core-to-UI notifications use listener/observer interfaces. Slow work runs off the UI thread and returns through execution queues or buffered observer callbacks.
- All
CPanelwork posted to the shared panel worker pool must carry the panel's task tag. Panel destruction retires that tag; preserve this lifetime guarantee when adding asynchronous work. - Every asynchronous
CPaneloperation that can replace the file list must carry the current file-list generation, path, and display mode, build its result locally, and publish only through the guarded commit funnel. Never build or replace_itemsincrementally from a worker. - Filesystem links are entries distinct from their targets. Use
CFileSystemObject::isLink()when that distinction matters, and ensure delete/move operations on a link cannot affect the target. Read the traversal rules indoc/core-engine.mdbefore changing recursive operations.