9 Commits
Author SHA1 Message Date
sami e0f22f808f merge: lane/pkg-qa
CI / clang-format (push) Canceled after 0s
CI / testserver (push) Canceled after 0s
CI / bootstrap-script (push) Canceled after 0s
CI / bootstrap-script-2604 (push) Canceled after 0s
CI / extension-lint (push) Canceled after 0s
CI / build (clang) (push) Canceled after 0s
CI / build (gcc) (push) Canceled after 0s
CI / sanitizers (dev) (push) Canceled after 0s
CI / sanitizers (tsan) (push) Canceled after 0s
CI / clang-tidy (push) Canceled after 0s
CI / conformance (push) Canceled after 0s
CI / nightly-integration (push) Canceled after 0s
CI / gui-dod (push) Canceled after 0s
CI / gui-dod-nightly (push) Canceled after 0s
2026-09-15 18:46:34 +04:00
sami 111229686c merge: lane/daemon 2026-09-15 18:46:34 +04:00
sami a5551db1c3 merge: lane/core 2026-09-15 18:46:34 +04:00
samiandClaude Sonnet 5 83b92d118b core: select platform/linux sources via velox_platform_sources()
Replace the hardcoded src/io/platform/linux/file_ops.cpp entry with a
velox_platform_sources(veloxcore src/io) call, now that PKG/QA's
cmake/platform.cmake owns VELOX_OS_* detection and source selection
(ADR 0020 §5). Adding platform/macos/ later needs no edit to this file.

Build-wiring only; full suite stays green (59/59).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-15 18:46:13 +04:00
samiandClaude Sonnet 5 78f2b22c8c daemon: use velox_platform_sources() instead of a hardcoded platform/linux/ list
PKG's cmake/platform.cmake (VELOX_OS_* + velox_platform_sources(<target> <dir>))
is on main now. Swap the hardcoded src/rpc/platform/linux/*.cpp list in
veloxd_rpc for velox_platform_sources(veloxd_rpc src/rpc), matching ADR 0020 §5
(source selection lives in cmake/platform.cmake and nowhere else). PORT can now
add platform/macos/ with no edit to this file.

Build-wiring only, no behaviour change. Full suite 59/59 green.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-09-15 18:46:07 +04:00
samiandClaude Sonnet 5 77bdb0c427 docs: mark GUI's bootstrap.sh apt-name-validation request (R2) resolved
tools/bootstrap.sh already validates every apt package name via apt-cache policy
(landed in an earlier session), so R2 was done but still read as an open request.
Mark it closed so it stops resurfacing.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0176u3fTrxegrGNm2yC7r69W
2026-09-15 18:39:03 +04:00
sami d60cf94905 merge: lane/pkg-qa — local .deb, cmake/platform.cmake, Linux-gated deps
CI / clang-format (push) Canceled after 0s
CI / testserver (push) Canceled after 0s
CI / bootstrap-script (push) Canceled after 0s
CI / bootstrap-script-2604 (push) Canceled after 0s
CI / extension-lint (push) Canceled after 0s
CI / build (clang) (push) Canceled after 0s
CI / build (gcc) (push) Canceled after 0s
CI / sanitizers (dev) (push) Canceled after 0s
CI / sanitizers (tsan) (push) Canceled after 0s
CI / clang-tidy (push) Canceled after 0s
CI / conformance (push) Canceled after 0s
CI / nightly-integration (push) Canceled after 0s
CI / gui-dod (push) Canceled after 0s
CI / gui-dod-nightly (push) Canceled after 0s
2026-09-15 18:35:11 +04:00
samiandClaude Sonnet 5 0cd5bf6882 pkg: cmake/platform.cmake; gate libsecret and Qt6::DBus to Linux
Root build infra, per ADR 0020 as amended in 9624e68: PORT owns the per-OS
backend directories and macOS/Windows packaging, but cmake/platform*.cmake stays
PKG/QA's — the amendment exists because Phase 0 (CORE's and DAEMON's own seams,
on Linux) needs velox_platform_sources() to select platform/linux/*.cpp, and PORT
can't start until Phase 0 lands. Landing it as PORT-owned would have deadlocked
both lanes waiting on each other.

cmake/platform.cmake sets exactly one of VELOX_OS_LINUX/VELOX_OS_MACOS/
VELOX_OS_WINDOWS from CMAKE_SYSTEM_NAME and exposes velox_platform_sources(target
dir), which globs dir/platform/<os>/*.cpp. No seam consumes it yet (Phase 0 hasn't
landed), so on Ubuntu this changes nothing observable — VELOX_OS_LINUX is simply
true and no lane calls the new function.

pkg_check_modules(LIBSECRET ...) was unconditional in the root CMakeLists.txt,
so macOS could not configure at all (docs/08-porting.md's stated blocker); it's
now gated on VELOX_OS_LINUX, same as the Qt6::DBus component this also adds
(gui/docs/pkg-qa-requests-m1.md R4 — backs the org.freedesktop.portal
GlobalShortcuts path, which is Linux/portal-only same as libsecret). Both are
still REQUIRED on Linux; PORT adds the macOS sides (Keychain, and no DBus
equivalent needed) behind their own seams, not by touching this find.

Verified: fresh configure + build of veloxd/velox/velox-gui/velox-nmhost still
green (libsecret-1 and Qt6::DBus both found), the .deb from the previous commit
still builds and installs.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0176u3fTrxegrGNm2yC7r69W
2026-09-15 18:03:50 +04:00
samiandClaude Sonnet 5 31eadffce5 pkg: build a local .deb; de-duplicate onto DAEMON's systemd/nativehost/man page
DAEMON landed packaging/nativehost/, packaging/systemd/{velox.service,velox.socket}
(real sd_listen_fds() socket activation) and cli/man/velox.1 on main while this was
in flight, duplicating paths this branch had drafted independently. Per CLAUDE.md
(packaging/nativehost/ is DAEMON's; the rest of packaging/ is PKG/QA's), DAEMON's
copies are kept as the single source and this branch's packaging/native-messaging/,
packaging/man/velox.1 and stale packaging/systemd/velox.service are dropped rather
than maintained twice. The root CMakeLists.txt's install() rules now point at
DAEMON's paths directly, install both systemd units (not just velox.service), and
docs/07-packaging.md / packaging/README.md no longer claim there's no socket
activation — there is, and this package now ships it.

Adds the local-test-only .deb itself: debian/{control,rules,postinst,postrm,
changelog,copyright}, a placeholder icon set, the desktop entry and PKG/QA's own
man pages (veloxd.8, velox-gui.1 — velox.1 stays DAEMON's). libveloxcore stays
static (no consumer needs a .so yet); pairing has no real approval UI in this
build (D1 unbuilt), so postinst and packaging/README.md both say VELOX_PAIR_AUTO=1
is required and print it prominently. No PPA, no GPG — local dpkg -i only.

Verified live: dpkg-buildpackage -us -uc -b, dpkg -i, socket activation (systemctl
--user enable --now velox.socket), `velox ls` against the running daemon, lintian
clean, dpkg -r removes the manifest/units and leaves $XDG_DATA_HOME/velox alone.

.gitignore now excludes dpkg-buildpackage's debhelper build tree and obj-*/ (the
debuild output dir) — debian/control et al. stay tracked, everything debhelper
regenerates does not.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0176u3fTrxegrGNm2yC7r69W
2026-09-15 18:02:11 +04:00
28 changed files with 572 additions and 15 deletions
+14
View File
@@ -45,3 +45,17 @@ crash-*
oom-*
leak-*
timeout-*
# dpkg-buildpackage output — debhelper's build tree and the produced .deb/.changes, plus
# the classic out-of-tree autotools-style build dir some debhelper versions still create.
# debian/control, changelog, copyright, rules, postinst, postrm, source/format and
# *.lintian-overrides are real packaging source and stay tracked; everything below is
# regenerated by `dpkg-buildpackage` on every run.
debian/.debhelper/
debian/velox/
debian/files
debian/*.substvars
debian/*.debhelper.log
debian/*.debhelper
debian/debhelper-build-stamp
obj-*/
+79 -3
View File
@@ -29,6 +29,10 @@ option(VELOX_BUILD_FUZZ "Build libFuzzer targets (clang only)" OFF)
option(VELOX_ENABLE_MEDIA "Build the HLS/DASH media grabber (M4)" OFF)
option(VELOX_WERROR "Treat warnings as errors" ON)
# Central OS detection (docs/adr/0020-cross-platform-strategy.md). Included early: the
# dependency finds below gate Linux-only libraries on VELOX_OS_LINUX.
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/platform.cmake)
# Project-wide warning flags. Set via add_compile_options (a directory property), not the
# CMAKE_CXX_FLAGS cache variable, because the dev/tsan presets overwrite that cache var
# wholesale for sanitizer flags — a target's warnings must not ride on it.
@@ -55,12 +59,24 @@ endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/daemon/CMakeLists.txt)
find_package(SQLite3 REQUIRED)
find_package(nlohmann_json 3.11 REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBSECRET REQUIRED IMPORTED_TARGET libsecret-1)
# libsecret / Secret Service is Linux-only (docs/adr/0020-cross-platform-strategy.md,
# docs/08-porting.md): macOS uses Keychain behind the same credential-store seam, so
# this stays REQUIRED on Linux and simply absent elsewhere — PORT's job is to add the
# macOS side of that seam, not to touch this find.
if(VELOX_OS_LINUX)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBSECRET REQUIRED IMPORTED_TARGET libsecret-1)
endif()
endif()
if(VELOX_BUILD_GUI AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/gui/CMakeLists.txt)
find_package(Qt6 6.6 REQUIRED COMPONENTS Widgets Svg Network LinguistTools)
# DBus (gui/docs/pkg-qa-requests-m1.md R4) backs the org.freedesktop.portal
# GlobalShortcuts path — Linux/portal-only, same reasoning as libsecret above.
if(VELOX_OS_LINUX)
find_package(Qt6 6.6 REQUIRED COMPONENTS Widgets Svg Network DBus LinguistTools)
else()
find_package(Qt6 6.6 REQUIRED COMPONENTS Widgets Svg Network LinguistTools)
endif()
qt_standard_project_setup()
endif()
@@ -105,3 +121,63 @@ if(VELOX_BUILD_TESTS)
endif()
endforeach()
endif()
# --- Install rules (M6 packaging; docs/07-packaging.md; owned by PKG/QA) ------------
#
# Guarded by `if(TARGET ...)`, not by editing each lane's own CMakeLists.txt: install()
# is a packaging concern, and reaching into daemon/CMakeLists.txt (DAEMON's), cli's build
# file (also DAEMON's) or gui/CMakeLists.txt (GUI's) to add it there would cross a lane
# boundary CLAUDE.md draws on purpose. Every target below is defined by its own lane;
# this only says where the packaged binary already built by that lane's rules goes.
#
# libveloxcore is intentionally absent here: it stays a static library linked into each
# binary (user decision, see docs/07-packaging.md) — there is no .so to install.
#
# CMAKE_INSTALL_LIBDIR is multiarch-adjusted (lib/x86_64-linux-gnu/) by GNUInstallDirs on
# Debian; systemd user units and the Mozilla native-messaging directory are NOT
# architecture-specific paths, so those two destinations are written literally
# (lib/systemd/user, lib/mozilla/...) rather than built from that variable.
include(GNUInstallDirs)
if(TARGET veloxd)
install(TARGETS veloxd RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${CMAKE_SOURCE_DIR}/packaging/man/veloxd.8
DESTINATION ${CMAKE_INSTALL_MANDIR}/man8)
# velox.socket ships alongside velox.service: DAEMON wired real sd_listen_fds()
# socket activation (daemon/src/rpc/systemd_activation.cpp) — see
# packaging/systemd/README.md for the pair's own rationale.
install(FILES ${CMAKE_SOURCE_DIR}/packaging/systemd/velox.service
${CMAKE_SOURCE_DIR}/packaging/systemd/velox.socket
DESTINATION lib/systemd/user)
endif()
if(TARGET velox)
install(TARGETS velox RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
# DAEMON owns cli/ and its man page (CLAUDE.md); packaging only installs it.
install(FILES ${CMAKE_SOURCE_DIR}/cli/man/velox.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif()
if(TARGET velox-gui)
install(TARGETS velox-gui RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${CMAKE_SOURCE_DIR}/packaging/man/velox-gui.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
install(FILES ${CMAKE_SOURCE_DIR}/packaging/desktop/velox.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
foreach(iconsize 16 22 24 32 48 64 128 256)
install(FILES
${CMAKE_SOURCE_DIR}/packaging/icons/hicolor/${iconsize}x${iconsize}/apps/velox.png
DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${iconsize}x${iconsize}/apps)
endforeach()
endif()
# nmhost and its manifest are DAEMON's (CLAUDE.md: nmhost/ and packaging/nativehost/).
# This lights up the moment DAEMON's target exists, the same way the add_subdirectory()
# guards above do — no coordinated edit needed when it lands.
if(TARGET velox-nmhost)
install(TARGETS velox-nmhost RUNTIME DESTINATION libexec/velox)
install(FILES ${CMAKE_SOURCE_DIR}/packaging/nativehost/com.velox.host.json
DESTINATION lib/mozilla/native-messaging-hosts)
else()
message(STATUS "velox: nmhost has not landed yet — native-messaging manifest not installed.")
endif()
+45
View File
@@ -0,0 +1,45 @@
# cmake/platform.cmake — central OS detection and per-OS source selection.
#
# Owned by PKG/QA (docs/adr/0020-cross-platform-strategy.md §4-5, amended: PORT owns
# **/platform/<os>/** and the macOS/Windows packaging trees, but this file is root build
# infrastructure and lands in Phase 0 — CORE's and DAEMON's own seams need
# velox_platform_sources() to select their platform/linux/*.cpp before PORT ever starts).
#
# Sets exactly one of VELOX_OS_LINUX / VELOX_OS_MACOS / VELOX_OS_WINDOWS. Selection lives
# here and nowhere else — no lane's own CMakeLists.txt should reimplement this check.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(VELOX_OS_LINUX TRUE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(VELOX_OS_MACOS TRUE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(VELOX_OS_WINDOWS TRUE)
else()
message(FATAL_ERROR "velox: unsupported CMAKE_SYSTEM_NAME '${CMAKE_SYSTEM_NAME}' — "
"expected Linux, Darwin or Windows.")
endif()
# velox_platform_sources(<target> <dir>) adds <dir>/platform/<os>/*.cpp to <target>, where
# <os> is linux, macos or windows to match this file's VELOX_OS_* selection. <dir> is
# relative to the calling lane's own CMakeLists.txt (e.g. src/io, src/rpc) — the seam
# headers themselves (<dir>/platform/*.hpp) are not globbed here, they're ordinary sources
# the owning lane already lists.
function(velox_platform_sources target dir)
if(VELOX_OS_LINUX)
set(os_dir "linux")
elseif(VELOX_OS_MACOS)
set(os_dir "macos")
elseif(VELOX_OS_WINDOWS)
set(os_dir "windows")
endif()
file(GLOB platform_sources CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/${dir}/platform/${os_dir}/*.cpp")
if(NOT platform_sources)
message(WARNING "velox: velox_platform_sources(${target} ${dir}) found no "
"sources under ${dir}/platform/${os_dir}/ — is the seam missing "
"its ${os_dir} backend?")
endif()
target_sources(${target} PRIVATE ${platform_sources})
endfunction()
+5 -1
View File
@@ -20,7 +20,6 @@ add_library(veloxcore STATIC
src/net/probe.cpp
src/io/sparse_file.cpp
src/io/write_buffer.cpp
src/io/platform/linux/file_ops.cpp
src/meta/veloxpart.cpp
src/segment/segmenter.cpp
src/segment/budget.cpp
@@ -33,6 +32,11 @@ add_library(veloxcore STATIC
)
add_library(velox::core ALIAS veloxcore)
# Per-OS backend behind src/io/platform/*.hpp (docs/adr/0020, docs/08-porting.md). Only
# the Linux backend exists (Phase 0); source selection lives in cmake/platform.cmake and
# nowhere else, so PORT's platform/macos/ addition needs no edit here.
velox_platform_sources(veloxcore src/io)
target_include_directories(veloxcore
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src # net/*.cpp -> "net/curl_error.hpp"
+5 -8
View File
@@ -83,17 +83,14 @@ add_library(veloxd_rpc STATIC
src/rpc/ws_server.cpp
src/rpc/pairing.cpp
src/rpc/dispatcher.cpp
# Per-OS backends behind daemon/src/rpc/platform/*.hpp (docs/adr/0020,
# docs/08-porting.md). Only the Linux backend exists (Phase 0); lane PORT adds
# cmake/platform.cmake + platform/macos/ in Phase 1 and this hardcoded list becomes
# a velox_platform_sources() call.
src/rpc/platform/linux/wakeup.cpp
src/rpc/platform/linux/peer_id.cpp
src/rpc/platform/linux/instance_lock.cpp
src/rpc/platform/linux/runtime_paths.cpp
)
add_library(velox::daemon_rpc ALIAS veloxd_rpc)
# Per-OS backends behind daemon/src/rpc/platform/*.hpp (docs/adr/0020, docs/08-porting.md).
# Source selection lives in cmake/platform.cmake and nowhere else — PORT adds
# platform/macos/ with no edit here.
velox_platform_sources(veloxd_rpc src/rpc)
target_include_directories(veloxd_rpc PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_compile_features(veloxd_rpc PUBLIC cxx_std_23)
target_compile_options(veloxd_rpc PRIVATE -Wall -Wextra -Wpedantic -Werror)
+11
View File
@@ -0,0 +1,11 @@
velox (0.1.0-1) UNRELEASED; urgency=medium
* Local test build only. Not signed, not uploaded anywhere — see
packaging/README.md for what this package is and is not.
* libveloxcore is linked statically; no libveloxcore.so is shipped.
* Placeholder app icon (packaging/icons/) — replace before any real release.
* No real pairing-approval UI is built yet (needs libdbus-1-dev, not in this
build's Build-Depends): pairing requires VELOX_PAIR_AUTO=1. See
packaging/README.md and postinst's own notice.
-- Velox Local Test Build <[email protected]> Sat, 12 Sep 2026 22:30:43 +0400
+35
View File
@@ -0,0 +1,35 @@
Source: velox
Section: net
Priority: optional
Maintainer: Velox Local Test Build <[email protected]>
Build-Depends: debhelper-compat (= 13),
cmake (>= 3.28),
ninja-build,
pkg-config,
g++ (>= 13),
qt6-base-dev,
qt6-tools-dev,
qt6-tools-dev-tools,
qt6-svg-dev,
libcurl4-openssl-dev,
libssl-dev,
libsqlite3-dev,
nlohmann-json3-dev,
libsecret-1-dev
Standards-Version: 4.6.2
Rules-Requires-Root: no
Package: velox
Architecture: amd64
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: IDM-class download manager for Linux (local test build)
Velox is a segmented, resumable download manager for Linux: a daemon
(veloxd) that does the transfer work, a Qt GUI, a CLI, and a Firefox
extension for capture.
.
This package ships veloxd, the velox CLI, the velox-gui Qt client and
velox-nmhost, the Firefox native-messaging host.
.
THIS IS A LOCAL TEST BUILD, not a release: it uses a placeholder app
icon and has no real pairing-approval UI (see /usr/share/doc/velox, or
packaging/README.md in the source tree, for both limitations).
+26
View File
@@ -0,0 +1,26 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: velox
Source: (no public upstream repository yet — local test build only)
Files: *
Copyright: 2026, the Velox project
License: Unlicensed-TODO
Files: debian/*
Copyright: 2026, the Velox project
License: Unlicensed-TODO
License: Unlicensed-TODO
No license has been chosen for Velox's own source yet. This is a genuine,
open project decision — not something packaging can invent on its own —
and is tracked as a release blocker in packaging/README.md. `lintian` is
expected to flag this package over it (a package normally must declare a
real license); that is correct behaviour on lintian's part, not a bug in
this packaging, and stays that way until the project adopts one.
.
Nothing above changes the licenses of this package's dynamically-linked
runtime dependencies (Qt, libcurl, SQLite, OpenSSL, nlohmann-json,
libsecret and friends) — those remain under their own upstream licenses,
covered by their own packages' Depends, and are not redistributed by this
source package. See packaging/README.md's licence-audit note for what
that still needs before a real release.
Vendored Executable
+92
View File
@@ -0,0 +1,92 @@
#!/bin/sh
# postinst for velox (local test build). See packaging/README.md.
set -e
NM_MANIFEST_SRC=/usr/lib/mozilla/native-messaging-hosts/com.velox.host.json
NM_MANIFEST_NAME=com.velox.host.json
# Every real (human) user with a home directory — UID range matches Debian's own
# adduser default (login.defs UID_MIN=1000), not just "everyone in /home" (a service
# account can have a home dir too) and not root.
real_users() {
getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 && $6 != "" {print $1":"$6}'
}
# Per-user native-messaging manifest (ADR 0003 / docs/05 §4.A): needed for BOTH
# deb/tarball and snap Firefox — the system-wide manifest this package also installs at
# $NM_MANIFEST_SRC only covers deb/tarball Firefox, never snap. Runs unconditionally,
# not just when snap is detected: a per-user login.defs-based install can't assume every
# user runs the same Firefox flavour, and dropping a JSON file nobody reads is harmless.
install_per_user_manifests() {
[ -f "$NM_MANIFEST_SRC" ] || {
echo "velox: native-messaging host not built yet (nmhost lane not landed) —" \
"skipping per-user manifest install."
return 0
}
real_users | while IFS=: read -r user home; do
[ -d "$home" ] || continue
dest_dir="$home/.mozilla/native-messaging-hosts"
install -d -o "$user" -g "$user" -m 0755 "$dest_dir" 2>/dev/null || {
echo "velox: could not create $dest_dir for $user — skipping" >&2
continue
}
cp "$NM_MANIFEST_SRC" "$dest_dir/$NM_MANIFEST_NAME"
chown "$user:$user" "$dest_dir/$NM_MANIFEST_NAME"
chmod 0644 "$dest_dir/$NM_MANIFEST_NAME"
done
}
# docs/07-packaging.md: detect snap Firefox and say so — the extension pairs over
# loopback WebSocket there (ADR 0003), not native messaging from inside the sandbox.
note_snap_firefox() {
if command -v snap >/dev/null 2>&1 && snap list firefox >/dev/null 2>&1; then
cat <<'EOF'
velox: Firefox is installed as a snap on this system. The extension will pair with
veloxd over the loopback WebSocket (ws://127.0.0.1:<port>), not native
messaging — this is expected (see docs/adr/0003, ADR 0003) and needs no
action from you.
EOF
fi
}
case "$1" in
configure)
install_per_user_manifests
note_snap_firefox
cat <<'EOF'
============================================================================
velox: LOCAL TEST BUILD — read this before pairing the extension
============================================================================
No real pairing-approval UI is built into this package yet (it needs
libdbus-1-dev, which this build's dependencies do not include). veloxd's
only pairing approver in this build auto-rejects every request UNLESS you
set VELOX_PAIR_AUTO=1 in its environment — there is no prompt to accept or
decline; it is all-or-nothing. Do not run this on a machine or account
where you would not want every pairing request accepted automatically.
systemctl --user edit velox.service
# add, in the [Service] section:
# Environment=VELOX_PAIR_AUTO=1
debhelper's dh_installsystemduser marks velox.service and velox.socket enabled (the
pair together, via velox.service's Also=velox.socket) for your next login session
automatically. For your CURRENT session, start socket activation now yourself — a
root postinst has no live user session to reach:
systemctl --user daemon-reload
systemctl --user enable --now velox.socket
See packaging/README.md in the source tree for the rest of this build's
testing-only limitations (placeholder icon, no license chosen yet, no
libveloxcore.so — it is linked statically).
============================================================================
EOF
;;
esac
#DEBHELPER#
exit 0
Vendored Executable
+34
View File
@@ -0,0 +1,34 @@
#!/bin/sh
# postrm for velox (local test build). See packaging/README.md.
set -e
NM_MANIFEST_NAME=com.velox.host.json
real_users() {
getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 && $6 != "" {print $1":"$6}'
}
# Undoes exactly what postinst's install_per_user_manifests() did — never anything
# beyond that file. In particular this never touches a user's Velox data
# ($XDG_DATA_HOME/velox, i.e. normally ~/.local/share/velox — the task database and
# any settings) on either `remove` or `purge`: per-user, root-owned deletion across
# every account on the system is exactly the kind of destructive multi-user operation
# that deserves its own careful design and testing, not a first cut bolted onto this
# local test package. Documented as a deliberate simplification in
# packaging/README.md, not a silent gap.
remove_per_user_manifests() {
real_users | while IFS=: read -r user home; do
f="$home/.mozilla/native-messaging-hosts/$NM_MANIFEST_NAME"
[ -e "$f" ] && rm -f "$f"
done
}
case "$1" in
remove|purge)
remove_per_user_manifests
;;
esac
#DEBHELPER#
exit 0
Vendored Executable
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/make -f
# Velox — local test .deb build. Not a release build (no signing, no LTO tuning beyond
# what the flags below ask for): see packaging/README.md.
#
# Explicit cmake flags rather than a CMakePresets.json preset: dh_auto_configure already
# sets its own CMAKE_INSTALL_PREFIX / build-dir conventions, which fighting a preset's own
# cache variables (build/<preset>/, etc.) would only complicate. The flags mirror the
# `release` preset's intent (RelWithDebInfo, no tests) without inheriting its binaryDir.
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh $@
override_dh_auto_configure:
dh_auto_configure -- \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DVELOX_BUILD_TESTS=OFF \
-DVELOX_BUILD_GUI=ON \
-DVELOX_WERROR=OFF
# dh_installsystemd (system units) is disabled: velox.service/velox.socket are --user
# units, not system ones, so that helper has nothing to do here. dh_installsystemduser is
# NOT overridden — it runs normally, finds both units under lib/systemd/user/ in the
# install tree, and marks them enabled for each user's *next* systemd --user login (it
# cannot reach an already-running session from a root maintainer script at install time;
# postinst prints the manual start commands for the current session, matching
# packaging/README.md's own instructions).
override_dh_installsystemd:
+1
View File
@@ -0,0 +1 @@
3.0 (native)
+10
View File
@@ -0,0 +1,10 @@
# initial-upload-closes-no-bugs: this is a local test build (packaging/README.md),
# never intended for the Debian/Ubuntu archive — there is no ITP bug to close.
initial-upload-closes-no-bugs
# maintainer-script-calls-systemctl (postinst): both flagged lines are inside a
# heredoc of instructions printed for the *admin* to run themselves (velox.service is
# a --user unit; postinst has no live user session to invoke systemctl against
# itself). lintian's check is a text scan and can't tell printed advice from an actual
# invocation — verified by reading the built postinst, see packaging/README.md.
maintainer-script-calls-systemctl
+14 -2
View File
@@ -9,16 +9,28 @@ Owner: lane **PKG/QA**. Target: Ubuntu 26.04 LTS.
/usr/bin/velox-gui
/usr/bin/velox # CLI
/usr/libexec/velox/velox-nmhost # native messaging host
/usr/lib/x86_64-linux-gnu/libveloxcore.so.1
/usr/share/applications/velox.desktop
/usr/share/icons/hicolor/*/apps/velox.png
/usr/share/man/man1/velox.1.gz
/usr/lib/systemd/user/velox.service
/usr/lib/systemd/user/velox.socket # socket activation
/usr/lib/systemd/user/velox.socket # real socket activation, see below
/usr/lib/mozilla/native-messaging-hosts/com.velox.host.json
/etc/xdg/autostart/velox-gui.desktop # optional, off by default
```
`libveloxcore` is **static**, linked into `veloxd`, `velox` and `velox-gui` directly —
there is no `libveloxcore.so.*` to install. A shared, versioned `libveloxcore.so.1` was
the original plan here; the user decided against building one for now (no consumer needs
it as a shared object yet, and it would need CORE's `core/CMakeLists.txt` to grow a
`SOVERSION`). Revisit as a CORE-lane request if that changes — this doc was corrected in
the same commit as the decision rather than left describing something unshipped.
`velox.service` and `velox.socket` are both DAEMON's (`packaging/systemd/README.md`,
`daemon/src/rpc/systemd_activation.cpp`) — real `sd_listen_fds()` socket activation, not a
plain `exec`. This package installs both units verbatim and lets `dh_installsystemduser`
(compat 13) pick them up from the install tree; see `packaging/README.md` for what that
does and does not do at install time for an already-running session.
`postinst` additionally drops per-user native-messaging manifests for the packaging formats
that need them, and **detects whether Firefox is a snap** — if so it prints (and the GUI's
first-run wizard shows) a one-line note that the extension will pair over loopback.
+6 -1
View File
@@ -67,7 +67,12 @@ failure for the whole project — not a skipped guard, not a GUI-only problem.
---
## R2 — `--check` verifies the outcome, not the thing that can break
## R2 — `--check` verifies the outcome, not the thing that can break — RESOLVED
**Status: done.** `tools/bootstrap.sh` now validates every apt name in `PKGS` via
`apt-cache policy` and greps for the `Candidate: (none)` line rather than trusting the
exit code (which is 0 either way) — the exact loop this request drafted. This is the
check that would have caught `libqt6svg6-dev` (R1) before the VM did.
`--check` today runs the "verify toolchain" block: `command -v` for the binaries,
`pkg-config --exists` for the dev libs (`Qt6Core`, `Qt6Widgets`, `Qt6Svg`, `libcurl`,
+100
View File
@@ -1 +1,101 @@
Owner: lane PKG/QA. See ../docs/07-packaging.md.
## `.deb` — local test build only
There is no PPA, no GPG signing, no Launchpad wiring here. This produces a `.deb` you
install with `dpkg -i` on the box you built it on (or an identical one), for testing —
not something to hand to a user or publish anywhere. See `docs/07-packaging.md`'s
package matrix for the eventual PPA plan.
```sh
sudo ./tools/bootstrap.sh --packaging # debhelper, dpkg-dev, lintian, devscripts, fakeroot
dpkg-buildpackage -us -uc -b # from the repo root; -b = binary only, no signing
sudo dpkg -i ../velox_0.1.0-1_amd64.deb
lintian ../velox_0.1.0-1_amd64.deb
```
Uninstall: `sudo dpkg -r velox` (or `sudo dpkg -P velox` to purge — see below for what
purge does and does not do here).
### Known limitations of this build — read before relying on any of these
- **`libveloxcore` is static, not `.so.1`.** The install layout in `docs/07-packaging.md`
originally called for a shared, versioned `libveloxcore.so.1`; the user decided against
building one for now (no consumer needs it as a shared object yet, and it would need a
`SOVERSION` added to CORE's own `core/CMakeLists.txt`). The doc was corrected in the
same commit as this packaging work — it no longer describes something unshipped.
- **Placeholder app icon.** `gui/resources/icons/` (GUI's lane) is empty — no real icon
art exists anywhere in the repo yet. `packaging/icons/hicolor/*/apps/velox.png` is a
plain generated placeholder (flat color, a download-arrow glyph), good enough to
install correctly and pass `desktop-file-validate`/lintian's icon checks, and nothing
more. **Replace it before any real release** — and do the icon-set licence audit
`docs/07-packaging.md`'s release checklist asks for once real art exists (this
placeholder was drawn from scratch for this package, so it has no licence question of
its own, but it is not real Velox branding either).
- **No license has been chosen for Velox's own source yet.** There is no top-level
`LICENSE` file in the repo. `debian/copyright` says so plainly (`License:
Unlicensed-TODO`) rather than inventing one — that is a real project decision, above
any one lane. Expect `lintian` to flag this package over it; that is lintian doing its
job, not a bug in this packaging, and it stays a known exception to "lintian clean"
until the project adopts a license. The release checklist's "Licence audit" item (Qt,
libcurl, SQLite, ffmpeg, icon set) is separate and still open regardless.
- **Pairing has no real approval UI in this build.** `libdbus-1-dev` is not in this
build's `Build-Depends` (D1's GUI-dialog/desktop-notification approver needs it and
isn't wired up yet — `daemon/src/main.cpp` still uses `EnvAutoApprover`
unconditionally). That approver auto-**rejects** every pairing request unless
`VELOX_PAIR_AUTO=1` is set in `veloxd`'s environment — there is no prompt, no
accept/decline, it is all-or-nothing. `postinst` prints this prominently after
install; it is repeated here so it isn't missed by anyone reading only one of the two.
**Do not set `VELOX_PAIR_AUTO=1` on a machine or account where auto-accepting every
pairing request is unacceptable.**
- **Socket activation is real.** `velox.service` and `velox.socket` both ship, verbatim
from DAEMON's `packaging/systemd/README.md` — `veloxd` receives the pre-bound fd via
`sd_listen_fds()` (`daemon/src/rpc/systemd_activation.cpp`) rather than binding its own
socket. `debian/rules` does **not** disable `dh_installsystemduser` (only the
system-level `dh_installsystemd`, since these are `--user` units); debhelper finds both
units under `lib/systemd/user/` in the install tree and enables the pair together
(`Also=velox.socket` in `velox.service`'s `[Install]`).
- **The systemd `--user` service starts enabled for your *next* login, not this one.**
debhelper's `dh_installsystemduser` (verified in the built package's `postinst`) marks
`velox.service` enabled automatically — that takes effect the next time each user's
`systemd --user` instance starts. It cannot reach an *already-running* session from a
root maintainer script, so for the session you're in right now, `postinst` prints:
```sh
systemctl --user daemon-reload
systemctl --user start velox.service
```
- **`dpkg -P velox` (purge) does not delete user data.** The uninstall test this package
is built to pass is "manifests, units and sockets removed; user data untouched *unless
purged*" — this build is deliberately conservative and leaves `$XDG_DATA_HOME/velox`
(normally `~/.local/share/velox`, the task database) alone on **both** `remove` and
`purge`, for every account. A root maintainer script deleting per-user data across
every account on the system is exactly the kind of destructive, hard-to-test operation
that deserves its own design pass, not a first cut bolted on here. `postrm` only ever
undoes what `postinst` did: the per-user native-messaging manifest it copied in.
### The uninstall test, concretely
What `docs/07-packaging.md`'s release checklist asks for, and what this build actually
does:
| Removed on `dpkg -r`/`-P`? | |
|---|---|
| `/usr/bin/{veloxd,velox,velox-gui}`, `/usr/libexec/velox/velox-nmhost` | yes — dpkg itself, ordinary package files |
| `/usr/lib/systemd/user/{velox.service,velox.socket}` | yes — same |
| `/usr/lib/mozilla/native-messaging-hosts/com.velox.host.json` | yes — same |
| Per-user `~/.mozilla/native-messaging-hosts/com.velox.host.json` | yes — `postrm`, both `remove` and `purge` |
| `$XDG_DATA_HOME/velox` (task DB, settings) | **no, on either `remove` or `purge`** — see above |
### Native messaging
`velox-nmhost` (DAEMON's `nmhost/`) and its manifest (DAEMON's
`packaging/nativehost/com.velox.host.json`) now ship in this package — the top-level
`CMakeLists.txt`'s install rules are guarded on `if(TARGET velox-nmhost)`, the same way its
`add_subdirectory()` calls are, so this lit up automatically the day that lane merged, no
packaging change needed on this end.
View File
+12
View File
@@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Velox
GenericName=Download Manager
Comment=IDM-class download manager
Exec=velox-gui
Icon=velox
Terminal=false
Categories=Network;FileTransfer;
Keywords=download;downloader;idm;resume;segmented;
StartupNotify=true
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+20
View File
@@ -0,0 +1,20 @@
.TH VELOX\-GUI 1 "2026-09-12" "velox 0.1.0" "Velox Download Manager"
.SH NAME
velox-gui \- Velox download manager, graphical client
.SH SYNOPSIS
.B velox-gui
.SH DESCRIPTION
.B velox-gui
is the Qt graphical client for
.BR veloxd (8),
the Velox download manager daemon. It takes no command-line arguments and connects
to the daemon over its local Unix socket.
.B veloxd
must already be running \(em see
.BR veloxd (8)
for starting it as a
.B systemd --user
service.
.SH SEE ALSO
.BR velox (1),
.BR veloxd (8)
+35
View File
@@ -0,0 +1,35 @@
.TH VELOXD 8 "2026-09-12" "velox 0.1.0" "Velox Download Manager"
.SH NAME
veloxd \- Velox download manager daemon
.SH SYNOPSIS
.B veloxd
.SH DESCRIPTION
.B veloxd
is the background daemon behind the Velox download manager. It manages downloads,
segmented transfers and resume state in a local SQLite database, and exposes a
JSON-RPC API over a local Unix socket (for
.BR velox (1)
and
.BR velox-gui (1))
and a loopback WebSocket (for the Firefox extension).
.PP
It takes no command-line arguments. It is normally started as a
.B systemd --user
service:
.RS
.nf
systemctl --user enable --now velox.service
.fi
.RE
.SH FILES
.TP
.I $XDG_RUNTIME_DIR/velox/velox.sock
The Unix socket clients connect to.
.TP
.I $XDG_DATA_HOME/velox/velox.db
The task and settings database (default
.IR ~/.local/share/velox/velox.db ).
.SH SEE ALSO
.BR velox (1),
.BR velox-gui (1),
.BR systemctl (1)