Files
YKanBan/USAGE.md
T
doyaGu 22102cd1ea fix(storage): initialize workspaces under the lock in one transaction
Follows PLAN 4.2: create .ykanban, take the lock, then build the database.
SqliteDatabase.Create writes every migration and the preset columns in a
single transaction and deletes the file again on failure, so no empty
version-0 database is left behind. WorkspaceSession.Initialize keeps the lock
into the session instead of releasing and re-acquiring it.

A lock conflict while initializing shows the lock-conflict page.
2026-10-03 08:12:35 -04:00

254 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# YKanBan usage
YKanBan is a local, offline kanban board. Like Git, it keeps its data in a
`.ykanban` folder inside the project folder it manages (the **workspace**).
Each YKanBan window manages exactly one workspace; several windows can run at
the same time on different workspaces.
- [Installing](#installing)
- [Starting YKanBan](#starting-ykanban)
- [macOS](#macos)
- [Workspaces, Git and backups](#workspaces-git-and-backups)
- [Search syntax](#search-syntax)
- [Settings file](#settings-file)
## Installing
Each release build is a self-contained archive; no .NET runtime is needed.
| Platform | Archive | Executable |
|---|---|---|
| Windows x64 | `YKanBan-<version>-win-x64.zip` | `YKanBan.exe` |
| Linux x64 | `YKanBan-<version>-linux-x64.tar.gz` | `YKanBan` |
| macOS Intel | `YKanBan-<version>-osx-x64.tar.gz` | `YKanBan.app` (see [macOS](#macos)) |
| macOS Apple silicon | `YKanBan-<version>-osx-arm64.tar.gz` | `YKanBan.app` (see [macOS](#macos)) |
Extract the archive anywhere. To type `ykanban <path>` as shown below, put the
executable on your `PATH` under that name, for example:
```sh
# Linux
ln -s /opt/YKanBan-<version>-linux-x64/YKanBan ~/.local/bin/ykanban
# macOS
ln -s /Applications/YKanBan.app/Contents/MacOS/YKanBan /usr/local/bin/ykanban
```
On Windows, add the extracted folder to `PATH`; `ykanban` then finds
`YKanBan.exe` because Windows ignores case.
## Starting YKanBan
The only way to start YKanBan is with the workspace path:
```sh
ykanban <path>
```
- Exactly one argument is accepted. A relative path is resolved against the
current working directory, so `ykanban .` opens the current folder (but see
[macOS](#macos) when starting through `open`).
- YKanBan looks for `.ykanban` **only in `<path>` itself**; it does not search
parent folders the way Git does.
- There are no command-line options. An argument starting with `-` is never
treated as a path; to open a folder whose name starts with `-`, write it as
`./-name`.
When the board cannot be shown, the whole window shows one of these pages
instead:
| Page | When |
|---|---|
| Invalid arguments | No argument, more than one argument, an empty or whitespace-only argument, an argument starting with `-` (including `--help`), or a path the operating system cannot represent (for example one containing a NUL character). Shows the usage line. |
| Folder not found | `<path>` does not exist or is not a folder. |
| No workspace here | `<path>` exists but has no `.ykanban`. The **Initialize workspace** button creates one, with the columns To Do / In Progress / Done (named in the current interface language). |
| Workspace locked | Another YKanBan window already has this workspace open. Close that window first. Also shown when another window takes the lock while you initialize. |
| Cannot open workspace | The database was created by a newer YKanBan, is damaged or cannot be opened, or a file-system or permission error occurred (also when initializing fails for a reason other than the lock). The English error details can be selected and copied. |
The window title is `<workspace name> - YKanBan` while a workspace is open and
just `YKanBan` on these pages.
## macOS
The app is not notarized. After extracting, remove the download quarantine
once, or macOS refuses to open it:
```sh
xattr -dr com.apple.quarantine YKanBan.app
```
Double-clicking `YKanBan.app` starts it without a path, so it only shows the
**Invalid arguments** page. Start it from a terminal instead, either through
Launch Services or by running the executable inside the bundle:
```sh
open -n -a YKanBan --args /path/to/project
/Applications/YKanBan.app/Contents/MacOS/YKanBan /path/to/project
```
- Keep `-n`: without it, `open` only brings an already running YKanBan to
the front and drops the path, instead of starting another window.
- Give `open` an **absolute** path. An app started by `open` runs in `/`, so
`open -n -a YKanBan --args .` opens `/`, not the current folder. Running the
executable inside the bundle resolves relative paths normally.
- `open -a YKanBan` finds the app once it is in `/Applications` (or another
folder Launch Services knows about).
## Workspaces, Git and backups
- **Do not commit `.ykanban` to Git.** Add it to your global ignore file once,
so no repository picks it up. If `git config --global core.excludesFile`
prints a file, add the line `.ykanban/` to that file; otherwise create one:
```sh
echo ".ykanban/" >> ~/.gitignore_global
git config --global core.excludesFile ~/.gitignore_global
```
- **Back up or move all three database files together**: `ykanban.db`,
`ykanban.db-wal` and `ykanban.db-shm` in `.ykanban/`. Recent changes may
still be in the `-wal` file; copying only `ykanban.db` can lose them. The
simplest safe backup is to close YKanBan and copy the whole `.ykanban`
folder.
- **Network shares (SMB, NFS, …) are not supported.** The database and the
workspace lock rely on local file-system features that do not work reliably
over a network. YKanBan does not detect this; keep workspaces on a local
disk.
- `.ykanban/ykanban.lock` is held while a window has the workspace open and is
released automatically when YKanBan exits or crashes.
## Search syntax
Type an expression in the search box on the **Board** tab and click
**Search** (or press Enter). Searching only happens then; there is no search
while typing. The **×** button clears the box and shows every card again.
- Columns are always shown, even when none of their cards match.
- An empty or blank expression shows every card.
- After any change (adding, editing, moving or deleting cards, columns or
tags), the board re-runs the **last expression that searched successfully**,
not whatever is in the box at that moment. Cards that stop matching
disappear; new cards that do not match are not shown.
### Examples
| Expression | Finds cards… |
|---|---|
| `login` | whose title or content contains "login" |
| `login crash` | containing both words (anywhere in title or content) |
| `login OR signup` | containing either word |
| `tag:bug title:login` | tagged `bug` whose title contains "login" |
| `tag:bug OR tag:ui` | tagged `bug` or `ui` |
| `(tag:bug OR tag:ui) column:Done` | tagged `bug` or `ui` in the column titled "Done" |
| `"dark mode"` | whose title or content contains "dark mode" |
| `tag:"needs review"` | tagged `needs review` |
| `id:61` or `id:#61` | number 61 |
| `"http://example.com"` | containing the URL (a `:` must be quoted) |
| `"AND"` | containing the text "AND" |
### Grammar
```
query := orExpr
orExpr := andExpr ( OR andExpr )*
andExpr := operand ( (AND)? operand )* -- neighbours are joined by AND
operand := atom | '(' orExpr ')'
atom := word | phrase | qualifier
qualifier := key ':' value
key := tag | title | content | id | column
value := word | phrase -- tag / title / content / column
| '#'? digit+ -- id: a positive decimal integer
word := one or more characters, except whitespace and ( ) " : \ ;
not equal to AND or OR
phrase := '"' any text '"' -- escapes: \" and \\
```
### Operators
- `AND` and `OR` are operators **only in uppercase**. `and` and `or` are
ordinary words.
- Writing words next to each other means `AND`: `a b` is `a AND b`.
- `AND` binds tighter than `OR`: `a OR b c` is `a OR (b AND c)`. Use
parentheses to group differently: `(a OR b) c`.
- To search for the literal text `AND` or `OR`, quote it: `"AND"`,
`tag:"OR"`.
- The search keywords (`AND`, `OR`, `tag`, `title`, `content`, `id`,
`column`) are always English, whatever the interface language. Qualifier
keys are lowercase only: `Tag:bug` is an unknown qualifier.
### What each atom matches
| Atom | Matches when |
|---|---|
| word or phrase | the card title **or** content contains the text |
| `title:` value | the card title contains the text |
| `content:` value | the card content contains the text |
| `tag:` value | the card has a tag whose name **equals** the text |
| `column:` value | the card is in a column whose title **equals** the text |
| `id:` value | the card number equals the value |
- A qualifier value can be a word (`tag:bug`) or a phrase
(`tag:"needs review"`). Use a phrase for values containing spaces, `(`,
`)`, `:` or `\`, and for the values `AND` / `OR`.
- `id:` takes an unquoted positive integer, optionally prefixed with `#`:
`id:61`, `id:#61`.
### Quoting and escapes
- A phrase is text in double quotes. Inside it, `\"` stands for a quote and
`\\` for a backslash; any other backslash is an error.
- Outside quotes, `\` is not allowed at all, and `:` always starts a
qualifier. Quote any text containing them: `"C:\\temp"`, `"a:b"`.
### Case
All matching ignores case, for letters of every language: `tag:BUG` finds
`bug`, and `ÄRGER` finds `ärger`. Text is otherwise compared literally: `%`,
`_` and `*` have no special meaning.
Tag names and column titles must be unique ignoring case for the letters A–Z
only. Two tags such as `Ä` and `ä` can therefore both exist, and `tag:ä`
matches both.
### Invalid expressions
An invalid expression does not search. A dialog shows "The query expression is
invalid. Details: …" followed by the parser's message (always in English).
After closing it, the box keeps your text for correcting and the board keeps
the previous result.
These are invalid:
| Problem | Example |
|---|---|
| Unbalanced parentheses | `(tag:bug`, `tag:bug)` |
| Parentheses nested more than 64 levels deep | `((((…a…))))` with 65 `(` |
| An operator with a missing side | `bug AND`, `OR bug` |
| Consecutive operators | `a AND OR b` |
| A qualifier without a value | `tag:` |
| `AND` / `OR` as an unquoted qualifier value | `tag:AND` (write `tag:"AND"`) |
| An unterminated phrase | `"dark mode` |
| An invalid escape in a phrase | `tag:"a\x"` |
| A backslash outside a phrase | `C:\temp` |
| An unknown qualifier key | `label:bug`, `Tag:bug`, `http://x` |
| An unquoted value containing `:` | `title:a:b` |
| An `id:` value that is not an unquoted positive integer | `id:abc`, `id:0`, `id:"61"` |
## Settings file
Settings (language, theme, card sort order, column width and the confirmation
switches) are stored in `app.json`:
| Platform | Location |
|---|---|
| Windows | `%APPDATA%\YKanBan\app.json` |
| Linux, macOS | `~/.config/YKanBan/app.json` (`$XDG_CONFIG_HOME/YKanBan/app.json` when that is set) |
- The file is written when YKanBan exits, and only if a setting was changed in
that session. With several windows open, the last one closed after changing
a setting wins.
- A language change takes effect after restarting YKanBan; a theme change
applies immediately.
- If the file cannot be parsed, it is saved as `app.json.bak` and the defaults
are used. A single invalid value falls back to its default; the other
values are kept.