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
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[env]
TS_RS_EXPORT_DIR = { value = "src/lib/types/generated", relative = true }

[target.'cfg(all(target_os = "windows", target_env = "msvc"))']
rustflags = ["-C", "target-feature=+crt-static"]
14 changes: 13 additions & 1 deletion .github/workflows/lint-rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ jobs:
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- run: cargo test --workspace

test-windows:
name: cargo test (Windows persistence)
runs-on: windows-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Install Rust toolchain
run: rustup toolchain install --no-self-update
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
- run: "cargo test --package procnote-tauri persistence::"

doc:
name: cargo doc
runs-on: ubuntu-latest
Expand Down Expand Up @@ -103,7 +115,7 @@ jobs:
- uses: crate-ci/typos@bee27e3a4fd1ea2111cf90ab89cd076c870fce14 # v1.48.0

collect-lint-rust:
needs: [clippy, fmt, test, doc, check-types, typos]
needs: [clippy, fmt, test, test-windows, doc, check-types, typos]
runs-on: ubuntu-latest
steps:
- run: echo "All Rust checks passed!"
56 changes: 52 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ concurrency:

env:
NODE_VERSION: 22
# tauri-build statically links the versioned VC runtime when this is enabled.
STATIC_VCRUNTIME: "true"

jobs:
build-tauri:
Expand All @@ -20,9 +22,11 @@ jobs:
- platform: macos-latest
args: "--target aarch64-apple-darwin"
rust-targets: "aarch64-apple-darwin,x86_64-apple-darwin"
binary-arch: arm64
- platform: macos-latest
args: "--target x86_64-apple-darwin"
rust-targets: "aarch64-apple-darwin,x86_64-apple-darwin"
binary-arch: x86_64
- platform: ubuntu-22.04
args: ""
rust-targets: ""
Expand Down Expand Up @@ -61,11 +65,12 @@ jobs:

- run: pnpm install

- name: Build CLI binary (Windows only)
if: matrix.platform == 'windows-latest'
- name: Remove cached package artifacts
shell: bash
run: |
cargo build --release --package procnote-cli
Copy-Item "target/release/procnote.exe" "src-tauri/resources/cli/procnote.exe"
if [ -d target ]; then
find target -type d -name bundle -prune -exec rm -rf {} +
fi

- uses: tauri-apps/tauri-action@1deb371b0cd8bd54025b384f1cd735e725c4060f # v1.0.0
env:
Expand All @@ -76,4 +81,47 @@ jobs:
releaseBody: "See the assets to download and install this version."
releaseDraft: true
prerelease: false
tauriScript: "pnpm run tauri"
args: ${{ matrix.args }}

- name: Validate packaged macOS launcher
if: runner.os == 'macOS'
shell: bash
run: |
dmg=$(find target -type f -path '*/bundle/dmg/*.dmg' -print -quit)
test -n "$dmg"
scripts/validate-macos-package.sh "$dmg" "${{ matrix['binary-arch'] }}"

- name: Validate packaged Linux launcher
if: runner.os == 'Linux'
shell: bash
run: |
deb=$(find target -type f -path '*/bundle/deb/*.deb' -print -quit)
test -n "$deb"
scripts/validate-linux-package.sh "$deb"

- name: Validate packaged Windows launchers and installers
if: runner.os == 'Windows'
shell: pwsh
run: |
$installer = Get-ChildItem target -Recurse -Filter "*-setup.exe" |
Where-Object { $_.FullName.Contains("\bundle\nsis\") } |
Select-Object -First 1
$msi = Get-ChildItem target -Recurse -Filter "*.msi" |
Where-Object { $_.FullName.Contains("\bundle\msi\") } |
Select-Object -First 1
if ($null -eq $installer) {
throw "NSIS installer was not produced"
}
if ($null -eq $msi) {
throw "MSI installer was not produced"
}

$legacyInstaller = Join-Path $env:RUNNER_TEMP "procnote_0.0.4_x64-setup.exe"
Invoke-WebRequest `
-Uri "https://github.com/ut-issl/procnote/releases/download/v0.0.4/procnote_0.0.4_x64-setup.exe" `
-OutFile $legacyInstaller
./scripts/validate-windows-package.ps1 `
-InstallerPath $installer.FullName `
-MsiPath $msi.FullName `
-LegacyInstallerPath $legacyInstaller
2 changes: 1 addition & 1 deletion .github/workflows/update-homebrew.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
depends_on :macos

app "procnote.app"
binary "\#{appdir}/procnote.app/Contents/MacOS/procnote"
binary "\#{appdir}/procnote.app/Contents/Resources/bin/procnote"

uninstall quit: "com.github.shunichironomura.procnote"

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ node_modules

# Rust
/target
/src-tauri/launchers/bin/

# Runtime data (execution logs inside each procedure directory)
.executions
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
1. **`crates/procnote-core/`** — Pure Rust domain logic. No Tauri dependency. Contains event types, execution state machine, and template parser.
2. **`src-tauri/`** — Tauri shell. Bridges core to desktop via IPC commands. Owns serialization DTOs (`ExecutionSummary`, `StepSummary`, etc.) and filesystem I/O.
3. **`src/`** — SvelteKit + Svelte 5 frontend. Uses runes (`$state`, `$derived`, `$props`), not stores.
- **`crates/procnote-launcher/`** is a Tauri-free console adapter outside those domain layers. It owns `procnote [WORKSPACE]`, prints help/version synchronously, and detaches the packaged GUI. It must never depend on `procnote-tauri`, Tauri, or GUI/dialog libraries.

### Core domain (`procnote-core`)

Expand Down
22 changes: 13 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[workspace]
resolver = "3"
members = ["crates/procnote-cli", "crates/procnote-core", "src-tauri"]
members = ["crates/procnote-core", "crates/procnote-launcher", "src-tauri"]

[workspace.package]
version = "0.0.4"
version = "0.0.5"
description = "Event-sourced desktop app for tracking step-by-step procedures"
readme = "README.md"
repository = "https://github.com/shunichironomura/procnote"
Expand All @@ -16,7 +16,6 @@ chrono = { version = "0.4.43", features = ["serde"] }
clap = { version = "4.5.56", features = ["derive"] }
log = "0.4"
names = { version = "0.14.0", default-features = false }
procnote-tauri = { path = "src-tauri" }
pulldown-cmark = "0.13.0"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
Expand Down
35 changes: 26 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ Connect PSU to DUT J1 connector. Set voltage to 5.0V. Enable output.
brew install --cask ut-issl/tap/procnote
```

This installs the app to `/Applications/` and creates a `procnote` CLI command in your PATH.
Homebrew installs the app to `/Applications/` and links its terminal launcher into your PATH. If you install the DMG manually, create the link yourself:

```sh
sudo ln -sf "/Applications/procnote.app/Contents/Resources/bin/procnote" /usr/local/bin/procnote
```

> [!NOTE]
> The macOS builds are not currently code-signed or notarized. After installing, you need to remove the quarantine attribute:
Expand All @@ -159,15 +163,26 @@ This installs the app to `/Applications/` and creates a `procnote` CLI command i
>
> Without this, macOS will show a "damaged and can't be opened" error.

### Windows / Linux
### Windows

> [!NOTE]
> Windows and Linux distribution is not well organized yet. Download installers manually from the [Releases page](https://github.com/ut-issl/procnote/releases).
>
> Available artifacts:
>
> - **Windows:** `.msi` and `.exe` installers
> - **Linux:** `.deb` package and `.AppImage`
Download the NSIS `.exe` installer from the [Releases page](https://github.com/ut-issl/procnote/releases). It installs the terminal launcher and adds its directory to your user PATH. Open a new terminal after installation.

The `.msi` installer also contains the launcher, but its `bin` directory must currently be added to PATH manually.

### Linux

The `.deb` package installs both the desktop application and `/usr/bin/procnote`. AppImage users must install their own PATH entry or detached launcher for the downloaded AppImage.

### Launch from a terminal

```sh
procnote .
procnote /path/to/workspace
procnote --help
procnote --version
```

Workspace commands start the desktop application and immediately return control to the terminal. Help, version, and argument errors are printed synchronously without starting the GUI.

## Development

Expand Down Expand Up @@ -198,4 +213,6 @@ Three layers with strict dependency direction:
2. **`src-tauri/`** -- Tauri shell. Bridges core to desktop via IPC commands. Owns serialization DTOs and filesystem I/O.
3. **`src/`** -- SvelteKit + Svelte 5 frontend.

**`crates/procnote-launcher/`** is a separate, Tauri-free console adapter. It handles the public terminal interface and starts the packaged GUI; it does not participate in the domain dependency layers above.

Executions are stored as append-only JSONL event logs under `.executions/`.
21 changes: 0 additions & 21 deletions crates/procnote-cli/Cargo.toml

This file was deleted.

3 changes: 0 additions & 3 deletions crates/procnote-cli/src/main.rs

This file was deleted.

26 changes: 26 additions & 0 deletions crates/procnote-launcher/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "procnote-launcher"
edition = "2024"
version.workspace = true
description.workspace = true
readme.workspace = true
repository.workspace = true
license.workspace = true
keywords.workspace = true
categories.workspace = true

[dependencies]
clap.workspace = true
thiserror.workspace = true

[lints]
workspace = true

[target."cfg(unix)".dependencies]
libc = "0.2.186"

[target."cfg(windows)".dependencies]
windows-sys = { version = "0.61.2", features = ["Win32_System_Threading"] }

[dev-dependencies]
tempfile.workspace = true
Loading
Loading