No description
  • Shell 56.6%
  • Python 18.7%
  • Ruby 13.6%
  • Lua 9.1%
  • CSS 1.1%
  • Other 0.9%
Find a file
user d993045fd1 install-swift.sh: --version VER, and a swift that refuses is not "installed"
- `--version 6.4.1` installs that exact toolchain and makes it the global
  default. "latest" moves, while a project can pin one in .swift-version, and
  swiftly's `swift` refuses to run anywhere under that file when the pinned
  version is missing.
- A false OK is fixed. With `swift` on PATH, the script took the proxy's
  refusal ("The swift version file … uses …") as the version, printed
  "already on PATH — skipping install" and exited 0, so nothing was
  installed. The default is now asked from `/` (a pin in the caller's
  directory cannot decide it) and only a successful `swift --version`
  counts, in the skip check, --check and the final verify. With --version,
  the final verify also requires that version.

- `--deps` printed "Dependencies installed." and exited 0 even when
  apt-get failed (seen on a box whose sudo needs a password, 2026-10-16).
  It now says so only on success; otherwise it prints FAILED and exits 1.
  The failing path is not exercised here, because builder's sudo is
  passwordless.

Unchanged elsewhere: no --version means latest, as before; a box with a
working swift still skips; macOS is still a no-op. Run on builder: --check
reports the real default (6.3.3) where it reported the refusal text, and
`--version 6.4.1` installed 6.4.1 as the default ("Done: Swift version
6.4.1").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 16:00:20 +00:00
.claude Add Claude memory: multi-machine replicable setup requirement 2026-06-24 13:34:12 +02:00
bin zshenv: put the monorepo's projs/tools/bin first on PATH; bin/index -> index-notes-deprecated 2026-10-09 08:46:38 +00:00
doc feat(gitd-updater): minute-by-minute autosave for git repositories 2026-09-05 15:15:40 +00:00
docs docs(scanup): readme section + lessons-learned — the two eSCL traps, measured 2026-10-07 08:37:46 +00:00
home install-swift.sh: --version VER, and a swift that refuses is not "installed" 2026-10-16 16:00:20 +00:00
lib zshenv: put the monorepo's projs/tools/bin first on PATH; bin/index -> index-notes-deprecated 2026-10-09 08:46:38 +00:00
recipes update 2025-11-27 13:18:08 +01:00
.gitignore chore: gitignore .claude/worktrees/ 2026-09-09 03:47:38 -07:00
.nvim.lua feat(shell): wd — jump to the workdir monorepo or fzf-pick a project 2026-09-03 10:16:27 -07:00
.nvimlog update 2025-11-27 13:18:08 +01:00
CLAUDE.md zshenv: put the monorepo's projs/tools/bin first on PATH; bin/index -> index-notes-deprecated 2026-10-09 08:46:38 +00:00
install zshenv: put the monorepo's projs/tools/bin first on PATH; bin/index -> index-notes-deprecated 2026-10-09 08:46:38 +00:00
Makefile update 2025-11-27 13:18:08 +01:00
readme.md zshenv: put the monorepo's projs/tools/bin first on PATH; bin/index -> index-notes-deprecated 2026-10-09 08:46:38 +00:00

Installing the environment

curl -sSL https://gurgul.pro/artur/environment/raw/branch/main/install | bash

Config:

Variable Name Default Value Description
DAT_CACHE_PATH ${HOME}/.cache/dat/ Path where cached data is stored.
DEFAULT_INTERNET_LOGIN not set
DAT_VM_DATA ${DAT_CACHE_PATH}/vm Directory for storing VM-related data.

Installing build daemon

make install-daemon

Dependencies — dat --install

The tools the shell and editor configuration in home/ depend on are installed by scripts, never by hand, and one command runs them:

Command Effect
dat --install install or update the default dependency set
dat --install <name> just one, e.g. dat --install fzf
dat --install --all include the desktop-only ones (fonts, Zed, printup)
dat --install --list what is registered, and which are in the default set
dat --install --check report what is installed — installs nothing
dat --install --forced reinstall even where the tool is already present

Every entry is a script under home/.local/bin/, registered in Install::DEPENDENCIES (lib/install.rb). Each is idempotent, so a re-run on a provisioned box skips rather than rebuilds. dat install and dat update go through the same register.

The default set is fzf, rust-tools (bat, fd), nvim and swift — what home/.zshrc and the Neovim config actually need in order to behave as written. fonts, zed and printup are real dependencies of a desktop box but not of a headless one, so they are opt-in.

fzf is not optional here: wd --find, v --open, the gf and hist aliases and bin/index-notes-deprecated (was bin/index; index is now the monorepo's Swift file indexer) are all built on it. If v --open prints "no fzf — 'wd --list' shows the projects without it", the fix is dat --install fzf.

macOS host config — dat macos

dat macos --setup      # personal defaults (settings, dock) + unattended-boot posture
dat macos --check      # is the unattended-boot posture in place? (exit 0/1)
dat macos --status     # full state dump
dat macos --defaults   # just settings + dock

The unattended-boot posture — FileVault off, auto-login, no lock screen, passwordless sudo, firewall on — is for a VM/host you fully control, where the console is the credential and the network surface is closed. Read bin/macos-config/README.md before running --setup.

Prompt width — mps

The zsh prompt has three widths, for when you drop onto a phone or a small terminal. Defined in home/.zshrc, switched with the mps function:

Command Prompt
mps full user@host ~/full/path (branch) ➜ (default)
mps git dir (branch) ➜ — minimal, keeps git info
mps static ➜ — minimal, no git, no vcs_info cost
mps no argument → cycle full → git → static → full
mps status print the active mode

The choice is saved to ~/.projps and restored by the next shell. Test: bin/test-mps.

Workdir jump — wd / v

wd gets you into the workdir monorepo and its subprojects fast; v opens Neovim there. Both defined in home/.zshrc.

Command Effect
wd cd to the workdir root — /workdir on Linux, /opt/workdir on macOS ($WORKDIR overrides; an existing path is preferred)
wd --find fzf-pick a project by name / description and cd into it
wd -f alias for --find
wd --list print the project table, no picker (works without fzf)
wd --help usage
v [files…] open Neovim (plain passthrough — replaces the old alias v=nvim)
v --open fzf-pick a project the same way and start Neovim with it as the working directory; the shell's own cwd is left alone
v -o alias for --open

A project is any directory holding a .nvim.lua marker. Its name and one-line blurb come from that file:

return { name = "hiot-hub", description = "ESP32 Hub firmware — ESP-NOW→MQTT bridge" }

This is the same table Neovim reads for fzf_ignore_dirs (home/.config/nvim/lua/keymaps.lua). A marker without a name falls back to its directory's own name. .git, .claude and node_modules are skipped during the scan.

--find and v --open need fzf on PATH — install it with dat --install fzf (see Dependencies). wd --list is the fallback that works without it.

Test: bin/test-wd (covers both wd and v).

Scanning — scanup

The companion to printup: scans from a network scanner to a PDF on the machine you run it on. It speaks eSCL (AirScan) to anything advertising _uscan._tcp, in standard-library Python — nothing to install.

Command Effect
scanup scan with the default scanner → ~/Scans/scan-YYYYMMDD-HHMMSS.pdf; the feeder if it holds paper, else the glass
scanup --select pick a scanner, save it as the default, then scan
scanup --set-default L6600 save a default (any unambiguous fragment of host or label)
scanup --list-scanners what is on the network; * marks the default
scanup --scan-from T520W this scan only, from another scanner
scanup --adf --duplex both sides of every sheet in the feeder
scanup --bw --dpi 200 smallest text scans (1-bit CCITT); --gray and --size letter also exist — both Brothers still send gray as RGB
scanup -o FILE · -o DIR/ write elsewhere (never overwrites without --force)
scanup --check Python, discovery, the default scanner, the merge tool

The default lives in ~/.config/scanup/default_scanner, the same two-line shape as printup's. A feeder job that the scanner returns as one document per page is merged with pdfunite or qpdf when present; without either, the pages are kept as numbered files and --check says how to add one.

Traps and measurements: docs/lessons-learned.md. Test: bin/test-scanup (--live scans the glass of each scanner found).

Repository autosave — gitd-updater

A systemd timer that, every minute, commits / pulls / pushes registered repositories so work in progress is never stranded on one disk. Debian only — it is built on systemd system units and refuses to install elsewhere.

Command Effect
sudo gitd-updater --install install the units and start the timer (runs as you)
gitd-updater --add /workspace register a repository (not with sudo)
gitd-updater --list registered repos, failure counts, suspensions
gitd-updater --check verify the install, and that the remote is reachable the way the unit reaches it
gitd-updater --resume [PATH] clear a suspension by hand
sudo gitd-updater --uninstall remove the units; registry and state are kept

A submodule you are actively editing (uncommitted changes newer than an hour) is held untouched; older ones are committed and pushed to their own remote before the parent's gitlink moves. Conflicts abort cleanly and retry; after five consecutive failures a repo is suspended for an hour, then retried automatically.

Full description, policy table and traps: doc/gitd-updater.md. Test: bin/test-gitd-updater (--selftest first — it proves the harness can fail).