-
Notifications
You must be signed in to change notification settings - Fork 3
Core Loop & Hardening & etc #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5138cbd
0dc647f
87fddaf
18db353
8570f81
076d240
8cb6a3c
3eb54c1
c9c0009
3b7e3b7
aa59cc5
bc96006
79eefd4
e451215
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,144 +1,58 @@ | ||||||
| name: Release Build | ||||||
|
|
||||||
| name: Release | ||||||
| on: | ||||||
| release: | ||||||
| types: [published] | ||||||
|
|
||||||
| permissions: | ||||||
| contents: write | ||||||
|
|
||||||
| concurrency: | ||||||
| group: release-${{ github.ref }} | ||||||
| cancel-in-progress: true | ||||||
| push: | ||||||
| tags: | ||||||
| - 'v*' | ||||||
| workflow_dispatch: | ||||||
|
|
||||||
| jobs: | ||||||
| build: | ||||||
| release: | ||||||
| permissions: | ||||||
| contents: write | ||||||
| strategy: | ||||||
| fail-fast: false | ||||||
| matrix: | ||||||
| include: | ||||||
| - platform: macos-latest | ||||||
| os: macos | ||||||
| - platform: ubuntu-latest | ||||||
| os: linux | ||||||
| - platform: windows-latest | ||||||
| os: windows | ||||||
| - platform: 'macos-latest' | ||||||
| args: '--target aarch64-apple-darwin' | ||||||
| - platform: 'macos-latest' | ||||||
| args: '--target x86_64-apple-darwin' | ||||||
| - platform: 'ubuntu-22.04' | ||||||
| args: '' | ||||||
| - platform: 'windows-latest' | ||||||
| args: '' | ||||||
|
|
||||||
| runs-on: ${{ matrix.platform }} | ||||||
|
|
||||||
| steps: | ||||||
| # Checkout full history (needed for proper tagging/version checks) | ||||||
| - name: Checkout repository | ||||||
| uses: actions/checkout@v6 | ||||||
| with: | ||||||
| fetch-depth: 0 | ||||||
| - uses: actions/checkout@v4 | ||||||
|
|
||||||
| - name: Setup Node.js | ||||||
| uses: actions/setup-node@v6 | ||||||
| with: | ||||||
| node-version: 20 | ||||||
|
|
||||||
| # Ensure tag matches package.json version | ||||||
| - name: Ensure tag matches package version | ||||||
| shell: bash | ||||||
| - name: install dependencies (ubuntu only) | ||||||
| if: matrix.platform == 'ubuntu-22.04' | ||||||
| run: | | ||||||
| TAG=${GITHUB_REF#refs/tags/v} | ||||||
| VERSION=$(node -p "require('./package.json').version") | ||||||
| if [ "$TAG" != "$VERSION" ]; then | ||||||
| echo "Tag ($TAG) does not match package.json version ($VERSION)" | ||||||
| exit 1 | ||||||
| fi | ||||||
|
|
||||||
| # Setup Bun | ||||||
| - name: Setup Bun | ||||||
| uses: oven-sh/setup-bun@v2 | ||||||
| with: | ||||||
| bun-version: latest | ||||||
| sudo apt-get update | ||||||
| sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf | ||||||
|
|
||||||
| # Cache Bun dependencies | ||||||
| - name: Cache Bun dependencies | ||||||
| uses: actions/cache@v5 | ||||||
| - name: setup node | ||||||
| uses: actions/setup-node@v4 | ||||||
| with: | ||||||
| path: | | ||||||
| ~/.bun/install/cache | ||||||
| bun.lockb | ||||||
| key: ${{ runner.os }}-bun-${{ hashFiles('bun.lockb') }} | ||||||
|
|
||||||
| # Setup Tiptap Pro registry auth | ||||||
| - name: Configure TipTap Pro auth | ||||||
| shell: bash | ||||||
| run: | | ||||||
| echo "@tiptap-pro:registry=https://registry.tiptap.dev/" > .npmrc | ||||||
| echo "//registry.tiptap.dev/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc | ||||||
| env: | ||||||
| NODE_AUTH_TOKEN: ${{ secrets.TIPTAP_TOKEN }} | ||||||
|
|
||||||
| # Install dependencies | ||||||
| - name: Install dependencies | ||||||
| run: bun install --frozen-lockfile | ||||||
|
|
||||||
| # Build Next.js (static export to out/) | ||||||
| - name: Build frontend | ||||||
| run: | | ||||||
| bun run build | ||||||
| node-version: 20 | ||||||
| cache: 'npm' | ||||||
|
|
||||||
| # Setup Rust | ||||||
| - name: Setup Rust | ||||||
| - name: install Rust stable | ||||||
| uses: dtolnay/rust-toolchain@stable | ||||||
| with: | ||||||
| targets: ${{ matrix.os == 'macos' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} | ||||||
|
|
||||||
| # Cache Rust dependencies | ||||||
| - name: Cache Rust dependencies | ||||||
| uses: actions/cache@v5 | ||||||
| with: | ||||||
| path: | | ||||||
| ~/.cargo/bin/ | ||||||
| ~/.cargo/registry/index/ | ||||||
| ~/.cargo/registry/cache/ | ||||||
| ~/.cargo/git/db/ | ||||||
| src-tauri/target/ | ||||||
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | ||||||
| restore-keys: | | ||||||
| ${{ runner.os }}-cargo- | ||||||
|
|
||||||
| # Linux system deps | ||||||
| - name: Install Linux dependencies | ||||||
| if: matrix.os == 'linux' | ||||||
| run: | | ||||||
| sudo apt-get update | ||||||
| sudo apt-get install -y \ | ||||||
| libgtk-3-dev \ | ||||||
| libwebkit2gtk-4.1-dev \ | ||||||
| libappindicator3-dev \ | ||||||
| librsvg2-dev \ | ||||||
| patchelf \ | ||||||
| libssl-dev | ||||||
|
|
||||||
| # Windows long path fix | ||||||
| - name: Enable long paths (Windows) | ||||||
| if: matrix.os == 'windows' | ||||||
| run: git config --system core.longpaths true | ||||||
|
|
||||||
| # Build and upload release assets | ||||||
| - name: Build and upload release assets | ||||||
| uses: tauri-apps/tauri-action@v0 | ||||||
| env: | ||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
| with: | ||||||
| releaseId: ${{ github.event.release.id }} | ||||||
| args: ${{ matrix.os == 'macos' && '--target universal-apple-darwin' || '' }} | ||||||
| includeUpdaterJson: false | ||||||
| targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} | ||||||
|
|
||||||
| - name: Generate release checksums | ||||||
| run: node scripts/generate-release-checksums.mjs --root src-tauri/target/release/bundle --out checksums-${{ matrix.os }}.sha256 | ||||||
| - name: install frontend dependencies | ||||||
| run: npm ci | ||||||
|
|
||||||
| - name: Upload checksum file | ||||||
| uses: actions/upload-release-asset@v1 | ||||||
| - uses: tauri-apps/tauri-action@v0 | ||||||
| env: | ||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
| with: | ||||||
| upload_url: ${{ github.event.release.upload_url }} | ||||||
| asset_path: ./checksums-${{ matrix.os }}.sha256 | ||||||
| asset_name: checksums-${{ matrix.os }}.sha256 | ||||||
| asset_content_type: text/plain | ||||||
| tagName: app-v__VERSION__ | ||||||
| releaseName: 'Plum Notes v__VERSION__' | ||||||
|
||||||
| releaseName: 'Plum Notes v__VERSION__' | |
| releaseName: 'Pulm Notes v__VERSION__' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Plum Notes v0.1.0 🚀 | ||
|
|
||
| The inaugural release of Plum Notes—a blazing-fast, local-first second brain for developers and creators. | ||
|
|
||
| This v0.1.0 release establishes the complete core loop of the application: frictionless capture, instant retrieval, deep linking, and triage. | ||
|
|
||
| ## Highlights | ||
| * **Frictionless Quick Capture:** Hit `Cmd/Ctrl + Shift + Space` anywhere on your OS to summon a floating scratchpad. Sub-100ms time to write. | ||
| * **Bulletproof Local Storage:** Your data is yours. Everything is saved instantly to a local SQLite database via Tauri FS. Offline by default, private by design. | ||
| * **Command Palette:** Keyboard-first navigation (`Cmd+K`) powered by Ariakit, with deep fuzzy-search across all note contents and blocks. | ||
| * **Knowledge Graph & Backlinks:** Connect your thoughts using `[[wiki-style]]` linking. Visualize your second brain with an interactive, highly-optimized 2D force graph. | ||
| * **Inbox Triage:** Say goodbye to the black hole. Uncategorized captures land in a dedicated Inbox where you can Promote (`P`), Snooze (`S`), or Discard (`D`) using pure keyboard shortcuts. | ||
| * **Tagging & Filtering:** Inline `#tag` support in the editor with a multi-select AND-filter sidebar to instantly slice your library. | ||
|
|
||
| ## Installation | ||
| Download the appropriate binary for your system from the assets below: | ||
| * **macOS:** `.dmg` (Apple Silicon & Intel supported) | ||
| * **Windows:** `.msi` | ||
| * **Linux:** `.AppImage` or `.deb` |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,99 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'use client'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import React from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Note } from '@/app/types'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { FileText, Link as LinkIcon } from 'lucide-react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface BacklinksSidebarProps { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| notes: Note[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentNoteId: string | null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onSelectNote: (noteId: string) => void; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const BacklinksSidebar: React.FC<BacklinksSidebarProps> = ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| notes, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentNoteId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onSelectNote | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!currentNoteId) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const currentNote = notes.find(n => n.id === currentNoteId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!currentNote) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Find all notes that mention the current note | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const backlinks = notes.filter(note => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (note.id === currentNoteId || note.isDeleted) return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Search blocks for mentions of currentNoteId | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return note.blocks.some(block => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Check block mentions array if it exists | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (block.mentions && block.mentions.some(m => m.noteId === currentNoteId)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Fallback: check raw text content for the wiki-link pattern [[title]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (block.content && block.content.includes(`[[${currentNote.title}]]`)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Check list items | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (block.items) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return block.items.some(item => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (item.mentions && item.mentions.some(m => m.noteId === currentNoteId)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (item.content && item.content.includes(`[[${currentNote.title}]]`)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+27
to
+51
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Search blocks for mentions of currentNoteId | |
| return note.blocks.some(block => { | |
| // Check block mentions array if it exists | |
| if (block.mentions && block.mentions.some(m => m.noteId === currentNoteId)) { | |
| return true; | |
| } | |
| // Fallback: check raw text content for the wiki-link pattern [[title]] | |
| if (block.content && block.content.includes(`[[${currentNote.title}]]`)) { | |
| return true; | |
| } | |
| // Check list items | |
| if (block.items) { | |
| return block.items.some(item => { | |
| if (item.mentions && item.mentions.some(m => m.noteId === currentNoteId)) { | |
| return true; | |
| } | |
| if (item.content && item.content.includes(`[[${currentNote.title}]]`)) { | |
| return true; | |
| } | |
| return false; | |
| }); | |
| } | |
| // Search each block for mentions of currentNoteId | |
| return note.blocks.some(block => { | |
| // Check block mentions array if it exists | |
| if (block.mentions && block.mentions.some(m => m.noteId === currentNoteId)) { | |
| return true; | |
| } | |
| // Fallback: check raw text content for the wiki-link pattern [[title]] | |
| if (block.content && block.content.includes(`[[${currentNote.title}]]`)) { | |
| return true; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This workflow installs dependencies with
npm ci, butsrc-tauri/tauri.conf.jsonusesbeforeBuildCommand: "bun run build". Unless Bun is installed on the runner, the Tauri build step will fail when it executes that command. Either install Bun here (like the CI workflow does) or switch the TauribeforeBuildCommandto an npm-based command.