Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,12 @@ jobs:
contents: write
strategy:
fail-fast: false
# Guards the updater artifacts, not today's build. tauri-action builds
# latest.json by fetching the existing asset off the release, merging its
# platforms map and re-uploading; concurrent legs race that
# delete-then-upload and 404 (tauri-action#1270), and upstream's fix is a
# random 1-10s retry its own src/utils.ts calls provisional.
# upload-version-json.ts returns early with no .sig files, so the race
# cannot fire until `createUpdaterArtifacts` lands, and no release is cut
# before then. Goes if the updater ever does.
# tauri-action builds latest.json by fetching the existing asset off the
# release, merging its platforms map and re-uploading. Concurrent legs
# race that delete-then-upload and 404 (tauri-action#1270), and
# upstream's fix is a random 1-10s retry its own src/utils.ts calls
# provisional. Now that `createUpdaterArtifacts` emits .sig files the
# race is live, so serialize. Goes if the updater ever does.
max-parallel: 1
matrix:
include:
Expand Down Expand Up @@ -226,6 +224,11 @@ jobs:
uses: tauri-apps/tauri-action@1deb371b0cd8bd54025b384f1cd735e725c4060f # v1.0.0
env:
GITHUB_TOKEN: ${{ github.token }}
# Signs the updater artifacts. Unrelated to Apple signing, and not
# optional: without it `createUpdaterArtifacts` emits no .sig files
# and the published latest.json would be unverifiable.
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with:
releaseId: ${{ steps.release.outputs.id }}
args: ${{ matrix.args }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
.DS_Store
*.pem

# tauri updater signing keys
*.key
*.key.pub

# debug
npm-debug.log*
yarn-debug.log*
Expand Down
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,9 @@ They cover every markdown file here, plus commit messages and PR bodies.
```

Two sections force the description to answer the two questions a reviewer
opens with, and a third section pads.
opens with, and a third section pads. Do not wrap the paragraphs: GitHub
renders every single newline in a PR body as a line break, so wrapped text
arrives as a ragged column. One line per paragraph.

- **`## Why` also says what happens when the change is wrong and how someone
finds out.** The section carries the problem the change addresses. Two more
Expand Down
13 changes: 11 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ src/
runtime.ts # AppRuntime (ManagedRuntime), wires the adapters
lib/ # Client utilities
pending-flush.ts # autosave flush registry read by the quit handshake
updater.ts # release check, offer toast, install + relaunch
ui/utils.ts # cn()
utils/ # fts-snippet, tag-query, word-count
src-tauri/
Expand Down Expand Up @@ -265,6 +266,14 @@ one chain so overlapping flushes cannot land out of order, and flushes on blur,
unmount, and quit. Rust holds `ExitRequested` until the webview reports back,
and a failed flush cancels the quit through `cancel_quit`.

An update restart is the exception. It reaches `ExitRequested` carrying
`RESTART_EXIT_CODE`, which Tauri refuses to prevent, so `lib.rs` returns before
the handshake rather than opening one it cannot honour. `installUpdate` in
`src/lib/updater.ts` awaits `flushPendingWrites` itself between
`downloadAndInstall` and `relaunch`. A failed flush leaves the app running the
old version rather than restarting, and the bundle already downloaded applies
the next time someone launches it.

### External-change reload guard

A loader refresh replaces the buffer only when the buffer is clean and the
Expand All @@ -284,8 +293,8 @@ into `attachments/`, and `write_external` writes outside the notes dir.
### The palette is the action surface

`command-palette.tsx` holds search, tag filtering via `#`, new note, pin, tag
editing, rename, move, delete, reveal, settings, and reindex. New note-level
actions belong there rather than in new chrome.
editing, rename, move, delete, reveal, settings, reindex, and the update check.
New note-level actions belong there rather than in new chrome.

`move`, `delete`, `rename`, and `tags` are sub-views of `PaletteView`. The tags view is
the one place an action row does not dismiss the palette: toggling calls
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ brew install --cask jimmy-guzman/tap/notras
The cask is published by the release pipeline, so it appears with the first
release.

Upgrade with `brew upgrade --cask notras`. Or download a `.dmg`, `.AppImage`,
notras updates itself. Or download a `.dmg`, `.AppImage`,
`.deb` or `.msi` from
[releases](https://github.com/jimmy-guzman/notras/releases), alongside that
release's `SHA256SUMS.txt`, and check what you got:
Expand Down
9 changes: 6 additions & 3 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ walkthrough is their only coverage. Run it under `pnpm dev`.
- [x] 13. `pnpm tauri build` → built artifact launches; "Open With" on a random `.md` works
- [x] 14. Type, then quit from the tray and again with ⌘Q → relaunch and the last
keystrokes are on disk
- [ ] 15. Install the first release carrying the updater, cut a second, relaunch
the installed copy → "version x.y.z is available" toast → type, leave the
keystrokes unsaved, then install → relaunches into the new version with
those keystrokes on disk. ⌘K → "check for updates..." reports either way.
Only the development message is reachable under `pnpm dev`: the check is
`PROD`-guarded, so the install path needs two real releases.

## Deferred

Expand All @@ -39,9 +45,6 @@ walkthrough is their only coverage. Run it under `pnpm dev`.
- Backlinks panel (wikilinks are one-directional today)
- Git integration UI (the folder is git-init-able by hand today)
- wdio + tauri-driver e2e (replaces the deleted Playwright smoke tests)
- In-app auto-update (`tauri-plugin-updater`; the release pipeline ships without
it, and turning it on needs a signing key, two releases to verify, and
`auto_updates true` restored to the cask so brew stops upgrading it)
- SHA-pinning the three actions in `.github/actions/install` (`release.yml`
pins everything it names, but the composite action both privileged jobs call
resolves `setup-node`, `action-setup` and `cache` by mutable major tag, and
Expand Down
44 changes: 23 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,35 @@
"@base-ui/react": "1.7.0",
"@fontsource-variable/literata": "5.3.0",
"@fontsource/ia-writer-mono": "5.3.0",
"@tanstack/react-router": "1.170.29",
"@tanstack/react-router": "1.170.30",
"@tauri-apps/api": "2.11.1",
"@tauri-apps/plugin-autostart": "2.5.1",
"@tauri-apps/plugin-dialog": "2.7.2",
"@tauri-apps/plugin-opener": "2.5.4",
"@tiptap/core": "3.30.1",
"@tiptap/extension-code-block-lowlight": "3.30.1",
"@tiptap/extension-document": "3.30.1",
"@tiptap/extension-image": "3.30.1",
"@tiptap/extension-table": "3.30.1",
"@tiptap/extension-task-item": "3.30.1",
"@tiptap/extension-task-list": "3.30.1",
"@tiptap/extension-text": "3.30.1",
"@tiptap/extensions": "3.30.1",
"@tiptap/markdown": "3.30.1",
"@tiptap/pm": "3.30.1",
"@tiptap/react": "3.30.1",
"@tiptap/starter-kit": "3.30.1",
"@tiptap/suggestion": "3.30.1",
"@tauri-apps/plugin-process": "2.3.1",
"@tauri-apps/plugin-updater": "2.10.1",
"@tiptap/core": "3.30.2",
"@tiptap/extension-code-block-lowlight": "3.30.2",
"@tiptap/extension-document": "3.30.2",
"@tiptap/extension-image": "3.30.2",
"@tiptap/extension-table": "3.30.2",
"@tiptap/extension-task-item": "3.30.2",
"@tiptap/extension-task-list": "3.30.2",
"@tiptap/extension-text": "3.30.2",
"@tiptap/extensions": "3.30.2",
"@tiptap/markdown": "3.30.2",
"@tiptap/pm": "3.30.2",
"@tiptap/react": "3.30.2",
"@tiptap/starter-kit": "3.30.2",
"@tiptap/suggestion": "3.30.2",
"class-variance-authority": "0.7.1",
"clsx": "2.1.1",
"cmdk": "1.1.1",
"date-fns": "4.4.0",
"drizzle-orm": "0.45.2",
"effect": "4.0.0-rc.109",
"lowlight": "3.3.0",
"lucide-react": "1.31.0",
"lucide-react": "1.32.0",
"react": "19.2.8",
"react-dom": "19.2.8",
"react-hotkeys-hook": "5.3.3",
Expand All @@ -60,16 +62,16 @@
"use-debounce": "10.1.1"
},
"devDependencies": {
"@biomejs/biome": "2.5.6",
"@biomejs/biome": "2.5.9",
"@tailwindcss/vite": "4.3.3",
"@tanstack/router-plugin": "1.168.32",
"@tanstack/router-plugin": "1.168.33",
"@tauri-apps/cli": "2.11.4",
"@total-typescript/ts-reset": "0.6.1",
"@types/node": "26.2.0",
"@types/react": "19.2.18",
"@types/react-dom": "19.2.4",
"@vitejs/plugin-react": "6.0.5",
"@vitest/coverage-v8": "4.1.10",
"@vitest/coverage-v8": "4.1.11",
"gitzy": "7.2.2",
"happy-dom": "20.11.2",
"jiti": "2.7.0",
Expand All @@ -78,10 +80,10 @@
"shadcn": "4.18.0",
"tailwindcss": "4.3.3",
"tw-animate-css": "1.4.0",
"typescript": "6.0.3",
"typescript": "7.0.2",
"ultracite": "7.10.5",
"vite": "8.2.1",
"vitest": "4.1.10"
"vitest": "4.1.11"
},
"packageManager": "pnpm@11.22.0"
}
Loading
Loading