os: the six user folders and the user-dirs.dirs reading (step 1 of #130, OS slice 6) #531

Closed
opened 2026-10-27 03:42:55 +00:00 by orion · 7 comments
Collaborator

Goal

Slice 6 of docs/design/OS.md, first step (epic #130): std/os answers the six user folders Directories.documents(), downloads(), desktop(), pictures(), music() and videos() on Windows, Linux, macOS and FreeBSD, with the user-dirs.dirs reading of the XDG half in TorbScript. The browser answers OsError.Unsupported, like the base directories do.

Specification

Acceptance criteria

  1. Directories gains documents(), downloads(), desktop(), pictures(), music() and videos(), each static fn ...(): Result<Path, OsError> with a doc comment, as in OS.md 5.8, each a match OperatingSystem.current like the base six.
  2. Linux and FreeBSD (xdg/directories.trb): read user-dirs.dirs in the configuration directory ($XDG_CONFIG_HOME, else ~/.config) and take XDG_DOCUMENTS_DIR, XDG_DOWNLOAD_DIR, XDG_DESKTOP_DIR, XDG_PICTURES_DIR, XDG_MUSIC_DIR and XDG_VIDEOS_DIR; a missing file, a missing key, or a value that is not an absolute path after $HOME expansion falls back to ~/Documents, ~/Downloads, ~/Desktop, ~/Pictures, ~/Music, ~/Videos. The file is read with the existing file helper of std/os (no new native).
  3. The parser of user-dirs.dirs is public and pure (text, home, key in; Path? out), so its tests run on every machine with captured text. They cover: the usual file with XDG_DOCUMENTS_DIR="$HOME/Documents" lines; comment and blank lines skipped; a quoted absolute path without $HOME; a value renamed by the user ("$HOME/Dokumente"); a key set to "$HOME/" (the XDG way to say "this folder does not exist": falls back, not the home directory itself); a relative value ignored; an unterminated quote ignored; a line for another key not mistaken for the asked one (XDG_DOCUMENTS_DIR_EXTRA).
  4. Windows (windows/directories.trb): Windows.knownFolder with the Known Folder ids FOLDERID_Documents, FOLDERID_Downloads, FOLDERID_Desktop, FOLDERID_Pictures, FOLDERID_Music, FOLDERID_Videos, the same way home is answered. No new native.
  5. macOS (macos/directories.trb): ~/Documents, ~/Downloads, ~/Desktop, ~/Pictures, ~/Music, ~/Movies (the Finder's name for videos), joined to home().
  6. Browser: every new function answers OsError.Unsupported through browser.unsupported, naming the question.
  7. A host test in std/os/tests/host.test.trb style: each of the six answers an absolute path on the host (every system but the browser has a fallback, so none may fail where home() works).
  8. torb check --every-target is clean; docs/standard-library/os.md documents the six with the table row of 5.8 and an example; docs check is clean and skills/ regenerated. OS.md slice 6 gets a note "Step 1 done (date)" in the slice table, like slice 3 has; the row is marked done when the epic is.

Seed impact

No. No syntax change, no new native (the Known Folder native and the file helper exist), no std name the compiler looks up by string. The compiler does not call these functions.

Size

One PR, two Conventional Commits:

  1. feat(os): the user folders on Linux and FreeBSD, with the user-dirs.dirs parser (parser, XDG half, tests)
  2. feat(os): Directories.documents and the other five user folders on every system (the Directories surface, Windows, macOS and browser arms, host test, docs, OS.md note)

Only std/os, its tests, docs/standard-library/os.md, docs/design/OS.md and skills/ change; no C.

Part of #130 (epic).

## Goal Slice 6 of `docs/design/OS.md`, first step (epic #130): `std/os` answers the six user folders `Directories.documents()`, `downloads()`, `desktop()`, `pictures()`, `music()` and `videos()` on Windows, Linux, macOS and FreeBSD, with the `user-dirs.dirs` reading of the XDG half in TorbScript. The browser answers `OsError.Unsupported`, like the base directories do. ## Specification - Design record: [OS.md section 5.8 (Well-known directories)](https://git.torb.dev/torbscript/language/src/branch/main/docs/design/OS.md#58-well-known-directories) (signatures and the table row "`documents` and the rest") and the slice 6 row of section 10. [docs/ROADMAP.md](https://git.torb.dev/torbscript/language/src/branch/main/docs/ROADMAP.md) lists `std/os` "the rest of their slices" (#126 to #131); this is a step of #130. - Dependency: slice 1 (the base six, `xdg/`, `Windows.knownFolder`), done. #126 (slice 2) is closed. ## Acceptance criteria 1. `Directories` gains `documents()`, `downloads()`, `desktop()`, `pictures()`, `music()` and `videos()`, each `static fn ...(): Result<Path, OsError>` with a doc comment, as in OS.md 5.8, each a `match OperatingSystem.current` like the base six. 2. Linux and FreeBSD (`xdg/directories.trb`): read `user-dirs.dirs` in the configuration directory (`$XDG_CONFIG_HOME`, else `~/.config`) and take `XDG_DOCUMENTS_DIR`, `XDG_DOWNLOAD_DIR`, `XDG_DESKTOP_DIR`, `XDG_PICTURES_DIR`, `XDG_MUSIC_DIR` and `XDG_VIDEOS_DIR`; a missing file, a missing key, or a value that is not an absolute path after `$HOME` expansion falls back to `~/Documents`, `~/Downloads`, `~/Desktop`, `~/Pictures`, `~/Music`, `~/Videos`. The file is read with the existing file helper of `std/os` (no new native). 3. The parser of `user-dirs.dirs` is public and pure (text, `home`, key in; `Path?` out), so its tests run on every machine with captured text. They cover: the usual file with `XDG_DOCUMENTS_DIR="$HOME/Documents"` lines; comment and blank lines skipped; a quoted absolute path without `$HOME`; a value renamed by the user (`"$HOME/Dokumente"`); a key set to `"$HOME/"` (the XDG way to say "this folder does not exist": falls back, not the home directory itself); a relative value ignored; an unterminated quote ignored; a line for another key not mistaken for the asked one (`XDG_DOCUMENTS_DIR_EXTRA`). 4. Windows (`windows/directories.trb`): `Windows.knownFolder` with the Known Folder ids `FOLDERID_Documents`, `FOLDERID_Downloads`, `FOLDERID_Desktop`, `FOLDERID_Pictures`, `FOLDERID_Music`, `FOLDERID_Videos`, the same way `home` is answered. No new native. 5. macOS (`macos/directories.trb`): `~/Documents`, `~/Downloads`, `~/Desktop`, `~/Pictures`, `~/Music`, `~/Movies` (the Finder's name for videos), joined to `home()`. 6. Browser: every new function answers `OsError.Unsupported` through `browser.unsupported`, naming the question. 7. A host test in `std/os/tests/host.test.trb` style: each of the six answers an absolute path on the host (every system but the browser has a fallback, so none may fail where `home()` works). 8. `torb check --every-target` is clean; `docs/standard-library/os.md` documents the six with the table row of 5.8 and an example; `docs check` is clean and `skills/` regenerated. OS.md slice 6 gets a note "Step 1 done (date)" in the slice table, like slice 3 has; the row is marked done when the epic is. ## Seed impact No. No syntax change, no new native (the Known Folder native and the file helper exist), no std name the compiler looks up by string. The compiler does not call these functions. ## Size One PR, two Conventional Commits: 1. `feat(os): the user folders on Linux and FreeBSD, with the user-dirs.dirs parser` (parser, XDG half, tests) 2. `feat(os): Directories.documents and the other five user folders on every system` (the `Directories` surface, Windows, macOS and browser arms, host test, docs, OS.md note) Only `std/os`, its tests, `docs/standard-library/os.md`, `docs/design/OS.md` and `skills/` change; no C. Part of #130 (epic).
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T09:55Z

[loop:torbscript] claim implement by session:loop-torbscript-20261027 until 2026-10-27T09:55Z
Author
Collaborator

[loop:torbscript] implement: checkpoint. Branch loop/531-user-folders pushed (2 commits): xdg half with public pure parseUserDirectory, Windows/macOS arms, the six Directories functions, parser and host tests; torb check std/os clean locally. Decided by the loop: the issue's "existing file helper of std/os" does not exist for this file (Linux.readSystemFile only reads /proc, /sys and os-release, by design), so the XDG half reads user-dirs.dirs with File.readText of std/fs (no new native, no cycle: std/fs does not import std/os). Open: browser arms are covered by browser.unsupported in Directories; still to do: docs/standard-library/os.md (table row + example), OS.md slice 6 note "Step 1 done (2026-10-27)", torb docs check + skills/ regen, open PR Closes #531, read CI with ci-wait.sh. next: docs and PR.

[loop:torbscript] implement: checkpoint. Branch `loop/531-user-folders` pushed (2 commits): xdg half with public pure `parseUserDirectory`, Windows/macOS arms, the six `Directories` functions, parser and host tests; `torb check std/os` clean locally. Decided by the loop: the issue's "existing file helper of std/os" does not exist for this file (`Linux.readSystemFile` only reads /proc, /sys and os-release, by design), so the XDG half reads `user-dirs.dirs` with `File.readText` of `std/fs` (no new native, no cycle: std/fs does not import std/os). Open: browser arms are covered by `browser.unsupported` in `Directories`; still to do: docs/standard-library/os.md (table row + example), OS.md slice 6 note "Step 1 done (2026-10-27)", `torb docs` check + `skills/` regen, open PR `Closes #531`, read CI with ci-wait.sh. next: docs and PR.
Author
Collaborator

[loop:torbscript] claim implement (continuation 1 of 3, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027 until 2026-10-27T10:10Z

[loop:torbscript] claim implement (continuation 1 of 3, pinned on anthropic:notahumanmate) by session:loop-torbscript-20261027 until 2026-10-27T10:10Z
Author
Collaborator

[loop:torbscript] implement: checkpoint. PR #532 open (Closes #531). Tier A of 78fa79d8 was red only on docs declarations --check and docs skill --check (declaration order of Directories, stale skill copy); fixed in 1d84edf2, CI running. Everything else of the gates (std/os check, tests native and VM, docs check) was green. next: read CI of 1d84edf2 with ci-wait.sh.

[loop:torbscript] implement: checkpoint. PR #532 open (`Closes #531`). Tier A of 78fa79d8 was red only on `docs declarations --check` and `docs skill --check` (declaration order of `Directories`, stale skill copy); fixed in 1d84edf2, CI running. Everything else of the gates (std/os check, tests native and VM, docs check) was green. next: read CI of 1d84edf2 with ci-wait.sh.
Author
Collaborator

[loop:torbscript] release implement: the stale claim of continuation 1 expired; PR #532 (head 1d84edf2) carries all work and forge CI is queued. next: waiting (CI on PR #532); red tier A gets a fix worker from the PR state.

[loop:torbscript] release implement: the stale claim of continuation 1 expired; PR #532 (head 1d84edf2) carries all work and forge CI is queued. next: waiting (CI on PR #532); red tier A gets a fix worker from the PR state.
Author
Collaborator

[loop:torbscript] implement: continuation 1 ended (worker run hit its time limit while waiting on CI, no further code change after the 07:28 checkpoint). PR #532 head 1d84edf2: bootstrap (linux-x64) green, tier A still running. Claim released. next: waiting (CI on PR #532); on red tier A a fix round.

[loop:torbscript] implement: continuation 1 ended (worker run hit its time limit while waiting on CI, no further code change after the 07:28 checkpoint). PR #532 head 1d84edf2: bootstrap (linux-x64) green, tier A still running. Claim released. next: waiting (CI on PR #532); on red tier A a fix round.
argus closed this issue 2026-10-27 12:33:26 +00:00
Author
Collaborator

[loop:torbscript] post-merge: PR #532 merged (argus approved at 5b49bc6, merge commit 77259d30). No After-merge steps and no deploy for torbscript/language; the change lands on main with the merge. Task closed with this evidence.

[loop:torbscript] post-merge: PR #532 merged (argus approved at 5b49bc6, merge commit 77259d30). No After-merge steps and no deploy for torbscript/language; the change lands on main with the merge. Task closed with this evidence.
Sign in to join this conversation.
No labels
loop
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#531
No description provided.