summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md30
-rw-r--r--Makefile5
-rw-r--r--README.md35
-rw-r--r--docs/gui-checklist.md91
-rw-r--r--man/krino-gui.1136
5 files changed, 291 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 14d4931..47af5e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,39 @@
## Unreleased
+## 0.0.10 — 2026-09-16
+
+A window, `krino-gui`, over the same engine: review and apply a plan, look
+back over runs and undo one, and edit a directory's rules with the
+configuration checked as you type. The command line is unchanged.
+
+- `krino-gui`, an optional GTK 4 program built and installed separately
+ (`make gui`, `make install-gui`; it needs GTK 4 development files and cgo,
+ which `krino` itself does not). Three tabs: **Plan** (scan a directory,
+ a checkbox and an explanation per file, Trash or delete-permanently
+ instead from a row's menu, Apply), **History and undo** (runs newest
+ first, a run's reversal file by file, refused files with the reason,
+ Undo), and **Rules** (the directory's excludes and rules as forms, or the
+ whole file as text; a check after every edit; Test on file; Save that
+ refuses a file which would not load, keeps the previous text as
+ `NAME.conf.bak`, and asks before overwriting an edit made elsewhere).
+ Described in krino-gui(1).
+- A plan the window holds open keeps its directory's lock, so nothing moves
+ underneath it, and applying or closing frees it. Each plan and each undo
+ is a run of its own in the log, exactly as a command-line invocation is,
+ and `krino log` and `krino undo` treat them no differently.
+- Engine, for both front ends: a `Session` that owns a run's lock, log, run
+ id and claims (the command line now goes through it, with no change to
+ what it does); loading a configuration with some files' text supplied in
+ memory, for the editor's live check; `Explain` that also reports a rule's
+ captures and the chain a file would get; a printer and splice for one
+ configuration form; and one atomic way to write a configuration file.
+- An undo result now says which file each outcome belongs to, so a front end
+ can show it per file. Nothing on the command line changes.
- A directory that applies nothing no longer frees what an earlier directory
of the same run put somewhere: every applied destination stays protected
from a later `(on-conflict overwrite)` for the whole run.
+
## 0.0.9 — 2026-09-15
Rules that cannot be decided fail closed in two more places, `krino check`
diff --git a/Makefile b/Makefile
index b18e486..e99e3cf 100644
--- a/Makefile
+++ b/Makefile
@@ -189,10 +189,11 @@ gui-ci: ## the GUI module's gate: gofmt, vet, tests
cd gui && CGO_ENABLED=1 go vet ./...
cd gui && CGO_ENABLED=1 go test ./...
-install-gui: gui ## install krino-gui beside krino
- mkdir -p $(BINDIR)
+install-gui: gui ## install krino-gui and its man page beside krino
+ mkdir -p $(BINDIR) $(MANDIR)/man1
rm -f $(BINDIR)/krino-gui
install -m 755 gui/krino-gui $(BINDIR)/krino-gui
+ install -m 644 man/krino-gui.1 $(MANDIR)/man1/krino-gui.1
clean: ## remove build output
rm -f $(BIN) gui/krino-gui
diff --git a/README.md b/README.md
index 81eec89..3d7f368 100644
--- a/README.md
+++ b/README.md
@@ -8,9 +8,10 @@ shows the plan before touching anything, lets you approve all of it or file
by file, logs every step, and can undo a run. Version 0.0.9 is the engine
and this command-line interface: per-directory rule files, placeholders in
destinations and new names, a keyword cache that makes a rerun fast, and
-builds for Linux, FreeBSD and OpenBSD. It is not a GUI (that comes later), a
-watch mode, OCR, EXIF dates, macOS or Windows support, a shell-command
-action, or a way to look inside archives.
+builds for Linux, FreeBSD and OpenBSD. Version 0.0.10 adds `krino-gui`, an
+optional GTK 4 window onto the same engine (see below). It is not a watch
+mode, OCR, EXIF dates, macOS or Windows support, a shell-command action, or
+a way to look inside archives.
## Install
@@ -210,6 +211,32 @@ that contain your home directory's path or an email address, and it catches
rule content only when a private pattern list is configured with
`git config krino.leakpatterns FILE`.
+## The window
+
+`krino-gui` is an optional GTK 4 window onto the same engine: it plans a
+directory, shows what would happen to each file with the explanation beside
+it, applies the files you check, undoes a run, and edits a directory's rules
+as forms or as text with the configuration checked as you type. Every
+decision is the engine's, so the window and the command line agree, and a
+run it applies is an ordinary run in the log that `krino undo` can reverse.
+
+```
+make gui && make install-gui
+```
+
+It lives in `gui/`, a nested module of its own, and needs GTK 4 development
+files and cgo — which the command line does not, so neither is needed to
+build or use `krino` itself:
+
+```
+sudo apt install libgtk-4-dev libgirepository1.0-dev # Debian, Devuan
+```
+
+The release tarballs hold the cross-compiled `krino` only; `krino-gui` is
+built from source on the machine that runs it. `man/krino-gui.1` describes
+the window, and `docs/gui-checklist.md` is what is run by hand before a
+release that changes it.
+
## Safety
- `(delete)` moves a file to the freedesktop.org Trash by default, not
@@ -233,7 +260,7 @@ rule content only when a private pattern list is configured with
## Status
-**0.0.9, local only.** The module path is `krino`; `go install` only
+**0.0.10, local only.** The module path is `krino`; `go install` only
works once a remote is chosen and the imports are renamed to match
(`docs/design.md`, §18). Until then, build from a clone.
`krino -n --json`'s output shape is unstable before krino 1.0 — don't
diff --git a/docs/gui-checklist.md b/docs/gui-checklist.md
new file mode 100644
index 0000000..04cb6af
--- /dev/null
+++ b/docs/gui-checklist.md
@@ -0,0 +1,91 @@
+# krino-gui: the checklist before a release
+
+The GTK layer has no automated tests (gui-design.md §6): package
+`gui/internal/model` is tested, `gui/internal/ui` is not. This list is run
+by hand before every release that changes the GUI, and what it found goes
+in the release's plan record.
+
+Run it against a sandbox, never a real directory:
+
+```sh
+S=$(mktemp -d)
+mkdir -p "$S/home/.config/krino/dirs" "$S/inbox"
+HOME="$S/home" XDG_CONFIG_HOME="$S/home/.config" XDG_DATA_HOME="$S/home/.local/share" \
+ XDG_STATE_HOME="$S/home/.local/state" XDG_CACHE_HOME="$S/home/.cache" krino init
+# write dirs/inbox.conf with (path "$S/inbox") and a few rules, put
+# invented files in "$S/inbox", then run krino-gui with the same HOME and
+# XDG_* set.
+```
+
+A headless X server keeps the run out of the way of whatever else is on the
+screen, and lets `import` take the same screenshots:
+
+```sh
+Xvfb :99 -screen 0 1280x800x24 &
+DISPLAY=:99 krino-gui &
+DISPLAY=:99 import -window "$(DISPLAY=:99 xdotool search --name '^krino$' | tail -1)" shot.png
+```
+
+A dialog is its own window: take it by its own id, not the main window's.
+
+## Plan tab
+
+1. The directory picker lists every included directory, and the path beside
+ it is the one the file names.
+2. Scan plans it; the counts line reads like `krino -n`'s: scanned, to act
+ on, excluded, skipped, with warnings.
+3. Each row shows the file, what would happen and where, and the rule. A
+ file krino could not decide about is listed and cannot be checked.
+4. Select all, None, and the Apply button's count agree with the boxes.
+5. Selecting a row explains it: every step, its rule and reason, and any
+ warning.
+6. Right-clicking a row offers Trash instead and Delete permanently
+ instead. The second asks first, names the file, and Escape leaves the
+ plan as it was.
+7. Apply acts on the checked files only: each row shows done, failed with
+ the reason, or declined, and the status bar summarises.
+8. While a plan is open, `krino -n` on that directory waits for the lock;
+ after Apply, or after closing the window, it proceeds.
+
+## History and undo tab
+
+9. Runs are newest first, with time, directory and counts; a reversed run
+ says `(undone)`.
+10. Selecting a run shows its reversal: the header counts, one row per
+ file, refused rows in red and not checkable.
+11. Undo reverses the checked files, logs the rest as declined, and the run
+ list then shows the undo run and marks the original.
+12. Selecting an undo run offers what is left of the run it reversed, as
+ plain `krino undo` does.
+
+## Rules tab
+
+13. Forms lists the directory itself, then the excludes and rules with
+ their actions.
+14. Selecting a rule fills its form: name, conditions, actions, `(stop)`,
+ settings.
+15. Changing a field rewrites only that form - check on the Text sub-tab
+ that every comment and every other rule is untouched.
+16. Add rule inserts after the selected rule and the check stays clean;
+ Delete asks first and takes the comment lines above the rule; Up and
+ Down move a rule with those comments.
+17. The directory's settings form writes into the header, above the rules,
+ and an empty field takes the setting out of the file.
+18. A form with comments inside it warns before an edit drops them and
+ offers the Text tab.
+19. Text: a mistake appears within a second as `file:line:col` in red, Save
+ greys out, and clicking the message goes to the line.
+20. Test on file prints the trace, the captures and the chain, answering
+ from the unsaved text.
+21. Save writes the file, leaves the previous text as `NAME.conf.bak`, and
+ the Plan tab then plans with the new rules.
+22. With the file changed underneath (edit it in another program), Save
+ offers Reload, Overwrite and Cancel; Overwrite keeps the other text as
+ the backup.
+
+## Window
+
+23. Nothing on disk changes until Apply, Undo or Save.
+24. Closing the window releases the directory lock it held.
+25. A configuration that does not load prints the problem and exits 2
+ rather than opening a window.
diff --git a/man/krino-gui.1 b/man/krino-gui.1
new file mode 100644
index 0000000..5f7b803
--- /dev/null
+++ b/man/krino-gui.1
@@ -0,0 +1,136 @@
+.\" SPDX-License-Identifier: GPL-3.0-or-later
+.Dd September 16, 2026
+.Dt KRINO-GUI 1
+.Os
+.Sh NAME
+.Nm krino-gui
+.Nd review, undo and edit krino's rules in a window
+.Sh SYNOPSIS
+.Nm
+.Op Fl c Ar file
+.Op Fl version
+.Sh DESCRIPTION
+.Nm
+is a GTK 4 window onto the same engine
+.Xr krino 1
+uses: it plans a directory, shows what would happen to each file, applies
+what you choose, undoes a run, and edits a directory's rules. Every
+decision - what matches, what is excluded, where a file lands, what may be
+deleted - is the engine's, so the window and the command line always agree.
+.Pp
+It is a separate program from
+.Xr krino 1 ,
+built and installed separately
+.Pq Cm make gui , Cm make install-gui ,
+because it needs GTK 4 and cgo, which the command line does not.
+.Pp
+The options are:
+.Bl -tag -width Ds
+.It Fl c Ar file
+Use
+.Ar file
+instead of
+.Pa ~/.config/krino/krino.conf .
+.It Fl version
+Print the version and exit.
+.El
+.Pp
+A configuration that does not load is reported the way
+.Xr krino 1
+reports it, and no window opens.
+.Ss Plan
+Pick one of the directories
+.Pa krino.conf
+includes and press
+.Cm Scan .
+Scanning takes that directory's lock, which is held while the plan is
+shown, so nothing moves underneath it; a directory another krino is working
+in is reported rather than waited for. Each row is a file, what would
+happen to it and where, and the rule that decided. A file krino could not
+decide about - unreadable content, a failed duplicate check - is listed with
+the reason and cannot be selected.
+.Pp
+Selecting a row explains it: every step with its rule and reason, and any
+warning. The right button offers
+.Cm Trash instead
+and
+.Cm Delete permanently instead ,
+the second only after a confirmation naming the file, as the
+.Cm t
+and
+.Cm d
+keys do in the terminal review.
+.Pp
+.Cm Apply
+acts on the checked files and logs the rest as declined, exactly as
+approving file by file in the terminal does. The run is written to the log
+under its own run id, so
+.Xr krino 1
+can list and undo it.
+.Ss History and undo
+The runs, newest first, with what each did and whether it has been undone.
+Selecting one shows its reversal: a row per file, refused files with the
+reason and never checkable, and the counts. Undoing takes the locks of
+every directory involved, reverses the checked files, and logs the rest as
+declined. Selecting an undo run offers what is left of the run it reversed,
+as plain
+.Cm krino undo
+does.
+.Ss Rules
+Only a directory's own file,
+.Pa dirs/NAME.conf ,
+is edited;
+.Pa krino.conf
+is not.
+.Pp
+.Cm Forms
+lists the directory itself, its excludes and its rules. A rule's form holds
+its name, its conditions, its actions in order,
+.Ic (stop) ,
+and the three rule settings; the directory's form holds the settings
+.Xr krino.conf 5
+documents, an empty field meaning krino's default. A condition is its kind
+and its arguments as the file writes them, so no test is out of reach and
+none is silently rewritten.
+.Cm Add rule
+inserts after the selected rule,
+.Cm Delete
+asks first, and
+.Cm Up
+and
+.Cm Down
+move a rule with the comment lines directly above it.
+.Pp
+.Cm Text
+is the whole file. Either way the configuration is checked as it is edited,
+about a second after typing stops: problems are listed with
+.Ar file : Ns Ar line : Ns Ar column ,
+and clicking one goes to that line.
+.Cm Test on file
+answers what the unsaved rules would do to one file, with the trace, the
+captures and the chain.
+.Pp
+.Cm Save
+is refused while the check reports anything, so a window cannot leave krino
+unable to run. It writes atomically, keeps what was there as
+.Pa NAME.conf.bak ,
+and, if the file changed on disk since it was opened, offers to reload,
+overwrite or cancel. Nothing on disk changes until Apply, Undo or Save.
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa ~/.config/krino/krino.conf
+The main configuration, as for
+.Xr krino 1 .
+.It Pa ~/.config/krino/dirs/NAME.conf
+A directory's rules, and what the Rules tab edits.
+.It Pa ~/.config/krino/dirs/NAME.conf.bak
+The text a save replaced.
+.El
+.Sh EXIT STATUS
+.Ex -std
+It exits 2 when the configuration does not load.
+.Sh SEE ALSO
+.Xr krino 1 ,
+.Xr krino.conf 5
+.Sh AUTHORS
+krino is free software under the GPL, version 3 or later.