From f9a1d458bbde15b4c423d774af2d691765502d26 Mon Sep 17 00:00:00 2001 From: tmad4000 Date: Fri, 10 Jul 2026 12:22:55 -0700 Subject: [PATCH 1/3] fix: focus editor when creating a new page (rich mode) The per-tab showEditor override only focused the plain-mode textarea; in rich mode (the default) the underlying textarea is hidden inside the EasyMDE wrapper, so Cmd+N / welcome-screen New File / sidebar inline-create left keyboard focus outside the editor. Add focusActiveEditor() which focuses the CodeMirror instance in rich mode and the textarea in plain mode, call it from showEditor and the rich/plain toggle. Verified via CDP smoke: activeElement lands inside .CodeMirror after New File. Closes markdown-reader-zi2 Co-Authored-By: Claude Fable 5 --- .beads/issues.jsonl | 227 ++++++++++++++++++----------------- renderer.js | 21 +++- tests/new-file-focus.test.js | 43 +++++++ 3 files changed, 176 insertions(+), 115 deletions(-) create mode 100644 tests/new-file-focus.test.js diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 616f26d..da3eaf1 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,113 +1,114 @@ -{"id":"markdown-reader-09i","title":"Highlight active file in left sidebar when tab is focused","description":"When a tab is active and present in the sidebar tree, visually highlight the matching sidebar item.","notes":"Implemented sidebar active-file highlighting for tree/recent/timeline views using a shared path-matching helper; synced highlight on tab focus switches, folder expansion, and save-as path updates. Added node:test coverage in test/sidebar-highlight.test.js and verified with npm test.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:16.685966-08:00","updated_at":"2026-02-26T17:45:58.074643-08:00","closed_at":"2026-02-26T17:45:58.074643-08:00","close_reason":"Closed"} -{"id":"markdown-reader-0d4","title":"Add advanced global search controls (match case, regex, include/exclude, replace)","description":"Current global search supports plain text matches but lacks common VS Code controls. Add UX controls for match case, regex mode, include/exclude globs, and replace across results to reduce context switching to external editors.","acceptance_criteria":"1) Global search UI includes toggles for Match Case and Regex. 2) Include/Exclude pattern inputs are available and applied during search. 3) Results can be replaced per-match and per-file with undo confirmation. 4) Keyboard flow remains usable (Cmd+Shift+F opens, Enter/arrow navigation still works).","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:45:46.372172-08:00","updated_at":"2026-02-26T17:45:46.372172-08:00"} -{"id":"markdown-reader-0f9","title":"Audit app lag and spinning behavior","description":"Investigate current severe UI lag/spinning in OpenMarkdownReader. Check live process CPU/memory, logs, watch mode behavior, remote URL tabs, renderer/main hot paths, and patch any concrete regressions found.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-22T02:07:38.420954-07:00","updated_at":"2026-05-22T02:14:57.223016-07:00","closed_at":"2026-05-22T02:14:57.223016-07:00","close_reason":"Found root recursive scan loop from second-instance dot path resolving to /; patched argument resolution, broad-root scan guards, and hidden-sidebar watcher behavior."} -{"id":"markdown-reader-0gz","title":"Noos bot: post-restart task queue","description":"The Noos Slack bot (running as Claude Code CLI inside Docker on Lightsail) can now self-restart via exit(1). But it can't queue a follow-up command to run after restart. Implement a startup hook: before restarting, write a pending task to a file (e.g. /app/.pending-task.json), and on boot check for it and execute. This enables the bot to modify its own code, restart, and verify the change worked — all autonomously.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-03-17T06:11:51.676762-07:00","updated_at":"2026-03-17T06:13:36.681131-07:00","closed_at":"2026-03-17T06:13:36.681131-07:00","close_reason":"Created in wrong project, moving to noos"} -{"id":"markdown-reader-0ue","title":"Add spacing between sibling heading sections","description":"Consecutive h2 sections (like Topics, Organizations, People) appear cramped with insufficient vertical spacing between them. The CSS removes margin-top from headings inside .md-section containers but doesn't add spacing between sibling sections. Fix: Add margin-top to .md-section + .md-section selector to create proper breathing room between sections.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-13T04:00:01.496549-08:00","updated_at":"2026-01-13T04:21:11.402478-08:00","closed_at":"2026-01-13T04:21:11.402478-08:00","close_reason":"Added .md-section + .md-section { margin-top: 24px } for proper spacing"} -{"id":"markdown-reader-18u","title":"Quick Open URL support","description":"Support pasting URLs into the Quick Open (Cmd+P) palette to quickly open them in the default browser.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-23T14:13:49.880642-08:00","updated_at":"2026-01-23T20:55:36.080641-08:00","closed_at":"2026-01-23T20:55:36.080641-08:00","close_reason":"Closed"} -{"id":"markdown-reader-1i5","title":"Research Proof by Every as related project","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-27T18:41:00.463023-07:00","updated_at":"2026-05-27T18:43:51.125803-07:00","closed_at":"2026-05-27T18:43:51.125803-07:00","close_reason":"Added Proof research note, linked it from requirements/handoff docs, and updated web viewer ticket notes."} -{"id":"markdown-reader-1la","title":"Add Cmd+Alt+R accelerator to Restart menu item","description":"The Restart menu item (main.js:1006-1011) has no keyboard accelerator. Cmd+R is already taken (refresh current file, main.js:1095). Add Cmd+Alt+R as the Restart accelerator so dev iteration is keyboard-driven.\n\n**Why this priority**: trivial 1-line fix, immediate quality of life improvement for dev work.\n\n**Acceptance**: Cmd+Alt+R triggers the Restart menu item from anywhere in the app.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-07T04:56:31.006552-07:00","updated_at":"2026-04-07T04:57:55.508692-07:00","closed_at":"2026-04-07T04:57:55.508692-07:00","close_reason":"Implemented in working tree (not yet committed). Smart dev watcher: main.js:3332-3380. Restart accelerator: main.js:1006-1013. DEV badge tooltip: renderer.js:6421-6448. New IPC: preload.js, main.js reload-renderer handler. User to review + commit."} -{"id":"markdown-reader-1ui","title":"Quick access to reveal file in Finder / open containing folder","description":"## Implemented (2026-04-10)\nAdded three access points for revealing the active file's parent folder:\n\n1. **File menu**: File \u003e Reveal in Finder (⇧⌘R)\n2. **Command palette**: \"Reveal in Finder\" and \"Open Containing Folder\" commands (type \u003e to see commands)\n3. **Existing**: sidebar right-click already had \"Reveal in Finder\" and \"Open in Finder\"\n\n\"Reveal in Finder\" selects the file in its parent folder (shell.showItemInFolder).\n\"Open Containing Folder\" opens the parent directory directly (shell.openPath).\n\nKeyboard shortcut: ⇧⌘R (matches VS Code convention).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-10T04:12:50.1261-07:00","updated_at":"2026-04-10T04:12:56.045522-07:00","closed_at":"2026-04-10T04:12:56.045522-07:00","close_reason":"Implemented in commit 9ff7bd9"} -{"id":"markdown-reader-1wc","title":"Evaluate default auto-save and simplify top-bar toggle affordance","description":"Consider making auto-save easier to discover and enable from the top bar.\n\nContext:\n- The app already has an auto-save mode and an autosave indicator/button in the titlebar.\n- Current behavior may be too hidden or require menu hunting.\n- User request: consider making auto-save a more obvious, easy-to-enable option from the top bar, with the button state updating immediately and clearly.\n\nQuestions to resolve:\n- Should auto-save remain opt-in, or become default-on for files with a path?\n- If it stays opt-in, should the top-bar autosave control be more prominent or clearer about enabled/disabled state?\n- Should clicking the top-bar control both toggle auto-save and update nearby UI/state immediately without ambiguity?\n- How should untitled files behave when auto-save is enabled?\n- How does this interact with external file watching/conflict handling?\n\nAcceptance ideas:\n1. Auto-save can be enabled/disabled directly from an obvious top-bar control.\n2. The control's visual state always matches the actual setting after click/menu changes.\n3. If default-on is chosen, the app handles unsaved/untitled files and external-change conflicts clearly.\n4. Copy/tooltips make it obvious whether auto-save is on, off, or unavailable for the current tab.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-08T22:03:47.467912-07:00","updated_at":"2026-04-08T22:03:47.467912-07:00"} -{"id":"markdown-reader-2wa","title":"Refresh Cmd+P file cache when project files change externally","description":"Cmd+P uses allFilesCache, which is populated on folder open / first palette use. External filesystem changes detected by the sidebar live watcher do not refresh that cache, so newly-created files may not appear in command palette search until the folder is reopened or another cache reset path runs. Acceptance: when the project file signature changes, refresh allFilesCache, rebuild wikilinks, and update Cmd+P results if the palette is open.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-07T21:04:33.31771-07:00","updated_at":"2026-05-07T21:06:10.390763-07:00","closed_at":"2026-05-07T21:06:10.390763-07:00","close_reason":"Fixed: sidebar live refresh now refreshes allFilesCache from the recursive filesystem snapshot, rebuilds wikilinks, and updates Cmd+P results when open."} -{"id":"markdown-reader-2ww","title":"Detect and reconcile on-disk renames/moves","description":"If a file is renamed on disk outside the app, detect it and update open tabs/sidebar references without breaking state.","notes":"Implemented external rename/move reconciliation using inode-based detection in file watchers; emit file-path-changed and update renderer tab/sidebar references to prevent broken state. Added unit tests for rename and move detection in file-watch-utils.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T17:25:18.010882-08:00","updated_at":"2026-02-26T17:47:20.026131-08:00","closed_at":"2026-02-26T17:47:20.026131-08:00","close_reason":"Closed"} -{"id":"markdown-reader-2yb","title":"JSONL files always render in dark mode regardless of theme setting","description":"## Symptom\nOpening a .jsonl file in OpenMarkdownReader always displays with a dark background/theme, even when the app is set to light mode or system theme (and system is in light mode).\n\n## Likely causes\n- JSONL files hit the syntax-highlighted code path (via highlight.js) which may have its own theme stylesheet that doesn't respect the app's light/dark toggle\n- The app loads both `vendor/github.min.css` (light) and `vendor/github-dark.min.css` (dark) for highlight.js — the wrong one may be active for non-markdown files\n- JSON/JSONL content is likely wrapped in a `\u003cpre\u003e\u003ccode\u003e` block where the highlight.js theme overrides the app's CSS variables\n- The theme switching logic in renderer.js may only toggle markdown-related styles, not the highlight.js code theme\n\n## Investigation checklist\n- [ ] Open a .jsonl file in light mode, inspect the `\u003cpre\u003e\u003ccode\u003e` element — which highlight.js stylesheet is active?\n- [ ] Search renderer.js for theme switching logic — does it swap the highlight.js CSS file?\n- [ ] Check if .json files have the same issue (same rendering path)\n- [ ] Check styles.css for any `.hljs` overrides that force dark backgrounds\n\n## Fix (likely)\nSwap the highlight.js theme stylesheet when the app theme changes:\n- Light mode: load `vendor/github.min.css`\n- Dark mode: load `vendor/github-dark.min.css`\nOr use CSS variables to override `.hljs` background/foreground to match the app theme.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-09T13:11:03.80332-07:00","updated_at":"2026-04-10T01:39:46.268486-07:00","closed_at":"2026-04-10T01:39:46.268486-07:00","close_reason":"Fixed in commit 91a08be — replaced all hardcoded dark colors with CSS variables"} -{"id":"markdown-reader-32n","title":"Reveal folder in tree from recent view","description":"Clicking on a folder header in the 'Recent Changes' view should switch the sidebar back to the standard 'Tree View', expand the clicked folder, and scroll it into view.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-22T22:36:49.119345-08:00","updated_at":"2026-01-23T12:03:57.236258-08:00","closed_at":"2026-01-23T12:03:57.236258-08:00","close_reason":"Closed"} -{"id":"markdown-reader-39u","title":"Live filesystem watch for left sidebar","description":"Left sidebar should watch filesystem changes and refresh live for add/remove/rename/move events.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-02-26T17:25:17.010023-08:00","updated_at":"2026-02-26T20:15:07.429986-08:00","closed_at":"2026-02-26T20:15:07.429986-08:00","close_reason":"Added live sidebar filesystem refresh watcher that auto-reloads tree on external add/remove/rename changes."} -{"id":"markdown-reader-3oq","title":"Chat parsing for terminal view","description":"Layer on top of Terminal View:\n- Detect Human:/Assistant: patterns\n- Visual separation between conversation turns\n- Collapsible sections for tool calls\n- Works with pasted terminal output and structured JSONL","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-01-20T19:10:59.373727-08:00","updated_at":"2026-01-20T19:51:12.981134-08:00","closed_at":"2026-01-20T19:51:12.981134-08:00","close_reason":"Closed"} -{"id":"markdown-reader-40u","title":"Improve wiki link path resolution (support folder paths)","description":"Wiki links with folder paths aren't resolving correctly.\n\n**Example that failed:**\n[[topics/Sussman_s_paper_on_controlled_hallucinations|Sussman's paper on controlled hallucinations]]\n\n**Expected behavior:**\n- Support [[folder/filename|display]] syntax\n- Match by relative path from folder root\n- Fall back to filename-only match if path doesn't match\n\n**Also add:**\n- Hover on opened folder path shows full path\n- Right-click on folder path to copy path","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-15T00:41:48.983488-08:00","updated_at":"2026-01-15T00:46:58.608662-08:00","closed_at":"2026-01-15T00:46:58.608662-08:00","close_reason":"Closed"} -{"id":"markdown-reader-4go","title":"Right-click in content area shows tab context menu","description":"Right-clicking in the content area should show the same context menu as right-clicking the tab. This eliminates the need to find the active tab when you want to close, duplicate, rename, or perform other tab actions. The user is already focused on the content, so the context menu appears where their attention is. Simple and discoverable.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-13T04:00:03.366942-08:00","updated_at":"2026-01-13T04:12:37.52187-08:00","closed_at":"2026-01-13T04:12:37.52187-08:00","close_reason":"Implemented: right-click in markdown content area now shows tab context menu"} -{"id":"markdown-reader-4y1","title":"Auto-save new/untitled files to daily note or personal wiki folder","description":"## Goal\nWhen the user creates a new tab and starts typing (scratchpad use case), auto-save the content to a persistent location instead of losing it when the app closes. Makes OpenMarkdownReader useful as a quick-capture scratchpad with built-in persistence.\n\n## Proposed behavior\n- New untitled tabs auto-save to a configurable folder (default: the daily-notes folder if set, or ~/Documents/OpenMarkdownReader/)\n- Filename auto-generated: timestamp-based like `2026-04-09-scratch-1.md` or integrated into the daily note as an appended section\n- Setting: \"Auto-save new files\" (default: ON)\n- Setting: \"Auto-save location\" — choices:\n - **Daily note** (append to today's daily note file, e.g. ~/memory/daily/2026-04-09.md) — best for scratchpad/quick capture\n - **Wiki folder** (save as individual files in a configured folder) — best for growing a personal wiki\n - **Ask each time** (prompt for save location on first auto-save)\n\n## Why this matters\nJacob uses OpenMarkdownReader as a scratchpad — opens it, starts typing quick notes, then closes. Right now that content is lost if he forgets to Cmd+S and pick a location. With auto-save-to-daily-note, every scratchpad session automatically ends up in his daily note (~/memory/daily/) where it's searchable and persistent.\n\n## Integration with existing features\n- The app already has `config.dailyNotesFolder` and a daily-note command (`daily-note` agent command)\n- Auto-save can reuse the daily note path resolution logic\n- The existing auto-save feature (`config.autoSave`) saves edits to EXISTING files — this feature is about saving NEW/untitled files to a default location\n\n## Implementation sketch\n1. When a new tab is created and the user starts typing, start a debounced auto-save timer (e.g., 3 seconds after last keystroke)\n2. On first auto-save trigger:\n - If mode is \"daily note\": append content under a `## Scratch` or `## Notes` heading in today's daily note\n - If mode is \"wiki folder\": create a new file with timestamp name\n - If mode is \"ask\": show save dialog\n3. Subsequent edits in the same tab auto-save to the same location (like existing autoSave behavior)\n4. Tab title updates to reflect the saved filename once persisted\n\n## Edge cases\n- Multiple untitled tabs: each gets its own scratch entry or file\n- Daily note doesn't exist yet: create it with standard daily note template\n- App crashes before auto-save: accept data loss (same as any editor)\n- Large paste operations: don't auto-save mid-paste, wait for debounce\n\n## Settings UI\nAdd to Settings menu:\n- [x] Auto-save new files (checkbox, default ON)\n- Location: [Daily note | Wiki folder | Ask each time] (dropdown)\n- Wiki folder path: [...] (folder picker, only shown when \"Wiki folder\" selected)","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-10T01:39:45.99521-07:00","updated_at":"2026-04-10T01:39:45.99521-07:00"} -{"id":"markdown-reader-4yq","title":"Add document comments in view mode","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-26T19:13:48.994761-08:00","updated_at":"2026-04-02T23:48:06.622312-07:00","labels":["defer"]} -{"id":"markdown-reader-571","title":"Open folders on remote SSH hosts (SFTP-backed browsing/editing)","description":"## Goal\nLet the user open a folder on a remote machine they're already SSH-connected to (e.g. `hostmyapple`, `macincloud`, `noos-prod`) and browse/read markdown files as if it were a local folder.\n\n## Motivation\nJacob frequently SSHs into Mac mini (hostmyapple), Hetzner box (jcortex), and others — and often wants to read markdown notes or READMEs living on those boxes without scp'ing them down first.\n\n## Feasibility: Yes\nSeveral viable approaches, in order of preference:\n\n### Option A — SFTP via `ssh2-sftp-client` (RECOMMENDED)\n- npm: `ssh2-sftp-client` (wraps `ssh2`, pure JS with optional native crypto). Both are well-maintained.\n- Parses `~/.ssh/config` via `ssh-config` package → lets user pick an existing Host alias (`hostmyapple`, `jcortex`, etc.) instead of retyping creds.\n- Uses existing SSH keys — no password entry for key-based hosts.\n- New IPC surface in main.js: `remote-fs:connect`, `remote-fs:list`, `remote-fs:read`, `remote-fs:stat`, `remote-fs:write` (for edit mode).\n- File tree builds an in-memory `fileTree` just like local, but every node carries a `remoteId`.\n- Renderer treats remote paths as a new scheme, e.g. `sftp://hostmyapple/Users/Jacob/notes/foo.md`.\n- Cache small files locally (`~/Library/Application Support/OpenMarkdownReader/remote-cache/\u003chost\u003e/`) for offline re-open + diff.\n\n### Option B — sshfs/macFUSE mount\n- User mounts remote dir via macFUSE + sshfs; app just opens the mount point as a normal local folder.\n- Zero code in OpenMarkdownReader, but requires user to install macFUSE (kext/system extension, macOS is actively hostile to this).\n- Not a good default, but document as a workaround.\n\n### Option C — Remote agent (VS Code style)\n- Ship a tiny companion binary to the remote host, speak a custom protocol over SSH stdio.\n- Overkill for a markdown reader. Skip.\n\n## Proposed UX\n- **File → Open Remote Folder…** menu item (new)\n- Dialog shows hosts parsed from `~/.ssh/config`, plus a \"Custom…\" row\n- After picking host, prompt for path (or show remote home dir browser)\n- Opened remote folder appears in the sidebar with a small 🌐 or hostname badge\n- Titlebar shows `hostmyapple:~/notes` so it's always clear which machine you're reading from\n- Recent Remote Folders section in File menu (mirror of Recent Folders)\n\n## Edge cases to consider\n- **Edit mode + write-back**: save over SFTP, show spinner in tab, revert on failure\n- **Large folders**: lazy-load subtrees instead of walking entire tree (unlike local mode)\n- **File watching**: no easy SFTP notify; poll `mtime` on currently-open files every N seconds, or just refresh-on-focus\n- **Wiki links \u0026 cross-file navigation**: all resolves must stay within the same remote root\n- **Disconnects**: detect, show \"reconnect\" toast, queue writes or fail them\n- **MAS sandbox**: SFTP will likely NOT work under App Sandbox (outbound network + arbitrary file access). Feature should be gated to the non-MAS / \"Local-Only\" edition, OR make it Pro/non-MAS only. Coordinate with `markdown-reader-xwc` (Local-Only MAS edition).\n- **Security**: only read from `~/.ssh/config` + `~/.ssh/known_hosts`; never prompt for or store passwords in plaintext; rely on key agent (ssh-agent) where possible.\n\n## Out of scope for v1\n- Real-time collab on remote files\n- Remote terminal inside the app\n- Writing back to remote via git\n\n## Acceptance criteria\n1. \"File → Open Remote Folder…\" works against `hostmyapple`, showing markdown files in sidebar\n2. Clicking a file opens it read-only in a new tab with correct rendering (including wiki links and images, at least for those inside the same remote root)\n3. Edit mode saves back to the remote host and the tab's dirty indicator clears on success\n4. Disconnecting/reconnecting doesn't crash the renderer (see existing dead-renderer guards)\n5. Works against at least one non-Mac remote (Linux box like jcortex) to prove portability\n\n## Related\n- Blocks / interacts with: `markdown-reader-xwc` (Local-Only MAS edition) — remote support must live in the non-sandboxed build","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-08T21:46:39.141717-07:00","updated_at":"2026-04-08T21:46:39.141717-07:00","dependencies":[{"issue_id":"markdown-reader-571","depends_on_id":"markdown-reader-xwc","type":"blocks","created_at":"2026-04-08T21:46:48.839501-07:00","created_by":"daemon"}]} -{"id":"markdown-reader-5ac","title":"Show upload success message after publishing","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-14T09:50:45.322846-08:00","updated_at":"2026-01-14T09:57:16.855461-08:00","closed_at":"2026-01-14T09:57:16.855461-08:00","close_reason":"Implemented toast notifications for publish success/error"} -{"id":"markdown-reader-5n9","title":"Terminal display mode with optional chat parsing","description":"## Core Feature: Terminal View\nA display mode optimized for terminal/CLI content:\n- **Monospace font** throughout\n- **Dark background** (terminal aesthetic)\n- **Preserved whitespace** and formatting\n- **No markdown rendering** - shows content as-is\n\n## Use Cases\n- Saved terminal sessions\n- Log files\n- Build output\n- AI chat transcripts (Claude Code, etc.)\n- Any CLI output\n\n## View Menu\n```\nView\n├── ✓ Standard View\n├── Terminal View ⌘⇧T\n```\n\n## Optional Enhancement: Chat Parsing\nWhen enabled (or auto-detected), layer on:\n- Visual separation between Human/Assistant turns\n- Collapsible sections for tool calls\n- But the base terminal view works without any parsing\n\n## Technical Approach\n1. Add CSS class for terminal mode (monospace, dark bg, preserve whitespace)\n2. View menu toggle with keyboard shortcut\n3. (Later) Add heuristic chat parser as enhancement\n4. (Later) Add JSONL parser for Claude Code sessions","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-20T18:53:40.692354-08:00","updated_at":"2026-01-20T19:17:43.712765-08:00","closed_at":"2026-01-20T19:17:43.71277-08:00"} -{"id":"markdown-reader-6ct","title":"Global search within opened folder (VS Code style)","description":"Add a global search feature when a folder is opened, similar to VS Code's Cmd+Shift+F:\n\n**Core features:**\n- Search across all files in the opened folder\n- Show results grouped by file with line previews\n- Click result → open file and jump to that line\n- Highlight matches in the preview\n\n**UI options:**\n- Sidebar panel (like VS Code)\n- Or modal search overlay (like Cmd+P in VS Code)\n- Keyboard shortcut: Cmd+Shift+F\n\n**Search options (nice to have):**\n- Case sensitive toggle\n- Regex support\n- File type filters (*.md only, etc.)\n- Include/exclude patterns\n\n**Performance:**\n- Index files on folder open\n- Debounce search input\n- Virtual scroll for large result sets","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-15T00:11:58.734385-08:00","updated_at":"2026-01-15T00:23:09.859827-08:00","closed_at":"2026-01-15T00:23:09.859827-08:00","close_reason":"Implemented global search with Cmd+Shift+F: search across all files in folder, grouped results, keyboard navigation, match highlighting"} -{"id":"markdown-reader-6ln","title":"Add backlinks panel: show all files linking to the current file","description":"Obsidian-style backlinks. When viewing a markdown file, show a panel listing every other file in the current folder (or workspace) that links to it via wiki-link `[[name]]` or relative markdown link `[label](path/to/file.md)`.\n\n**Why:** Makes manifest files (like the new active-projects dashboard) two-way navigable. Today `active-projects.md` links to `sideboard/README.md`, but from inside the README there's no surfaced indication that the manifest references it. Backlinks close that loop and turn any markdown set into a navigable graph.\n\n**Scope (v1):**\n- Index links across the loaded folder/workspace (not just open tabs)\n- Resolve both `[[name]]` wiki-links and `[label](path)` markdown links to absolute paths\n- Show a collapsible 'Linked from' panel below the rendered content (or in the sidebar — UX TBD)\n- Click a backlink → opens the source file\n- Update incrementally as files change (watch mode already exists)\n- Handle the existing `Wiki link name conflicts detected` case\n\n**Out of scope (v1):**\n- Cross-folder/global index\n- Block-level / heading-level backlinks (Obsidian-style `#section`)\n- Unlinked mentions (text-match without an actual link)\n\n**First user:** the Active Projects Dashboard build (dashboard profile). Manifest → README is one-way today; backlinks make the dashboard appear in each project's README without anyone editing it.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-04T22:43:24.323427-07:00","updated_at":"2026-05-04T22:43:24.323427-07:00"} -{"id":"markdown-reader-6v2","title":"Review settings vs View menu placement for layout controls","description":"Audit whether content margin/layout controls belong in Settings or View menu; consolidate for clearer IA.","status":"open","priority":3,"issue_type":"task","created_at":"2026-02-26T17:25:18.608032-08:00","updated_at":"2026-02-26T17:25:18.608032-08:00"} -{"id":"markdown-reader-788","title":"Add dev mode restart button","description":"Add a feature to detect source code changes in dev mode and show a restart button in the titlebar.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-22T22:26:25.791567-08:00","updated_at":"2026-04-07T04:56:07.09016-07:00","closed_at":"2026-04-07T04:56:07.09016-07:00","close_reason":"Already fully implemented in code: file watcher (main.js:3332-3353), restart-app IPC (main.js:3355-3359), button HTML (index.html:38-43), pulsing styles (styles.css:656-696), DEV badge (index.html:37, renderer.js:6421-6428), source-code-changed handler with toast (renderer.js:1426-1436). Closing as done."} -{"id":"markdown-reader-7a5","title":"Update-available indicator when new GitHub release exists","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-30T04:58:58.971509-08:00","updated_at":"2026-01-30T05:06:19.880343-08:00","closed_at":"2026-01-30T05:06:19.880343-08:00","close_reason":"Closed"} -{"id":"markdown-reader-7f6","title":"Preserve scroll position when switching between edit and preview modes","description":"When switching from preview to edit mode (or vice versa), the view jumps to the top. Should preserve scroll position using percentage-based or content-matching approach.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-26T19:11:49.857569-08:00","updated_at":"2025-12-26T19:21:42.713484-08:00","closed_at":"2025-12-26T19:21:42.713484-08:00","close_reason":"Closed"} -{"id":"markdown-reader-7gp","title":"Drag and drop files into folders in left sidebar","description":"Enable drag-and-drop reorganization of files into folders in the left sidebar.","notes":"Implemented sidebar file-\u003efolder drag and drop with validated move-file-to-directory IPC, tree state sync, open-tab path updates, and new unit tests for file move safety + tree move behavior.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:17.51286-08:00","updated_at":"2026-02-26T20:15:07.09335-08:00","closed_at":"2026-02-26T20:15:07.09335-08:00","close_reason":"Implemented drag-and-drop move of files into folders in the sidebar tree with move validation."} -{"id":"markdown-reader-7lp","title":"Standardize rename UX and fix double-click rename bug","description":"Add right-click Rename in tab bar and left sidebar; make double-click rename reliable and consistent with VS Code behavior.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T17:25:17.677346-08:00","updated_at":"2026-02-26T20:15:07.239803-08:00","closed_at":"2026-02-26T20:15:07.239803-08:00","close_reason":"Standardized rename entry points by adding Rename actions in tab/sidebar context menus and wiring to rename flows."} -{"id":"markdown-reader-7ol","title":"Bug: updateCommandPaletteSelection is not defined when opening Cmd+P","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-03-11T03:39:53.296657-07:00","updated_at":"2026-03-11T03:43:42.470832-07:00","closed_at":"2026-03-11T03:43:42.470832-07:00","close_reason":"Closed"} -{"id":"markdown-reader-7qf","title":"Open folder as project: Cmd+P folder results + sidebar context menu","description":"Two related UX improvements for opening folders as the workspace root:\n\n1) **Cmd+P folder results** — When Cmd+P search matches a folder (not just a file), show the folder in results. Selecting a folder opens it as the active project/workspace root (same as File → Open Folder). Use a visual distinction (folder icon + 'Open folder' hint) so it's clear it's not a file.\n\n2) **Sidebar right-click → Open as project** — Right-clicking a folder in the left sidebar exposes actions to open that folder as its own workspace root. Options to consider:\n - 'Open Folder in New Window' (primary, VS Code-style, non-destructive — recommended default)\n - 'Open Folder Here' (replaces current workspace, with confirmation if there are unsaved tabs)\n - (Deferred) 'Add Folder to Workspace' — multi-root workspaces, larger refactor\n\n**Recommendation**: Ship 'Open in New Window' first as the safer/clearer option, matching VS Code. Skip multi-root workspaces for now — it's a significant refactor and most users get what they want from a new window.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T04:17:51.180246-07:00","updated_at":"2026-04-07T16:00:48.317934-07:00","closed_at":"2026-04-07T16:00:48.317934-07:00","close_reason":"Implemented both parts:\n1. Sidebar right-click → 'Open in New Window' menu item added to both folder context menus in main.js (show-folder-context-menu and show-sidebar-folder-item-context-menu).\n2. Cmd+P shows folders: getAllFilesRecursive now optionally includes directories (gated behind opts.includeDirs), and the renderer's get-all-files-recursive IPC handler enables it. Folder items in Cmd+P show a 'Folder' badge + 📂 icon and are routed to a new openFolderInNewWindow IPC method that calls createWindow(folderPath).\n3. Bonus: 'omr --cmd open /path --new-window' agent command flag for headless testing.\nVerified end-to-end: passing newWindow:true creates a second browser window with the folder as its sidebar root."} -{"id":"markdown-reader-8cy","title":"Fix widescreen space usage on globalbr.ai/files","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-14T09:03:20.991429-08:00","updated_at":"2026-01-14T09:03:27.626348-08:00","closed_at":"2026-01-14T09:03:27.626348-08:00","close_reason":"Wrong project - should be in noos"} -{"id":"markdown-reader-8en","title":"EasyMDE split mode: toolbar disappears and can't close split view","description":"When opening side-by-side split mode in EasyMDE rich editor, the toolbar disappears and there's no way to close the split view.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-26T19:19:42.041474-08:00","updated_at":"2025-12-26T19:35:20.681032-08:00","closed_at":"2025-12-26T19:35:20.681032-08:00","close_reason":"Closed"} -{"id":"markdown-reader-8ls","title":"Create new file directly inside selected folder from left sidebar","description":"Support creating a new file in the currently selected folder from left sidebar context.","notes":"Implemented selected-folder file creation from sidebar tree: right-click folder -\u003e New File Here, plus command palette path (Sidebar: New File in Selected Folder). Added selected folder state + nested temp file insertion/rename flow and case-insensitive collision utility tests.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:17.345994-08:00","updated_at":"2026-02-26T17:49:34.308053-08:00","closed_at":"2026-02-26T17:49:34.308053-08:00","close_reason":"Completed: create-new-file in selected sidebar folder with context menu + command path, collision validation coverage, and tests."} -{"id":"markdown-reader-8wt","title":"Default to edit mode when creating new file","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-28T00:51:33.564006-08:00","updated_at":"2026-01-17T04:48:04.496727-08:00","closed_at":"2026-01-17T04:48:04.496727-08:00","close_reason":"Implemented in this session"} -{"id":"markdown-reader-9a5","title":"Fix Command-Shift-S shortcut handling","description":"Cmd+Shift+S is currently not working; shortcut should trigger expected Save As / mapped action.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T17:25:18.262075-08:00","updated_at":"2026-02-26T20:15:06.521692-08:00","closed_at":"2026-02-26T20:15:06.521692-08:00","close_reason":"Restored Cmd+Shift+S handling via keyboard shortcut path to save-as flow."} -{"id":"markdown-reader-a4h","title":"Undo history is lost on mode toggle / tab switch / rich↔plain toggle","description":"**Problem**: Undo state is repeatedly wiped by normal UI actions. User types for 10 minutes, hits Escape to preview, goes back to edit → Cmd+Z does nothing.\n\n**Three places undo is lost** (found in renderer.js):\n\n1. **Edit → Preview → Edit (plain textarea mode)** — renderer.js:1212 'showEditor(content)' does 'editor.value = content' every time. Assigning .value to a textarea programmatically **resets the browser's native undo stack**. So any mode toggle clears undo.\n\n2. **Rich mode ↔ Plain mode toggle** — renderer.js:5597-5602 'destroyRichEditor()' calls 'easyMDE.toTextArea()', which tears down the entire CodeMirror instance. All undo history gone. The reverse direction pipes via 'easyMDE.value(editor.value)' (line 5611) which also starts a fresh history.\n\n3. **Tab switching** — likely same issue: returning to a tab re-runs 'showEditor(tab.content)' → textarea .value reassignment → undo wiped. Needs verification but the pattern is suspicious.\n\n**Why this matters now**: The proposed Escape-to-exit-edit-mode feature (markdown-reader-kq3) would make this 10x more frequent. Mis-tapping Escape shouldn't lose 20 minutes of undo.\n\n**Fix directions** (in order of effort):\n- **Cheap**: In plain mode, don't reassign 'editor.value' if the content hasn't actually changed from what the user last saved or what's currently in the textarea. Mode toggle becomes pure show/hide.\n- **Medium**: Persist **per-tab editor state** so that switching tabs (or modes) restores the textarea/CodeMirror instance rather than re-populating from content.\n- **Right answer**: One editor instance per tab, kept alive across mode/tab changes. Bigger refactor but it's the correct model — matches VS Code/Obsidian/any real editor.\n\n**Current escape hatch**: 'tab.originalContent' (renderer.js:1178) gives a 'revert all' via the Cancel button, but that's all-or-nothing — no granular undo.\n\n**Acceptance**: After typing, hitting Escape/preview toggle, switching tabs, or toggling rich/plain mode, Cmd+Z should still step back through all edits in the session.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-07T04:27:17.1708-07:00","updated_at":"2026-04-07T15:56:10.951225-07:00","closed_at":"2026-04-07T15:56:10.951225-07:00","close_reason":"Implemented per-tab editor refactor. Each tab now owns its own textarea (tab.editorEl) and EasyMDE instance (tab.easyMDE), both lazy-created and kept alive across tab switches and preview toggles. Verified end-to-end via the new _debug-editor-state agent command: setting distinct content in two tabs and switching between them preserves each tab's CodeMirror state independently. Preview-toggle round-trip also preserves the editor instance (no destroy/recreate). Within-tab rich/plain mode toggle still loses undo on the OLD mode — that's a separate, smaller concern documented in the new follow-up."} -{"id":"markdown-reader-a8y","title":"PDF export broken: only first page, sidebar visible","description":"PDF export has two issues in the current installed version: (1) Only the first page renders — multi-page documents are truncated. (2) The sidebar is visible in the PDF output. A previous fix (markdown-reader-f2q) addressed print stylesheet overrides but these issues persist in the installed app, suggesting the fix was either not included in the installed build or is insufficient. Needs investigation.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-01T21:06:58.552649-08:00","updated_at":"2026-03-02T17:22:41.234605-08:00","closed_at":"2026-03-02T17:22:41.234605-08:00","close_reason":"Fixed PDF export: Added comprehensive print CSS to hide sidebar and enable multi-page rendering"} -{"id":"markdown-reader-aad","title":"Prompt to become default handler for .md/.jsonl on first launch","description":"## Goal\nOn first launch (or when the app detects it's not the default handler), show a non-intrusive banner or dialog asking: \"Make OpenMarkdownReader your default app for Markdown files?\"\n\n## Current state (2026-04-09)\n- .md and .jsonl defaults set manually via `duti -s com.jacobcole.openmarkdownreader .md all`\n- .jsonl added to fileAssociations in package.json (will be in Info.plist after next build)\n- Stale \"OpenMarkdownReader 2.app\" (TestFlight wrapper) was poisoning LaunchServices; fixed by unregistering via lsregister\n\n## Implementation sketch\n1. On `app.whenReady()`, check if `app.isDefaultProtocolClient()` or equivalent for file types\n2. Electron doesn't have a built-in \"is default for file extension\" check, so use `duti -x md` or `LSCopyDefaultRoleHandlerForContentType` via native module\n3. If not default, show a subtle banner (not a modal) with \"Set as default\" / \"Not now\" / \"Don't ask again\"\n4. Store preference in config: `defaultHandlerPromptDismissed: true`\n5. Gate behind `!isMASBuild()` — MAS apps can't call `duti` or `lsregister`\n\n## File types to check\n- .md (primary)\n- .markdown, .mdown, .mkd (variants)\n- .jsonl (newly added)\n- NOT .json, .txt, .yaml — too aggressive, users likely want VS Code/other for those\n\n## UX reference\nSimilar to Chrome's \"Make Chrome your default browser?\" or VS Code's \"Make VS Code your default editor?\"\n\n## Out of scope\n- Auto-setting without asking (bad UX, user should consent)\n- Setting defaults for ALL registered file types (only markdown family + jsonl)","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-09T13:06:34.750491-07:00","updated_at":"2026-04-09T13:06:34.750491-07:00"} -{"id":"markdown-reader-av2","title":"Fix chat code fence rendering corruption","description":"Backticks inside fenced code blocks were being converted to inline code in chat view.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-07T19:52:23.61694-08:00","updated_at":"2026-04-07T15:12:26.164749-07:00","closed_at":"2026-04-07T15:12:26.164749-07:00","close_reason":"Already fixed in commit fcd87e9 (renderer.js:4146-4166). Fenced code blocks are protected via @@CHAT_CODE_BLOCK_N@@ placeholders before inline-code processing, then restored. Verified by reading the current code."} -{"id":"markdown-reader-av3","title":"Clarify sidebar sort mode/status in UI","description":"Make current sidebar sort mode obvious (label/tooltip/indicator) and improve legibility so users understand what ordering is active.","notes":"Implemented clear sidebar sort status with persistent label + indicator + tooltip. Added shared helper (sidebar-sort-indicator.js), wired renderer sort UI updates via updateSidebarSortUI(), updated sidebar header markup/styles for legible status pill, and added node tests in tests/sidebar-sort-indicator.test.js. Verified with npm test (all passing).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:16.847626-08:00","updated_at":"2026-02-26T17:45:53.028256-08:00","closed_at":"2026-02-26T17:45:53.028256-08:00","close_reason":"Implemented and tested sort mode status indicator UI"} -{"id":"markdown-reader-b28","title":"Wire up electron-updater for non-MAS DMG auto-updates","description":"## Goal\nWire up `electron-updater` for the **non-MAS** DMG distribution so Jacob and other direct-download users automatically get new releases without manually downloading DMGs or re-building from source.\n\n## Current state (verified 2026-04-08)\n- `package.json` has **no `build.publish`** config\n- **`electron-updater` is not a dependency**\n- `main.js` never imports `autoUpdater`\n- Result: v1.0.4 users who installed from GitHub are stuck on v1.0.4 forever unless they manually re-download\n\n## Why this matters\n- Currently my workflow to get the latest code running is \"build locally, ditto into /Applications\". That's fine for one user. Not fine for anyone else.\n- The Local-Only MAS edition (markdown-reader-xwc) and MAS Standard get updates via Apple automatically. The non-MAS build is currently the odd one out with *no* update path at all.\n- The non-MAS edition is strategically the most important one for power users (it's where SFTP, shell integration, and future power features will live — see markdown-reader-571). Power users especially need fast update cadence.\n\n## Implementation\n\n### 1. Add dependency\n```bash\nnpm install electron-updater\n```\n**Dep version policy**: per CLAUDE.md, use a version at least one month old. Check npm before installing.\n\n### 2. Configure publishing in `package.json`\n```json\n\"build\": {\n \"publish\": {\n \"provider\": \"github\",\n \"owner\": \"tmad4000\",\n \"repo\": \"OpenMarkdownReader\",\n \"releaseType\": \"release\"\n }\n}\n```\n\n### 3. Wire updater into `main.js`\nGate on non-MAS build using the existing `isMASBuild()` helper — MAS updates are handled by Apple and calling `autoUpdater` from a MAS build will crash or no-op ugly:\n\n```javascript\nconst { autoUpdater } = require('electron-updater');\n\napp.whenReady().then(() =\u003e {\n // ... existing ready logic ...\n if (!isMASBuild()) {\n autoUpdater.checkForUpdatesAndNotify().catch(err =\u003e {\n console.warn('[auto-update] check failed:', err.message);\n });\n // Re-check every 6 hours for long-running instances\n setInterval(() =\u003e {\n autoUpdater.checkForUpdatesAndNotify().catch(() =\u003e {});\n }, 6 * 60 * 60 * 1000);\n }\n});\n```\n\n### 4. UI: \"Update available\" indicator\nPer global CLAUDE.md guidance (\"Always show when a new version is available\"), add a subtle indicator in the user menu / footer:\n- Listen for `autoUpdater.on('update-available', ...)` → set a flag in main, forward to renderer via IPC\n- Renderer shows a small dot next to the version number (already displayed per CLAUDE.md \"Version Display in User Menus\" rule)\n- Clicking the dot opens a \"Restart to update\" dialog backed by `autoUpdater.quitAndInstall()`\n- Listen for `autoUpdater.on('update-downloaded', ...)` → enable the restart option\n\n### 5. Release workflow change\n- electron-builder needs to publish `latest-mac.yml` alongside the DMG/zip in every GitHub release or the updater has nothing to check against\n- Change release command from `gh release upload` → `electron-builder --mac --publish always`\n- This requires `GH_TOKEN` env var in the shell doing the release (from 1Password or gh auth)\n- Update `CLAUDE.md` \"Releasing\" section with the new command\n\n### 6. Signing requirement\n- electron-updater on macOS **requires** signed + notarized builds to apply updates (unsigned apps get \"update failed: code signature\" errors)\n- This means going back to the notarized build flow (`APPLE_API_KEY` env vars) for every release — no more skip-notarize shortcuts for public releases\n- Local dev installs can still skip notarization since they bypass the updater\n\n## Acceptance criteria\n1. Fresh v1.0.N install from GitHub DMG auto-detects and installs v1.0.N+1 without manual intervention\n2. User sees \"Update available\" indicator before restart, not just a silent swap\n3. MAS builds don't crash or get confused — `isMASBuild()` gate prevents any updater code from firing\n4. Release script documented in CLAUDE.md and produces the `latest-mac.yml` file in the GitHub release\n5. `autoUpdater` errors don't break app startup (wrapped in try/catch, logged not thrown)\n\n## Edge cases\n- **First run after install**: avoid checking for updates immediately on first launch — wait a few minutes so the UI loads first\n- **Offline / no network**: updater should silently fail and not bother the user\n- **Code signing identity rotates**: the new build must be signed with the *same* identity or the updater refuses. Document this.\n- **Differential updates**: electron-updater supports delta patches but requires the previous build's signature. First few updates will be full downloads.\n\n## Out of scope\n- In-app update notes / changelog display (can be added later)\n- Nightly / pre-release channel (the alpha group on TestFlight covers pre-release testers for now)\n\n## Related\n- Discovered during 2026-04-08 session after manually installing v1.0.4 DMG and realizing there's no update path","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-08T22:33:13.422412-07:00","updated_at":"2026-04-08T22:33:13.422412-07:00"} -{"id":"markdown-reader-b79","title":"Markdown diff and track-changes mode for writing","description":"Add a writing workflow with diffs/track changes similar to editor review flows (VS Code-style compare/inline change visibility).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-02-26T17:25:17.18097-08:00","updated_at":"2026-02-26T17:25:17.18097-08:00"} -{"id":"markdown-reader-b90","title":"Fix Command-F input losing focus after first character","description":"Find box/search input currently drops focus after typing one character.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T17:25:18.778108-08:00","updated_at":"2026-02-26T20:15:06.21325-08:00","closed_at":"2026-02-26T20:15:06.21325-08:00","close_reason":"Fixed find bar focus loss by preserving input focus during live match updates in editor search flow."} -{"id":"markdown-reader-br6","title":"Research UX gaps vs VS Code and propose parity roadmap","description":"Audit markdown-reader against standard VS Code behaviors (navigation, sidebar, tabs, search, rename/move, context menus, split editors, update flow). Deliver prioritized gaps with concrete acceptance criteria and map to existing/new bd tickets.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-26T17:42:07.357858-08:00","updated_at":"2026-02-26T20:15:06.801566-08:00","closed_at":"2026-02-26T20:15:06.801566-08:00","close_reason":"Added VS Code parity gap analysis and research notes with prioritized mapping to tickets."} -{"id":"markdown-reader-c45","title":"Watch remote URL tabs for changes","description":"Remote URL tabs opened via Cmd+P are currently one-time snapshots. Add watch-mode support for remote URL sources by polling while listening mode is enabled, using ETag/Last-Modified when available and falling back to content hashing. Refresh the tab when the remote content changes, preserving local unsaved edits/conflict behavior.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T01:58:43.959989-07:00","updated_at":"2026-05-22T01:58:43.959989-07:00"} -{"id":"markdown-reader-cz3","title":"Fix publish error - handle 'File storage not configured' gracefully with helpful link","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-30T04:59:00.55877-08:00","updated_at":"2026-01-30T05:06:19.884538-08:00","closed_at":"2026-01-30T05:06:19.884538-08:00","close_reason":"Closed"} -{"id":"markdown-reader-d12","title":"Support tilde (~) expansion in Cmd+P open paths","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-23T12:32:13.165148-10:00","updated_at":"2026-04-07T15:11:52.376723-07:00","closed_at":"2026-04-07T15:11:52.376723-07:00","close_reason":"Fixed: open-file-by-path IPC handler now expands ~/path to home directory. Single change in main.js handles all 18 callers (Cmd+P, sidebar, recent files, wikilinks, etc.)."} -{"id":"markdown-reader-d37","title":"Make content margins fully adjustable with wider max option","description":"Current margin settings are limited. Want:\n1. Fully adjustable/customizable margins (slider or input)\n2. Make 'Spacious' (widest) setting even wider - less margin, more content width\n3. Possibly add preset options: Compact, Normal, Spacious, Full-width","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-14T15:04:55.307941-08:00","updated_at":"2026-01-17T04:48:04.510781-08:00","closed_at":"2026-01-17T04:48:04.510781-08:00","close_reason":"Implemented in this session"} -{"id":"markdown-reader-ds7","title":"Open in Finder action for files/folders across app","description":"Provide Open in Finder from left sidebar, tab bar, and other relevant file context menus.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:17.838022-08:00","updated_at":"2026-02-26T20:15:06.933628-08:00","closed_at":"2026-02-26T20:15:06.933628-08:00","close_reason":"Added Open in Finder/Revel in Finder actions across tab, sidebar file/folder, and folder-path context menus."} -{"id":"markdown-reader-dvb","title":"Resizable left sidebar via drag handle","description":"Allow the left sidebar width to be expanded/collapsed by dragging, similar to standard editors.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:16.352815-08:00","updated_at":"2026-02-26T20:15:07.570778-08:00","closed_at":"2026-02-26T20:15:07.570778-08:00","close_reason":"Implemented draggable sidebar resizer with constrained width and session persistence."} -{"id":"markdown-reader-e7r","title":"Far-future: Real-time collaborative editing via Yjs + Milkdown","description":"**Not urgent — parking ticket** to preserve the decision context from the 2026-04-02 session.\n\n**Goal**: Eventually support real-time collaborative editing on markdown files (multiple users editing the same doc with live cursors and awareness).\n\n**Approach**:\n- Milkdown (ProseMirror-based) already has @milkdown/plugin-collab which wraps Yjs + y-prosemirror — the same stack Tiptap uses. Adding Milkdown as the editor (markdown-reader-r1r) is the enabling move; collab is a plugin on top.\n- Tiptap has a more mature commercial collab story (Tiptap Cloud), but we're choosing Milkdown for other reasons. Collab capability on Milkdown is fine — just less polish on the DX.\n- Yjs is the CRDT library. Transport options: y-websocket (self-hosted, simple), y-webrtc (P2P, NAT pain), y-indexeddb (local persistence).\n\n**Hard problems to solve before shipping collab**:\n1. **Backend/transport**: where does the Yjs server live? Self-host a tiny y-websocket server? Piggyback on noos / IdeaFlow backend? This decision is upstream of everything.\n2. **On-disk reconciliation**: OpenMarkdownReader is a file-based editor. If someone else edits the .md file on disk while a collab session is live, we have a classic local-first conflict problem. Need a merge strategy.\n3. **Markdown round-tripping under collab**: Yjs operates on the ProseMirror document tree, not the Markdown string. Serialization to .md happens at save time. Two users with slightly different serialization preferences (e.g. ATX vs setext headings) could produce diff noise.\n4. **Auth / identity / presence**: who is the other user? Needs some notion of identity.\n5. **Why this matters for the product**: collab is probably the natural meeting point between OpenMarkdownReader and noos / IdeaFlow / Thoughtstream. Revisit when those products' roadmaps are clearer.\n\n**Prerequisites**:\n- markdown-reader-r1r (Milkdown editor) must ship first.\n\n**Do not work on this without explicit user green-light.** It's here to preserve context, not as a signal to build.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-07T04:36:07.138876-07:00","updated_at":"2026-04-07T04:36:07.138876-07:00","dependencies":[{"issue_id":"markdown-reader-e7r","depends_on_id":"markdown-reader-r1r","type":"blocks","created_at":"2026-04-07T04:36:09.656187-07:00","created_by":"daemon"}]} -{"id":"markdown-reader-f2q","title":"Print/PDF export should render only document content","description":"PDF export and print include full app chrome (title bar/sidebar/overlays) and card width styling. Restrict print output to page content area with print-specific layout rules.","notes":"Implemented print stylesheet overrides to hide app UI and normalize document width in printed/PDF output.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-02-26T20:36:18.692331-08:00","updated_at":"2026-02-26T20:44:01.802613-08:00","closed_at":"2026-02-26T20:44:01.802613-08:00","close_reason":"Added print handling for EasyMDE UI/split preview and improved page-break behavior for headings/tables/code blocks.","comments":[{"id":2,"issue_id":"markdown-reader-f2q","author":"jacobcole","text":"Adding additional rich-editor print cleanup and pagination refinements","created_at":"2026-02-27T04:43:58Z"}]} -{"id":"markdown-reader-f9j","title":"Add more App Store screenshots","description":"Consider adding additional screenshots to the Mac App Store listing. Current: 1 screenshot (1440x900 dark mode with features list). Could add: light mode, editing view, multiple tabs, file browser sidebar.","status":"open","priority":3,"issue_type":"task","created_at":"2026-01-28T02:50:23.475556-08:00","updated_at":"2026-01-28T02:50:23.475556-08:00"} -{"id":"markdown-reader-fc1","title":"Command-F search not working in edit mode","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-26T19:13:52.18588-08:00","updated_at":"2025-12-26T19:19:30.090565-08:00","closed_at":"2025-12-26T19:19:30.090565-08:00","close_reason":"Closed"} -{"id":"markdown-reader-fgg","title":"DEV badge tooltip: show git hash + build date + version","description":"The DEV badge (index.html:37, renderer.js:6421-6428) is visible in dev mode but has no tooltip. We already have getBuildInfo() returning version, buildNumber, gitHash, buildDate. Surface this in the badge title attribute so hovering reveals exactly what's running.\n\n**Format**: 'DEV build • v1.0.x (build N) • abc1234 • 2026-04-07 14:30'\n\n**Bonus**: also use this for the dev-restart-btn tooltip when it's visible (currently says 'Source code changed. Click to restart.').","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-07T04:56:27.7762-07:00","updated_at":"2026-04-07T04:57:55.50769-07:00","closed_at":"2026-04-07T04:57:55.50769-07:00","close_reason":"Implemented in working tree (not yet committed). Smart dev watcher: main.js:3332-3380. Restart accelerator: main.js:1006-1013. DEV badge tooltip: renderer.js:6421-6448. New IPC: preload.js, main.js reload-renderer handler. User to review + commit."} -{"id":"markdown-reader-g8f","title":"Auto-increment build number on every build","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-30T04:58:57.402922-08:00","updated_at":"2026-01-30T05:06:19.87447-08:00","closed_at":"2026-01-30T05:06:19.87447-08:00","close_reason":"Closed"} -{"id":"markdown-reader-g9e","title":"Create product homepage highlighting OpenMarkdownReader differentiators","description":"Build a homepage / landing page for OpenMarkdownReader that explains why someone should use it instead of other markdown apps.\n\nKey differentiators to cover:\n- Open arbitrary markdown/text files directly, not just a managed vault\n- Strong local-first workflow\n- Auto-save / low-friction editing\n- Fast preview + editor workflow\n- Obsidian compatibility where relevant (for example wikilinks), without requiring an Obsidian-only workflow\n- Other differentiators discovered in the app during implementation should be surfaced too\n\nPossible scope:\n- A simple static marketing page in-repo is fine for v1\n- Should be easy to host later\n- Should include clear headline, supporting sections, screenshots/placeholders if available, and a concise feature comparison / positioning angle\n\nAcceptance ideas:\n1. A homepage exists in the repo with a clear entrypoint.\n2. Messaging explains the product in plain language and names the key differentiators above.\n3. The page works on desktop and mobile.\n4. The implementation path is documented enough that it can be hosted/deployed later.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-08T22:04:23.405224-07:00","updated_at":"2026-04-08T22:12:21.187268-07:00","closed_at":"2026-04-08T22:12:21.187268-07:00","close_reason":"Implemented a standalone static homepage under `site/` with clear product positioning, plus alternative concepts under `site/alternatives/claude/` and `site/alternatives/nash/`. Messaging covers arbitrary file support, local-first workflow, low-friction editing/auto-save, fast preview/edit flow, and Obsidian compatibility without vault lock-in."} -{"id":"markdown-reader-hjc","title":"More aggressive, visible build number — increment per build, surface in version label","description":"**Problem**: Two builds of the same commit get the SAME build number, because scripts/generate-build-info.js currently sets buildNumber = 'git rev-list --count HEAD' (commit count, not build count). Worse, the build number is hidden inside the About dialog — the user-facing version label just says 'v1.0.4', so the user can't tell at a glance whether they're running an old install vs a fresh build. This bit us today: an install from Dec 26 2025 and a working-tree-with-uncommitted-fix both display as v1.0.4.\n\n**Goal**:\n1. **Per-build increment** — every invocation of generate-build-info.js bumps the build number, even on the same commit. Current 'git rev-list --count HEAD' approach is too coarse.\n2. **Visible in the version label**, not just the About modal. Render as something like 'v1.0.4.128' or 'v1.0.4 (b128)' wherever the version is shown to the user (status bar, window title, sidebar footer, tab tooltips).\n3. **Git hash stays** but as secondary info — the build number is the primary 'are you on the latest?' signal.\n\n**Implementation options for the increment**:\n- **A. Persistent counter in build-info.json**: read existing buildNumber, increment by 1, write back. Simple, monotonic. Risk: counter file conflicts in CI / multiple machines. Mitigation: store on a server-side gitignored file or accept per-machine drift.\n- **B. Epoch seconds since v1.0.0 release**: like the MAS build does (date +%s). Always unique, always increasing, machine-independent. Less human-friendly (huge numbers).\n- **C. Combined**: 'gitCount + .build N' where N is per-machine, e.g., '128.7' meaning 'commit 128, 7th local build of that commit'.\n\n**Recommendation**: Option A for the local file, Option B for MAS (already done). Track the counter in build-info.json and gitignore it.\n\n**Display format**: Render as 'v1.0.4.128' in user-visible labels (status bar, sidebar footer, tab tooltips). Apple constraint: CFBundleVersion is capped at 3 dot-separated integers, so we keep package.json version at '1.0.4' but the display in the JS UI can include the build number as a 4th segment. CFBundleVersion in Info.plist can be set to the build number itself for MAS uniqueness (which is already done).\n\n**Where to surface the new label**:\n- Window title (e.g. 'OpenMarkdownReader v1.0.4.128')\n- Status bar (already shows nothing? check)\n- Sidebar footer (per CLAUDE.md guidance)\n- About dialog (already shows it inside)\n\n**Related**: \n- Closed ticket markdown-reader-g8f covers 'auto-increment build number' but it's clearly insufficient for this use case\n- markdown-reader-7a5 (closed) is the 'update available' indicator — both should agree on what 'latest version' means\n- markdown-reader-jbx (closed) is the manual update check menu\n\n**Acceptance**:\n1. Two consecutive 'npm run build:mac' commands on the same commit produce two different build numbers\n2. The version label visible to the user without opening About includes the build number\n3. Easy to compare two installs at a glance ('I'm on .128, you're on .131')","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T05:57:42.21518-07:00","updated_at":"2026-04-07T15:15:32.280718-07:00","closed_at":"2026-04-07T15:15:32.280718-07:00","close_reason":"Implemented Option A from ticket: scripts/generate-build-info.js now reads previous buildNumber from build-info.json and uses max(gitCount, previous+1), so each invocation strictly increments. Also made the dev-badge in the titlebar visible on packaged builds (subtle gray pill showing 'b\u003cn\u003e'), giving every install a glance-able build number without opening About. Verified: two consecutive runs produced 130 → 131 on the same commit."} -{"id":"markdown-reader-hm9","title":"kljlj","status":"tombstone","priority":2,"issue_type":"task","created_at":"2026-01-15T00:21:30.200665-08:00","updated_at":"2026-04-07T05:54:28.068421-07:00","deleted_at":"2026-04-07T05:54:28.068421-07:00","deleted_by":"daemon","delete_reason":"delete","original_type":"task"} -{"id":"markdown-reader-huu","title":"Unify content width and margins into single custom setting","description":"## Current State\n- Content Width: presets only (700, 900, 1100, 1300, 1500, 1800, full)\n- Content Margins: presets only (8, 16, 20, 28, 40px padding)\n- No way to set arbitrary values\n\n## Proposed\nConsider unifying into a single 'Content Width' setting that:\n- Allows arbitrary pixel values (input field or slider)\n- Or maybe just add 'Custom...' option that opens input dialog\n- The margin/padding setting may be redundant if width handles it\n\n## Questions\n- Should margins be separate from width?\n- What's the UX for custom values? Submenu with input? Separate dialog?","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-20T19:11:04.178847-08:00","updated_at":"2026-01-20T19:51:13.0106-08:00","closed_at":"2026-01-20T19:51:13.0106-08:00","close_reason":"Closed"} -{"id":"markdown-reader-i20","title":"Fix back button navigation to previous tab/history item","description":"Back button should navigate to previous tab/history entry reliably; currently not working as expected.","notes":"Reproduced regression by tracing tab switch flow: renderer.js has two switchToTab implementations, and the later EasyMDE override (active at runtime) did not call pushNavHistory(). As a result, tab switches stopped recording history, so Back could not navigate to prior tab/history entries. Fixed by restoring pushNavHistory(tabId, tab.filePath) in the EasyMDE switchToTab override before updateTabUI(). Targeted validation: rg confirmed pushNavHistory present in both switchToTab paths; node --check renderer.js passed.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T17:25:18.954308-08:00","updated_at":"2026-02-26T20:15:06.380867-08:00","closed_at":"2026-02-26T20:15:06.380867-08:00","close_reason":"Fixed back/forward reliability by ensuring tab switches push consistent navigation history entries."} -{"id":"markdown-reader-ie3","title":"Wikilink [[...]] not resolving even with project folder open","description":"**Reproduction**: File /Users/jacobcole/Documents/Main/2023-08-23.md contains [[Todos before BM]]. Project directory is open but the wikilink renders as raw [[...]] text even though a file named `Todos before BM.md` exists.\n\n**Earlier (incorrect) suspicion — RETRACTED**: Case sensitivity is NOT the issue. renderer.js already lowercases both sides of the lookup: index keys at lines 239, 242, and the lookup name at line 274. Ruled out on re-read.\n\n**Real root causes** (three bugs, all must be fixed):\n\n1. **Missing index rebuild on 3 of 5 cache-write sites.** `buildWikiLinkIndex()` was only called at the openDirectory prefetch (renderer.js:1753) and refreshSidebarForExternalMove (renderer.js:3305). These 3 other sites populated `allFilesCache` WITHOUT rebuilding the index:\n - renderer.js:1844 — renderRecentFilesTree fallback fetch\n - renderer.js:1975 — renderRecentFilesTimeline fallback fetch\n - renderer.js:4490 — showCommandPalette fallback fetch\n\n2. **Race condition on the happy path.** In openDirectory, the prefetch at renderer.js:1749 is async, but renderMarkdown → processWikiLinks (renderer.js:3913) is synchronous. If a tab was already open when the folder opened, the file rendered before the index existed, so `processWikiLinks` bailed out at the `size === 0` guard (renderer.js:264/291) and left the `[[...]]` verbatim in innerHTML.\n\n3. **No re-render after index builds.** Once `processWikiLinks` emitted the raw `[[...]]` into markdownBody.innerHTML, nothing invalidated that state when the index later finished loading.\n\n**Fix applied** (renderer.js):\n- Added a `setAllFilesCache(files)` helper (~line 261) that assigns the cache, calls `buildWikiLinkIndex()`, AND re-renders the active tab via `renderContent(tab.content, tab.fileName)` if it's a non-editing preview with visible markdownBody. This closes bugs #2 and #3 together.\n- Replaced all 5 happy-path `allFilesCache = files` assignments with `setAllFilesCache(files)`:\n - renderer.js:1781 (openDirectory prefetch .then)\n - renderer.js:1872 (renderRecentFilesTree fallback)\n - renderer.js:2003 (renderRecentFilesTimeline fallback)\n - renderer.js:3332 (refreshSidebarForExternalMove)\n - renderer.js:4517 (showCommandPalette fallback)\n- Removed the now-redundant explicit `buildWikiLinkIndex()` calls (old lines 1753, 3305).\n- Left reset/error paths alone (`allFilesCache = null` / `= []`) — those shouldn't trigger a rebuild.\n\n**Status**: Code change complete, `node --check renderer.js` passes. Ready to verify in app.\n\n**Acceptance**: Opening a folder with a tab already showing [[Todos before BM]] resolves the link to the matching file on first visible paint.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-07T04:23:38.956517-07:00","updated_at":"2026-04-07T15:11:08.994473-07:00","closed_at":"2026-04-07T15:11:08.994473-07:00","close_reason":"Already fixed in commit fbed0e8 (wikilink resolver via setAllFilesCache helper). Verified in renderer.js — all 5 cache assignment sites now call setAllFilesCache which builds the index AND re-renders the active tab."} -{"id":"markdown-reader-il6","title":"Agent-native control: Unix socket + CLI commands for full programmatic control","status":"in_progress","priority":1,"issue_type":"epic","created_at":"2026-04-02T23:47:59.978654-07:00","updated_at":"2026-04-03T00:39:08.838316-07:00"} -{"id":"markdown-reader-iqz","title":"Within-tab rich/plain toggle still loses undo on old mode","description":"Phase 2 follow-up to markdown-reader-a4h. Tab switches and preview toggles now preserve undo (per-tab editorEl + easyMDE kept alive), but toggling rich↔plain WITHIN a single tab still loses the OLD mode's undo history because:\n\n- enterRichMode() may call easyMDE.value(textarea.value) to sync, which triggers CM setValue and clears CM history\n- leaveRichMode() syncs textarea.value = easyMDE.value(), which resets the textarea's native undo stack\n\nTo preserve both stacks across in-tab toggles, we'd need to either (a) re-parent the textarea between the EasyMDEContainer and the bare host without triggering value reassignments, or (b) keep both editors visible/positioned but only one focused and accept duplicate state.\n\nLower priority than markdown-reader-a4h was — most users switch tabs, fewer toggle modes within a tab. Revisit only if anyone complains.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-04-07T15:56:25.048129-07:00","updated_at":"2026-04-07T15:56:25.048129-07:00"} -{"id":"markdown-reader-j1s","title":"Visually indicate empty folders in sidebar file tree","description":"Sidebar folders currently give no indication that they're empty until you click to expand, at which point nothing appears. Adds dimmed chevron + folder icon + muted label for folders containing no visible (non-dotfile) entries. Uses an isEmpty flag populated server-side by a cheap opendirSync-based check. State is re-synced on expansion to catch external filesystem changes.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-16T00:31:54.983312-07:00","updated_at":"2026-04-16T00:32:02.405718-07:00","closed_at":"2026-04-16T00:32:02.405718-07:00","close_reason":"Dimmed chevron/icon/label on empty folders; isEmpty populated server-side by cheap opendirSync check and re-synced on expand to catch external filesystem changes."} -{"id":"markdown-reader-j45","title":"Show full path tooltip for tabs and left sidebar items","description":"Hovering a file item in top tab bar or left sidebar should show full path tooltip.","notes":"Verified full-path tooltips on top tabs and left sidebar file items (tree/recent/timeline). Added tab-title tooltip propagation and ensured sidebar file elements expose full path via title attribute.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:16.521035-08:00","updated_at":"2026-02-26T17:48:08.153333-08:00","closed_at":"2026-02-26T17:48:08.153333-08:00","close_reason":"Closed"} -{"id":"markdown-reader-jbx","title":"Menu item for update status and manual check/apply update","description":"Add explicit update status and update action in the app menu, complementing passive update indicator.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:18.441476-08:00","updated_at":"2026-02-26T20:15:07.700868-08:00","closed_at":"2026-02-26T20:15:07.700868-08:00","close_reason":"Added update status indicator and manual Check for Updates action in app menu with available/download state."} -{"id":"markdown-reader-jd4","title":"Add scroll wheel navigation for tabs","description":"Allow two-finger scroll (trackpad) or scroll wheel to navigate through tabs in the tab bar. Idiomatic approach: Listen for wheel events on .tab-bar and scroll horizontally when tabs overflow. This matches behavior in Chrome, VS Code, and other macOS apps with tab bars.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-13T04:00:02.355809-08:00","updated_at":"2026-01-13T04:23:12.453178-08:00","closed_at":"2026-01-13T04:23:12.453178-08:00","close_reason":"Added wheel event listener to convert vertical scroll to horizontal tab bar scroll"} -{"id":"markdown-reader-jyh","title":"Open remote files and folders over SFTP","description":"Add a real remote filesystem backend for SSH-accessible machines. Support sftp://host/path/file.md and remote folders using hosts from ~/.ssh/config where possible, remote stat/read/list/write operations, sidebar browsing, and polling-based watch support for opened remote files. This builds on markdown-reader-571 and should keep MAS/local-only constraints in mind.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T01:58:43.959173-07:00","updated_at":"2026-05-22T01:58:43.959173-07:00"} -{"id":"markdown-reader-k8x","title":"Timeline view for recent changes","description":"Add a new view mode to the 'Recent Changes' feature that groups modified files by date (Today, Yesterday, Previous 7 Days) and then by parent folder. This provides a timeline-based perspective on work.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-22T22:36:43.710863-08:00","updated_at":"2026-01-22T22:53:49.399865-08:00","closed_at":"2026-01-22T22:53:49.399865-08:00","close_reason":"Closed"} -{"id":"markdown-reader-kfr","title":"Resolve TestFlight external review rejection for v1.0.4 build 1773489007","description":"**Status**: Both recent MAS builds were rejected for external TestFlight testing:\n- Build 1773489007 (v1.0.4) uploaded 2026-03-14, rejected 2026-03-17\n- Build 1773226755 (v1.0.4) uploaded 2026-03-11, rejected 2026-03-13\n\nInternal TestFlight works fine (IN_BETA_TESTING on the 'alpha' group). Only external review failed.\n\n**Rejection reason is NOT in the rejection emails** — Apple only puts it in the Resolution Center on App Store Connect. Emails just say 'visit the App Review page'. The API also doesn't expose the rejection text.\n\n**Action required from Jacob**: Open https://appstoreconnect.apple.com/apps/6758376669/testflight/ios, click the rejected build, read the App Review message in the Resolution Center, and paste the reason into this ticket.\n\n**Likely suspects** (to narrow down once we see the reason):\n- macOS 26.3 crash (fixed in 6d379bb on 2026-03-14 — upgrade Electron 40.1.0 → 41.0.2). The 1773489007 build was uploaded the same day as the fix commit, so it may or may not contain it.\n- Missing beta test notes or reviewer demo info (betaAppReviewDetails shows notes=null, demoAccountRequired=false, but reviewer might need extra context)\n- Sandbox entitlement issue\n- Helper app signing issue\n- Hardcoded paths\n\n**Blocks**: markdown-reader-xwc (Local-Only edition) — it makes no sense to submit a second MAS edition when we can't get the first through beta review.\n\n**Next step after cause identified**: bump to v1.0.5, rebuild with current main.js (which includes Electron 41.0.2, agent-native socket, Unix IPC fixes, and editor-per-tab improvements), upload via scripts/build-mas.sh --upload, resubmit for external review.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-04-07T17:04:24.365032-07:00","updated_at":"2026-04-07T17:20:01.875886-07:00","comments":[{"id":5,"issue_id":"markdown-reader-kfr","author":"jacobcole","text":"Resolved the rejection cause and resubmitted:\n\n**Rejection reason** (from Resolution Center): Guideline 2.1(a) — App Completeness. 'We were unable to review the app as it crashed on launch on Mac running macOS 26.3.' (Confirmed via Resolution Center on 2026-04-07; the email notification had no details.)\n\n**Root cause**: The rejected build 1773489007 was uploaded on 2026-03-14 at 04:54 PT. The Electron 40→41 fix for the macOS 26.3 crash was committed 18 minutes later at 05:12 PT (commit 6d379bb). The fix was never rebuilt + re-uploaded — it sat in source for ~3 weeks while Apple rejected the broken build on 2026-03-17 / 2026-03-18.\n\n**Resubmitted 2026-04-07**:\n- Build: v1.0.5 (1775607178)\n- Electron: 41.0.2 (fix confirmed in package.json)\n- Commit: 417356a on feature/daily-notes\n- Also includes: agent-native Unix socket, wikilink resolver, editor-per-tab, folder support, and 3 weeks of other improvements\n- Added to 'friendsext' external beta group\n- Submitted to Apple beta review, state: WAITING_FOR_REVIEW\n- Apple typically reviews within 24-48 hours\n\n**Process improvements committed to prevent repeat**:\n1. scripts/build-mas.sh now has a Step 0 version safeguard that aborts if package.json version matches the last uploaded build (with --auto-bump flag to auto-increment patch version)\n2. scripts/submit-mas-for-external-review.py automates the manual step of adding build to group and submitting for review (previously done by hand in the App Store Connect UI)\n\n**Next**: Monitor beta review state at https://appstoreconnect.apple.com/apps/6758376669/testflight/ios. Close ticket when Apple approves the build or if we need to iterate.","created_at":"2026-04-08T00:20:02Z"}]} -{"id":"markdown-reader-kq3","title":"Escape key to exit edit mode (auto-save or prompt)","description":"Currently Escape doesn't leave edit mode. Proposal: Escape switches from edit → preview mode.\n\n**Options to consider:**\n1. **Auto-save + switch (recommended)**: Escape silently saves any pending changes and switches to preview. Clean, no dialogs, matches Obsidian's Ctrl+E toggle feel. Relies on having autosave or a synchronous save-on-toggle.\n2. **Prompt on unsaved**: Escape shows 'Save changes before exiting edit mode?' Save / Discard / Cancel. More explicit but friction.\n3. **Toggle only (no save)**: Escape switches mode but leaves the unsaved state as-is — the tab shows the blue dot. Safest, least decision, matches current Cmd+S ergonomics.\n\n**Recommendation**: Option 1 if autosave is reliable; Option 3 otherwise. Avoid option 2 unless the app regularly loses work.\n\n**Also consider**: What if user is in a modal/command palette/search bar when Escape is pressed? Those already consume Escape, so this should only fire when the editor has focus and no overlay is open.\n\n**Reference**: Obsidian uses Ctrl+E to toggle; VS Code has no edit/preview split; Typora auto-saves.","notes":"Claimed for implementation. Plan: Escape exits edit mode when the editor has focus and no overlay is open, preserving unsaved state rather than reverting or silently saving.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T04:23:47.493774-07:00","updated_at":"2026-04-08T22:03:14.921905-07:00","closed_at":"2026-04-08T22:03:14.921905-07:00","close_reason":"Implemented Escape-to-preview behavior for active editor focus. Escape now exits edit mode without forcing a revert or silent save, preserving dirty state and using the same preview transition path as the explicit toggle.","dependencies":[{"issue_id":"markdown-reader-kq3","depends_on_id":"markdown-reader-a4h","type":"blocks","created_at":"2026-04-07T04:28:23.669412-07:00","created_by":"daemon"}]} -{"id":"markdown-reader-kw7","title":"Show recently modified files in the current open folder","description":"Design and implement a feature to view recently modified files in the currently open folder, sorted by recency. This helps users quickly identify which files have been updated.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-22T15:09:11.171354-08:00","updated_at":"2026-01-22T15:19:11.193534-08:00","closed_at":"2026-01-22T15:19:11.193534-08:00","close_reason":"Closed"} -{"id":"markdown-reader-l7u","title":"Cmd+F should refocus open find bar in edit mode","description":"When the in-file find bar is already open while editing, pressing Cmd+F again should keep find open and focus/select the query. It currently behaves like a toggle and can close or fail from the editor context.","acceptance_criteria":"Cmd+F opens find from edit mode; Cmd+F with find already open keeps it open, focuses/selects the query, and does not exit edit mode; Esc or close button still closes find.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-11T17:42:58.67441-07:00","updated_at":"2026-05-11T17:44:03.992081-07:00","closed_at":"2026-05-11T17:44:03.992081-07:00","close_reason":"Fixed Cmd+F handling so Find opens or refocuses the find bar instead of toggling it closed. Added capture-phase shortcut handling for edit mode and regression coverage."} -{"id":"markdown-reader-lc6","title":"File-tree labels overflow right edge of sidebar (esp. sample Obsidian vault)","description":"## Symptom\nLong filenames — especially in sample Obsidian Vault files — overflow past the right edge of the left sidebar instead of being truncated or wrapping.\n\n## Repro (needs confirmation)\n1. Open the bundled sample Obsidian vault\n2. Notice one or more file-tree entries whose title visibly bleeds past the sidebar's right border\n3. Probably worse when the sidebar is at default width and worse on files deep in a nested folder (indent eats horizontal space)\n\n## Suspected cause\nPossibly one or more of:\n- Missing/insufficient `overflow: hidden` or `text-overflow: ellipsis` on `.file-name` / tree-node label CSS\n- A flex layout where the label has `flex-shrink: 0` or `min-width` blocking truncation\n- Wiki-link rendering extension recently added (commit `207b6c4`) — worth checking whether it changed tree rendering too, or only document rendering\n- Obsidian titles with spaces and unicode may be computed-width differently than ASCII-only\n\n## Investigation checklist\n- [ ] Open sample vault, screenshot the overflow in both collapsed and expanded states\n- [ ] Inspect offending node in DevTools; note computed `width`, `overflow`, `text-overflow`, `flex` on each ancestor up to the sidebar container\n- [ ] Check styles.css rules for `.file-name`, `.file-tree-item`, `.file-tree-label`, etc.\n- [ ] Verify the same filename in a non-sample folder — is it Obsidian-specific or any long name?\n- [ ] Test edge cases: emoji in name, CJK characters, very long unbroken strings (no spaces)\n\n## Fix (likely)\nAdd the standard text-truncation pattern to the label element:\n```css\n.file-tree-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0; /* crucial: allows flex children to shrink below content size */\n}\n```\nPlus ensure the parent flex row has `min-width: 0` too (common flex gotcha).\n\n## Bonus\nOnce truncation works, add a tooltip (`title` attribute or custom) showing the full filename on hover so users can still read long names.","notes":"Claimed for implementation. Plan: fix sidebar row flex/truncation so long file/folder labels ellipsize within the sidebar and keep full path/name available on hover.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-08T21:58:38.124027-07:00","updated_at":"2026-04-08T22:03:15.072404-07:00","closed_at":"2026-04-08T22:03:15.072404-07:00","close_reason":"Fixed sidebar tree row truncation by giving rows and labels proper flex shrink/min-width behavior, adding explicit label elements, and preserving full path/name tooltips through render and rename flows."} -{"id":"markdown-reader-lg4","title":"Blue dot (unsaved indicator) persists after saving a file","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-01T21:06:57.501638-08:00","updated_at":"2026-03-02T17:22:41.441986-08:00","closed_at":"2026-03-02T17:22:41.441986-08:00","close_reason":"Fixed unsaved indicator: Blue dot now shows for modified files, edit mode shows pencil symbol"} -{"id":"markdown-reader-lrp","title":"Keep expanded sidebar folders in sync with external filesystem changes","description":"The sidebar live watcher detects recursive filesystem changes but only reloads the root directory tree. If a nested folder is already expanded, its child list can go stale or disappear after external files are added/removed. Acceptance: before re-rendering after an external refresh, reload children for currently-expanded folders so visible nested contents stay current.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-07T21:04:33.024955-07:00","updated_at":"2026-05-07T21:06:10.39581-07:00","closed_at":"2026-05-07T21:06:10.39581-07:00","close_reason":"Fixed: sidebar live refresh now reloads children for folders that are currently expanded before re-rendering the tree."} -{"id":"markdown-reader-lzy","title":"Add DOCX import and export support","description":"Allow users to export current markdown documents to .docx and open/import .docx files into the app. Include menu actions (Open..., Export...), reasonable markdown↔docx fidelity for headings/lists/links/code blocks, and clear handling for unsupported formatting.","acceptance_criteria":"1) Users can open a .docx file and it loads as editable markdown content. 2) Users can export the active document to .docx from the app menu. 3) File dialogs include .docx in supported types where relevant. 4) Unsupported DOCX constructs are handled gracefully without crashes and with user-visible notice when needed.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-26T20:16:19.597636-08:00","updated_at":"2026-02-26T20:16:19.597636-08:00"} -{"id":"markdown-reader-msv","title":"Web-based markdown viewer — paste URL or upload file to render","description":"A hosted web version of OpenMarkdownReader where anyone can paste a markdown URL or upload a file and view it rendered nicely, no app install needed. Consider integrating with noos (knowledge graph) for saving/linking notes.","notes":"2026-05-27 Proof by Every research added at research/proof-by-every.md. Default v1 should be read-only publish plus raw/JSON agent endpoints; defer comments/suggestions and realtime collaboration as explicit later product choices.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-03-23T12:51:34.836741-10:00","updated_at":"2026-05-27T18:43:29.04764-07:00"} -{"id":"markdown-reader-mwv","title":"Add VS Code-style split editor view (side-by-side tabs)","description":"Add split editor workflow to view/edit two files side-by-side (or split same file), with tab-to-split actions and resizeable divider similar to standard editors.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:42:07.534395-08:00","updated_at":"2026-02-26T17:42:07.534395-08:00"} -{"id":"markdown-reader-n36","title":"Add breadcrumb path bar for active file navigation","description":"Standard editors expose active-file location with clickable breadcrumbs. Add a breadcrumb bar above content showing workspace-relative path segments and current heading/file context to reduce navigation friction in nested folders.","acceptance_criteria":"1) Breadcrumbs show workspace root -\u003e folder segments -\u003e file name for active tab. 2) Each folder segment is clickable and reveals that folder in sidebar. 3) Breadcrumbs update on tab switch and file rename/move. 4) Hidden/overflow handling works on small window widths.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-02-26T17:45:57.732577-08:00","updated_at":"2026-02-26T17:45:57.732577-08:00"} -{"id":"markdown-reader-n6w","title":"EasyMDE preview doesn't render lists with dashes as bullets","description":"In split/side-by-side mode, dashes (-) aren't being rendered as bullet points. This is NOT intentional - EasyMDE is using its own bundled markdown parser instead of the app's configured marked.js with proper rendering. Fix: Add previewRender option to EasyMDE config that uses the app's marked instance.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-26T19:20:07.110116-08:00","updated_at":"2025-12-26T19:35:21.202776-08:00","closed_at":"2025-12-26T19:35:21.202776-08:00","close_reason":"Closed"} -{"id":"markdown-reader-nzs","title":"Obsidian markdown support","notes":"Investigating current wiki-link rendering path and restoring Obsidian-style [[...]] support without flattening links into saved markdown.","status":"closed","priority":4,"issue_type":"feature","assignee":"codex","created_at":"2025-12-28T00:52:01.583283-08:00","updated_at":"2026-04-07T21:03:45.71013-07:00","closed_at":"2026-04-07T21:03:45.71013-07:00","close_reason":"Implemented parser-level Obsidian-style wiki link support in the desktop renderer via a marked extension. `[[page]]`, `[[page|alias]]`, and same-note heading links now render without rewriting markdown source; remaining broader Obsidian compatibility is tracked in markdown-reader-q3q."} -{"id":"markdown-reader-o3m","title":"Auto-parse AI chat transcripts into formatted sections","description":"When pasting AI chat history (from Clawd, Claude, etc.), automatically parse and format it:\n- Detect chat patterns (User:/Assistant:, Human:/Claude:, etc.)\n- Convert to formatted sections with headings or visual distinction\n- Make conversations more readable in markdown view\n- Could be auto-detect on paste or a manual 'Format as Chat' action\n\nVisual distinction:\n- Clear visual difference between human messages and AI messages\n- Different styling/colors/backgrounds for each speaker\n- Appropriate margins/spacing between messages for readability\n\nCollapse functionality:\n- Consider 'Collapse all AI responses' button\n- Or leverage existing section collapse features\n- Evaluate if current heading collapse covers this use case or if dedicated chat collapse is needed\n\nTerminal formatting preservation:\n- Research: Can we preserve/import terminal formatting (ANSI colors, syntax highlighting)?\n- Export option to retain terminal colors/highlights from CLI tools\n- Consider parsing ANSI escape codes and converting to styled HTML/markdown\n- Useful for Claude Code transcripts, other CLI chat tools\n\nLayout/Margins:\n- Chat-specific margin settings (tighter or looser spacing between turns)\n- Consider chat bubble style vs linear style options\n- Respect global margin settings but allow chat-specific overrides","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-14T15:05:39.04639-08:00","updated_at":"2026-01-14T15:22:44.335623-08:00"} -{"id":"markdown-reader-o5i","title":"Sort files by recency in sidebar","description":"Add a sort toggle button to the sidebar header to switch between 'Name' (A-Z) and 'Date Modified' (Newest First) sorting for the standard file tree view.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-22T22:36:38.304546-08:00","updated_at":"2026-01-22T22:48:34.639595-08:00","closed_at":"2026-01-22T22:48:34.639595-08:00","close_reason":"Closed"} -{"id":"markdown-reader-p87","title":"Formalize frontend log forwarding","description":"Ensure frontend console logs are always forwarded to the main process terminal in development mode for easier debugging. Currently implemented ad-hoc in renderer.js.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-23T12:03:41.240835-08:00","updated_at":"2026-01-23T20:55:41.428687-08:00","closed_at":"2026-01-23T20:55:41.428687-08:00","close_reason":"Closed"} -{"id":"markdown-reader-pcb","title":"Open remote markdown URLs from Quick Open","description":"Cmd+P currently detects http/https URLs but sends them to shell.openExternal. Implement remote text/markdown URL fetching in main process and open fetched content in an app tab, keeping document links external.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T01:51:33.893278-07:00","updated_at":"2026-05-22T01:56:01.07713-07:00","closed_at":"2026-05-22T01:56:01.07713-07:00","close_reason":"Implemented Cmd+P remote text/markdown URL opening inside the app"} -{"id":"markdown-reader-pvi","title":"Consider full WYSIWYG editing mode","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-12-28T00:52:31.002609-08:00","updated_at":"2026-04-07T04:35:50.078825-07:00","closed_at":"2026-04-07T04:35:50.078825-07:00","close_reason":"Merged into markdown-reader-r1r (Milkdown WYSIWYG editor plan). The two tickets were near-duplicates; r1r is now the active home for WYSIWYG work.","dependencies":[{"issue_id":"markdown-reader-pvi","depends_on_id":"markdown-reader-rhj","type":"relates-to","created_at":"2025-12-28T00:54:57.448388-08:00","created_by":"daemon"}]} -{"id":"markdown-reader-q1s","title":"Support Obsidian-style wiki links within opened folders","description":"When a folder is opened in OpenMarkdownReader, support Obsidian-style [[wiki links]]:\n\n**Behavior:**\n- Parse `[[page name]]` syntax in markdown files\n- Resolve links by matching against filenames in the opened folder (without .md extension)\n- Click on wiki link → open that file in a new tab (or switch to existing tab)\n\n**Conflict handling:**\n- If multiple files have the same name (in different subdirectories), choose the first match\n- Show a warning/toast when a conflict is detected\n- Could potentially show disambiguation UI in future\n\n**Requirements:**\n- Folder must be opened (not just a single file)\n- Links are relative to the folder root\n- Support both `[[page]]` and `[[page|display text]]` syntax\n\n**Nice to have:**\n- Backlinks panel showing what links to the current page\n- Broken link highlighting (links to non-existent pages)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-15T00:10:04.281947-08:00","updated_at":"2026-01-15T00:16:45.172351-08:00","closed_at":"2026-01-15T00:16:45.172351-08:00","close_reason":"Implemented Obsidian-style wiki links: [[page]] and [[page|alias]] syntax, conflict warnings, broken link styling"} -{"id":"markdown-reader-q3q","title":"Finish broader Obsidian compatibility beyond parser-level wiki links","description":"Parser-level support for `[[page]]`, `[[page|alias]]`, and same-note heading links is now in the desktop renderer via a marked extension. Remaining Obsidian compatibility work should be tracked separately:\n- `![[embed]]` embeds\n- cross-file heading navigation (`[[note#Heading]]` should open note and jump)\n- block refs (`[[note#^block]]`)\n- audit any metadata/backlink panes that may still serialize links as markdown text instead of rendering them","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-07T21:03:23.515813-07:00","updated_at":"2026-04-07T21:03:23.515813-07:00"} -{"id":"markdown-reader-qcz","title":"Smart dev watcher: renderer reload vs full app restart","description":"**Goal**: Make the dev iteration loop dramatically faster by differentiating which source files changed.\n\n**Today**: main.js:3332-3353 watches all source files and unconditionally fires 'source-code-changed' which triggers a full app.relaunch(). That's slow (~3-5s) and loses BrowserWindow state, sidebar collapse state, scroll position, etc.\n\n**Proposal**:\n- main.js / preload.js / build-info.json change → full app.relaunch() (must — main process is stale)\n- renderer.js / index.html / styles.css / vendor/* change → webContents.reload() per window (much faster, preserves BrowserWindow + main state)\n\n**Implementation sketch** (main.js:3332-3353):\n1. Group sourceFiles into 'mainProcessFiles' and 'rendererFiles'\n2. fs.watch callback inspects filename, sends either 'source-code-changed' (existing, full restart) or 'renderer-changed' (new event, soft reload)\n3. Renderer 'renderer-changed' handler shows the existing pulsing button but with text 'Reload' instead of 'Restart' and triggers webContents.reload() via a new IPC handler\n4. Main process IPC handler 'reload-renderer' calls win.webContents.reload() on focused window (or all windows)\n\n**Acceptance**:\n- Editing only renderer.js shows 'Reload' button → click reloads in \u003c500ms, preserves window\n- Editing main.js shows 'Restart' button → click full restarts as today\n- Toast confirms which mode fired\n\n**Related**: markdown-reader-788 (closed) shipped the basic restart button this builds on.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T04:56:23.418835-07:00","updated_at":"2026-04-07T04:57:55.505931-07:00","closed_at":"2026-04-07T04:57:55.505931-07:00","close_reason":"Implemented in working tree (not yet committed). Smart dev watcher: main.js:3332-3380. Restart accelerator: main.js:1006-1013. DEV badge tooltip: renderer.js:6421-6448. New IPC: preload.js, main.js reload-renderer handler. User to review + commit."} -{"id":"markdown-reader-qn6","title":"Make pasting terminal output friendly","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T00:51:32.439447-08:00","updated_at":"2026-04-16T00:32:02.118506-07:00"} -{"id":"markdown-reader-r12","title":"Add collapse-all feature for sidebar/outline","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-03-23T12:35:22.982746-10:00","updated_at":"2026-04-07T15:13:17.130848-07:00","closed_at":"2026-04-07T15:13:17.130848-07:00","close_reason":"Added Collapse All button to sidebar header. Clicking it clears expandedFolders and re-renders the file tree. Only acts when in tree view mode (no-op for recent/timeline modes which don't have folder state)."} -{"id":"markdown-reader-r1r","title":"WYSIWYG edit mode that renders markdown inline","description":"**Goal**: Add a Milkdown-based WYSIWYG editor as a new editing mode. Long-term, this could become the default edit mode, with a separate read-only viewing mode preserved.\n\n**Why Milkdown (not Tiptap)**:\n- Built on ProseMirror, like Tiptap, but Markdown is first-class (uses remark) so round-tripping text → tree → text is clean\n- Plugin-based so we can add only what we need\n- Collab path is still open via @milkdown/plugin-collab (see parking ticket markdown-reader-[collab])\n\n**Scope v1**:\n- Ship Milkdown as an **alternative** edit mode behind a toggle / setting — do NOT make it default on day one\n- Preserve current plain-textarea and EasyMDE modes until Milkdown is proven stable on real notes\n- Roundtrip fidelity test: open each file in the user's vault, edit nothing, save, diff — must be zero-change\n- Handle wikilinks [[...]] as a custom node (otherwise they get mangled)\n- Handle frontmatter passthrough\n\n**Scope v2** (after stability):\n- Promote Milkdown to default editing mode\n- Keep a 'Plain / Raw Markdown' mode in the View menu for power users and for cases where Milkdown struggles\n- Read-only preview mode stays untouched\n\n**Blockers / prerequisites**:\n- markdown-reader-a4h (undo persistence across mode/tab switches). A WYSIWYG editor is a much bigger state machine and swapping it in/out while preserving undo is hard. Don't start until editor-per-tab lifecycle is solid.\n\n**Open questions**:\n- Do we ship Milkdown via CDN/vendor or bundle through a proper build step? (likely need a build step — Milkdown isn't a single-file drop-in like EasyMDE)\n- How does it interact with the custom wikilink indexer and the rich-toolbar toggle?\n- Styling parity with current preview CSS\n\n**Merged from**: markdown-reader-pvi (closed as duplicate)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-26T19:11:51.966206-08:00","updated_at":"2026-04-07T04:35:42.859157-07:00","labels":["defer"],"dependencies":[{"issue_id":"markdown-reader-r1r","depends_on_id":"markdown-reader-a4h","type":"blocks","created_at":"2026-04-07T04:35:48.006635-07:00","created_by":"daemon"}],"comments":[{"id":1,"issue_id":"markdown-reader-r1r","author":"jacobcole","text":"## Research Notes\n\n**Options for WYSIWYG/live-preview edit mode:**\n\n| Approach | Raw Text Visible | Rendered Inline | Effort |\n|----------|------------------|-----------------|--------|\n| EasyMDE (current) | Yes | No | N/A |\n| Milkdown/Tiptap | No | Yes (pure WYSIWYG) | Medium |\n| Obsidian-style (CodeMirror 6) | Yes | Yes (decorations) | High |\n| Split pane (EasyMDE built-in) | Yes | Side-by-side | Already available |\n\n**Recommendations:**\n- Milkdown is pure WYSIWYG - hides raw markdown, shows rendered output only\n- Obsidian approach is best of both worlds (see raw syntax but styled) - requires CodeMirror 6 with custom decorations\n- EasyMDE already has side-by-side mode (columns icon in Rich toolbar)\n\n**Libraries to consider:**\n- Milkdown (ProseMirror-based, ~40kb gzipped)\n- Tiptap (ProseMirror-based, very flexible)\n- CodeMirror 6 with markdown decorations (what Obsidian uses)","created_at":"2025-12-27T03:17:10Z"}]} -{"id":"markdown-reader-rhj","title":"RTF with formatting support","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T00:54:41.684696-08:00","updated_at":"2025-12-28T00:54:41.684696-08:00","dependencies":[{"issue_id":"markdown-reader-rhj","depends_on_id":"markdown-reader-pvi","type":"relates-to","created_at":"2025-12-28T00:54:57.449069-08:00","created_by":"daemon"}]} -{"id":"markdown-reader-rx4","title":"Choose homepage variant and wire a hosting/deployment path","description":"The repo now has a primary marketing homepage in `site/` and two alternatives in `site/alternatives/claude/` and `site/alternatives/nash/`.\n\nFollow-up needed:\n- Decide which concept becomes the canonical public homepage\n- Fold best ideas from the alternates into the chosen version if needed\n- Pick a hosting path (GitHub Pages, static host, app site, etc.)\n- Add a simple local preview/deploy workflow if we want the page to live outside the repo only as source\n\nAcceptance ideas:\n1. One homepage variant is selected as canonical.\n2. Hosting/deployment path is documented and tested.\n3. Public URL or publish procedure exists.\n4. Repo docs link to the chosen homepage entrypoint and workflow.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-08T22:12:21.368633-07:00","updated_at":"2026-04-08T22:12:21.368633-07:00"} -{"id":"markdown-reader-s8i","title":"Show word count for current document","description":"Add visible word count for the active markdown document.","notes":"Implemented a titlebar word-count indicator for the active document. Added shared countWords utility (Unicode-aware, handles contractions/hyphenation), wired live updates for preview/plain/rich edit flows, and added node tests in tests/word-count.test.js.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:16.171721-08:00","updated_at":"2026-02-26T17:45:04.752645-08:00","closed_at":"2026-02-26T17:45:04.752645-08:00","close_reason":"Completed: current-document word count visible in UI with tests."} -{"id":"markdown-reader-st8","title":"Add browsing/navigation history feature","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-02T23:48:01.701383-07:00","updated_at":"2026-04-02T23:48:01.701383-07:00"} -{"id":"markdown-reader-trs","title":"Feature: Open markdown files from URL in command palette (Cmd+P)","status":"open","priority":2,"issue_type":"feature","created_at":"2026-03-11T03:39:54.351428-07:00","updated_at":"2026-03-11T03:39:54.351428-07:00"} -{"id":"markdown-reader-tw1","title":"Daily note opens directly in edit mode","description":"Creating a new daily note should immediately enter edit mode instead of preview/read mode.","notes":"Reproduced by tracing daily-note flow: createDailyNote() writes new file, then calls loadMarkdownFile() without forceEdit, so renderer opens in preview/read mode. Implemented fix in main.js: track newly created file and call loadMarkdownFile(win, filePath, { forceEdit: createdNewFile }). Existing daily notes still open in current mode; only newly created notes force edit mode. Verification: node --check main.js passed.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-26T17:25:15.841763-08:00","updated_at":"2026-02-26T20:15:06.670436-08:00","closed_at":"2026-02-26T20:15:06.670436-08:00","close_reason":"Daily note creation now opens newly created note directly in edit mode."} -{"id":"markdown-reader-va5","title":"Add one-click publish to noos (globalbr.ai)","description":"Add publish button that uploads current file to noos anonymously and copies shareable URL to clipboard","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-14T08:45:14.576567-08:00","updated_at":"2026-01-14T08:56:23.873016-08:00","closed_at":"2026-01-14T08:56:23.873016-08:00","close_reason":"Implemented publish button that uploads to noos anonymous endpoint"} -{"id":"markdown-reader-vji","title":"Add back/forward navigation (browser-style history)","description":"Add browser-style back/forward navigation for file history:\n\n**Features:**\n- Back button (Cmd+[) to go to previous file/location\n- Forward button (Cmd+]) to go forward after going back\n- Navigation history stack tracking opened files\n- Buttons in titlebar or toolbar\n\n**Behavior:**\n- Opening a file pushes to history\n- Back navigates to previous file\n- Forward only available after using back\n- History clears forward stack on new navigation","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-15T00:38:56.82804-08:00","updated_at":"2026-01-15T00:42:47.691132-08:00","closed_at":"2026-01-15T00:42:47.691132-08:00","close_reason":"Implemented back/forward navigation with Cmd+[ and Cmd+], buttons in titlebar, Go menu"} -{"id":"markdown-reader-wdj","title":"JSONL parser for Claude Code sessions","description":"Parse Claude Code session files (~/.claude/projects/*.jsonl):\n- Auto-detect format on file open\n- Extract human/assistant/tool messages\n- Render with Terminal View + chat parsing\n- Show timestamps, thinking blocks (toggleable)","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-01-20T19:11:01.762111-08:00","updated_at":"2026-01-20T19:51:12.995096-08:00","closed_at":"2026-01-20T19:51:12.995096-08:00","close_reason":"Closed"} -{"id":"markdown-reader-wlp","title":"Render YAML frontmatter as collapsed metadata block instead of markdown","description":"YAML frontmatter at the top of a markdown file is currently passed directly to marked.parse(), which mangles it: single tildes in paths like ~/Downloads/... trigger strikethrough, the --- delimiters become horizontal rules / setext headings, and wiki links mixed with YAML punctuation create bizarre inline wrapping. Repro: /Users/jacobcole/code/RealtimeMeetingOutline/wiki/meta/ideaflow-slack-export.md. Fix: extract leading YAML frontmatter and render it as a collapsed \u003cdetails\u003e block with syntax-highlighted YAML, then render the body as markdown normally.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-15T23:02:28.336493-07:00","updated_at":"2026-04-15T23:21:18.81983-07:00","closed_at":"2026-04-15T23:21:18.81983-07:00","close_reason":"Fixed: extract YAML frontmatter into collapsed \u003cdetails\u003e block, render remainder as markdown. Repro file now renders correctly instead of showing mangled strikethrough/horizontal-rule/wiki-link soup."} -{"id":"markdown-reader-xwc","title":"Ship 'OpenMarkdownReader Local-Only' as a second MAS edition","description":"**Goal**: Ship a second edition of OpenMarkdownReader on the Mac App Store aimed at enterprise users (Anthropic, banks, law firms, anyone with data-exfiltration policies). The killer positioning: the only markdown app on the Mac App Store that cannot leak your documents.\n\n**Product decisions** (finalized 2026-04-07):\n- **Name**: \"OpenMarkdownReader Local-Only\" (NOT \"Secure\" or \"Private\" — those would imply the standard edition isn't, which is a bad marketing signal)\n- **Distribution**: Mac App Store only (both editions live side-by-side on MAS)\n- **Standard edition**: keeps Share button, Report Issue, Noos feedback widget, auto-updater (and continues to ship as direct-download DMG/ZIP too)\n- **Local-Only edition**: MAS-only, sandboxed, ZERO network egress for document data\n\n**Two MAS listings from one codebase**:\n\n| | Standard | Local-Only |\n|---|---|---|\n| Distribution | MAS + direct DMG/ZIP | MAS only |\n| Bundle ID | `com.jacobcole.openmarkdownreader` | `com.jacobcole.openmarkdownreader.localonly` |\n| productName | OpenMarkdownReader | OpenMarkdownReader Local-Only |\n| Share-to-web button | ✅ | ❌ hidden |\n| Report Issue menu | ✅ | ❌ hidden |\n| Noos feedback widget | ✅ | ❌ not loaded |\n| Auto-updater | ✅ (direct build) / managed by MAS | managed by MAS |\n| `network.client` entitlement | ✅ | ❌ removed — sandbox physically blocks all outbound connections |\n| Icon | standard | variant (TBD — maybe subtle lock/house overlay) |\n\n**Current network egress paths that must be gated off in Local-Only build**:\n- `renderer.js:2776` — Share button POSTs document content to `https://globalbr.ai/api/files/anonymous`\n- `renderer.js:3116` — Report Issue modal POSTs to `https://globalbr.ai/api/nodes/anonymous-submit`\n- `vendor/noos-feedback.js` + `index.html:457` — Noos feedback widget (GET on open, POST on send)\n- Auto-updater (already gated via `isMASBuild()`)\n\n**Architecture** (decided):\n\nSingle codebase, three layers of enforcement:\n\n1. **Build-edition constant** (`build-edition.js`, generated at build time from `BUILD_EDITION` env var):\n ```js\n module.exports = {\n edition: 'standard' | 'local-only',\n hasCloudShare: boolean,\n hasReportIssue: boolean,\n hasNoosWidget: boolean,\n productName: string,\n bundleId: string,\n };\n ```\n Every network-feature call site checks this constant and hides/disables UI.\n\n2. **Build-time file exclusion** — electron-builder `files` pattern drops `vendor/noos-feedback.js` from local-only builds. Script tag in `index.html` becomes a 404 at runtime, so even if gating breaks, no code to execute.\n\n3. **Entitlement removal** — local-only `entitlements.mas.plist` removes `com.apple.security.network.client`. Apple's sandbox itself blocks every outbound connection. This makes \"local only\" auditable: a security researcher can verify it with `codesign -d --entitlements - OpenMarkdownReader\\ Local-Only.app`.\n\n**Build commands**:\n```bash\nnpm run build:mac # Standard universal DMG/ZIP (unchanged)\nnpm run build:mas # Standard edition on MAS (unchanged)\nnpm run build:mas-local-only # Local-Only edition on MAS (new)\n```\n\n**Acceptance criteria**:\n1. Both MAS editions share \u003e95% of source code; only divergence is the `BUILD_EDITION` constant, electron-builder config, and entitlements.\n2. `npm run build:mas-local-only` produces a MAS package with:\n - No `noos-feedback.js` in the bundle\n - No `network.client` entitlement (verifiable via `codesign -d --entitlements -`)\n - Share button hidden, Report Issue menu item hidden\n3. Static verification: `grep -r globalbr.ai` in the built app bundle finds nothing in the renderer code for the local-only edition.\n4. About dialog on Local-Only shows: \"OpenMarkdownReader Local-Only — Sandboxed, no network\". Standard About dialog is unchanged.\n5. Both editions can be installed simultaneously (different bundle IDs) and share no state.\n6. Marketing copy for Local-Only MAS listing emphasizes: \"No telemetry. No cloud sync. No share-to-web. Your documents never leave your Mac. Verified by Apple's sandbox — we physically cannot send your data anywhere.\"\n\n**Implementation plan** (when ready):\n1. Create `build-edition.js` generator script (similar to `scripts/generate-build-info.js`)\n2. Add `build-edition` import to `main.js` and `renderer.js`\n3. Gate all three network paths in `renderer.js` behind `buildEdition.hasCloudShare` etc.\n4. Add `package.json` build variant with `mac-local-only` config (different `files`, `mac.appId`, `productName`, `mas.entitlements`)\n5. Create `build/entitlements.mas.local-only.plist` (copy of current without `network.client`)\n6. Create `scripts/build-mas-local-only.sh` (variant of current `build-mas.sh`)\n7. Add \"Local-Only edition — Sandboxed, no network\" badge in About dialog\n8. Update README.md with both editions\n9. Create second App Store Connect listing for the new bundle ID\n10. Test: install both on same Mac, confirm no network calls from local-only via `tcpdump` / Little Snitch\n\n**Open questions** (remaining):\n- Should we ship Local-Only as the FIRST MAS release and hold Standard back until we have both? Or ship Standard first and add Local-Only later?\n- Icon variant design — subtle lock overlay? Different color? Or same icon?\n- Do we use a shared README or two separate App Store Connect descriptions?\n\n**Related tickets**:\n- markdown-reader-il6 (agent-native Unix socket — must work in both editions since it's local IPC)\n- markdown-reader-ztt (audit MAS sandbox-unsafe paths — informs gating)\n- markdown-reader-st8 (browsing history — must be local-only storage in both editions)","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-02T23:48:02.18555-07:00","updated_at":"2026-04-07T16:53:05.879376-07:00","dependencies":[{"issue_id":"markdown-reader-xwc","depends_on_id":"markdown-reader-kfr","type":"blocks","created_at":"2026-04-07T17:04:33.224063-07:00","created_by":"daemon"}],"comments":[{"id":3,"issue_id":"markdown-reader-xwc","author":"jacobcole","text":"Icon decision finalized 2026-04-07: slate/graphite gradient background (#475569 → #0F172A) with 'LOCAL' ribbon across the bottom. Assets committed: build/icon-local-only.{svg,png,icns} and build/icon-local-only-dev.{svg,png} (dev variant shows 'LOCAL • DEV' ribbon, DEV in orange to match existing dev icon convention). Candidates explored in build/icon-variants/: v1-green (too hobbyist), v2-slate-padlock (padlock invisible at small sizes), v3-blue-house (insufficient differentiation), v4-slate-ribbon (WINNER — slate says 'premium/enterprise', LOCAL ribbon stays readable down to 32px dock size). main.js:1943 updated to pick build/icon-local-only-dev.png as the dev dock icon when OMR_EDITION=local-only env var is set; this env var will eventually come from the BUILD_EDITION constant once the dual-edition system lands.","created_at":"2026-04-07T23:59:47Z"},{"id":4,"issue_id":"markdown-reader-xwc","author":"jacobcole","text":"Blocked on markdown-reader-TBD (the TestFlight rejection ticket — will add dep once created). The Local-Only edition cannot be submitted until we can ship ANY edition through external beta review successfully. The Standard edition has been rejected twice for external testing (builds 1773226755 and 1773489007, both v1.0.4), reason unknown until Jacob reads the Resolution Center. Also: the Local-Only build itself does not exist yet — only icon assets and the implementation plan are committed. Actual code gating, entitlement variant, build script, and package.json variants are still pending per the 10-step implementation plan above.","created_at":"2026-04-08T00:04:29Z"}]} -{"id":"markdown-reader-ypl","title":"Marktree support","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T00:52:02.696217-08:00","updated_at":"2025-12-28T00:52:02.696217-08:00"} -{"id":"markdown-reader-yqc","title":"Fix Publish button: CSP, icon direction, size","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-14T09:01:59.202001-08:00","updated_at":"2026-01-14T09:09:55.319108-08:00","closed_at":"2026-01-14T09:09:55.319108-08:00","close_reason":"Fixed: CSP, icon direction, button size all resolved"} -{"id":"markdown-reader-ytp","title":"Native macOS editor context menu actions in content area","description":"Right-click context menu should include standard actions like Copy, Paste, Look Up, and Speech (Speak/Start Speaking) where appropriate, matching normal macOS app behavior.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-26T17:25:16.011537-08:00","updated_at":"2026-02-26T20:15:07.825822-08:00","closed_at":"2026-02-26T20:15:07.825822-08:00","close_reason":"Added native macOS-style text context menu actions (edit, Look Up, Speech) via webContents context-menu handling."} -{"id":"markdown-reader-zn7","title":"Fix heading collapse arrow wrapping","description":"On narrow screens, the collapse arrow (triangle) for headings wraps to the line above the heading text. It should remain inline with the heading using proper flexbox or white-space handling.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-22T22:36:54.540942-08:00","updated_at":"2026-01-22T22:44:08.924571-08:00","closed_at":"2026-01-22T22:44:08.924571-08:00","close_reason":"Closed"} -{"id":"markdown-reader-ztt","title":"Audit MAS build for sandbox-unsafe code paths + surface silent failures","description":"**Context**: MAS build (markdown-reader-il6 uses isMASBuild() gating) runs inside Apple's sandbox with entitlements: app-sandbox, files.user-selected.read-write, files.downloads.read-write, network.client. Anything writing outside those scopes silently fails in MAS but works fine in the notarized build.\n\n**Goal**: Audit renderer.js and main.js for file-system, shell, and IPC operations that could silently fail under sandbox, and either (a) gate them off with isMASBuild() checks or (b) surface a clear error toast to the user when they fail.\n\n**Suspects to review**:\n- Recent files persistence / security-scoped bookmarks — do we reestablish bookmarks on relaunch so recents still work in MAS?\n- Exports (PDF/HTML/DOCX) that write outside Downloads or user-selected paths\n- Backup / auto-save paths writing to arbitrary locations\n- Any fs.writeFile / fs.writeFileSync outside known-good sandbox scopes\n- Any child_process / spawn / exec calls (shell access is not granted by default)\n- open-in-external-editor flows, 'Reveal in Finder' (should work via shell.showItemInFolder)\n- Global settings / config writes (should go through app.getPath('userData'))\n- Log file writes (electron-log should use a sandbox-safe path by default, verify)\n- Update check / download paths (already gated, but worth double-checking)\n- CLI-install flow (already gated correctly)\n\n**Acceptance**:\n1. Audit document listing every fs/shell/exec call and whether it is safe under sandbox\n2. Each unsafe path is either gated with isMASBuild() or wrapped to show a toast/error on failure\n3. About dialog shows a 'Sandboxed build' badge so the user can tell at a glance (separate from the existing MAS build: true/false line in the debug info)\n4. No silent failures: every file write under sandbox either succeeds or produces a user-visible error\n\n**Related**: Not a blocker on anything, but worth doing before the next MAS release since v1.0.1 had signing issues that masked whether feature parity was actually there.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-07T04:50:36.979058-07:00","updated_at":"2026-04-07T04:50:36.979058-07:00"} +{"_type":"issue","id":"markdown-reader-zi2","title":"New file/page should focus the editor (rich mode never focuses CodeMirror)","description":"Jacob: 'when I create a new page it should focus.' Root cause: the overridden showEditor in renderer.js focuses only in plain mode (tab.editorEl.focus()); in rich mode (default richEditorMode:true) it calls enterRichMode() but never easyMDE.codemirror.focus(), so Cmd+N / welcome-screen New File / sidebar inline-create leave keyboard focus outside the editor. Fix: focus the CodeMirror instance in the rich-mode branch of showEditor.","status":"in_progress","priority":1,"issue_type":"bug","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:15:16Z","created_by":"tmad4000","updated_at":"2026-07-10T19:15:24Z","started_at":"2026-07-10T19:15:24Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-0f9","title":"Audit app lag and spinning behavior","description":"Investigate current severe UI lag/spinning in OpenMarkdownReader. Check live process CPU/memory, logs, watch mode behavior, remote URL tabs, renderer/main hot paths, and patch any concrete regressions found.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-22T09:07:38Z","updated_at":"2026-05-22T09:14:57Z","closed_at":"2026-05-22T02:14:57Z","close_reason":"Found root recursive scan loop from second-instance dot path resolving to /; patched argument resolution, broad-root scan guards, and hidden-sidebar watcher behavior.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-l7u","title":"Cmd+F should refocus open find bar in edit mode","description":"When the in-file find bar is already open while editing, pressing Cmd+F again should keep find open and focus/select the query. It currently behaves like a toggle and can close or fail from the editor context.","acceptance_criteria":"Cmd+F opens find from edit mode; Cmd+F with find already open keeps it open, focuses/selects the query, and does not exit edit mode; Esc or close button still closes find.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-12T00:42:59Z","updated_at":"2026-05-12T00:44:04Z","closed_at":"2026-05-11T17:44:04Z","close_reason":"Fixed Cmd+F handling so Find opens or refocuses the find bar instead of toggling it closed. Added capture-phase shortcut handling for edit mode and regression coverage.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-b28","title":"Wire up electron-updater for non-MAS DMG auto-updates","description":"## Goal\nWire up `electron-updater` for the **non-MAS** DMG distribution so Jacob and other direct-download users automatically get new releases without manually downloading DMGs or re-building from source.\n\n## Current state (verified 2026-04-08)\n- `package.json` has **no `build.publish`** config\n- **`electron-updater` is not a dependency**\n- `main.js` never imports `autoUpdater`\n- Result: v1.0.4 users who installed from GitHub are stuck on v1.0.4 forever unless they manually re-download\n\n## Why this matters\n- Currently my workflow to get the latest code running is \"build locally, ditto into /Applications\". That's fine for one user. Not fine for anyone else.\n- The Local-Only MAS edition (markdown-reader-xwc) and MAS Standard get updates via Apple automatically. The non-MAS build is currently the odd one out with *no* update path at all.\n- The non-MAS edition is strategically the most important one for power users (it's where SFTP, shell integration, and future power features will live — see markdown-reader-571). Power users especially need fast update cadence.\n\n## Implementation\n\n### 1. Add dependency\n```bash\nnpm install electron-updater\n```\n**Dep version policy**: per CLAUDE.md, use a version at least one month old. Check npm before installing.\n\n### 2. Configure publishing in `package.json`\n```json\n\"build\": {\n \"publish\": {\n \"provider\": \"github\",\n \"owner\": \"tmad4000\",\n \"repo\": \"OpenMarkdownReader\",\n \"releaseType\": \"release\"\n }\n}\n```\n\n### 3. Wire updater into `main.js`\nGate on non-MAS build using the existing `isMASBuild()` helper — MAS updates are handled by Apple and calling `autoUpdater` from a MAS build will crash or no-op ugly:\n\n```javascript\nconst { autoUpdater } = require('electron-updater');\n\napp.whenReady().then(() =\u003e {\n // ... existing ready logic ...\n if (!isMASBuild()) {\n autoUpdater.checkForUpdatesAndNotify().catch(err =\u003e {\n console.warn('[auto-update] check failed:', err.message);\n });\n // Re-check every 6 hours for long-running instances\n setInterval(() =\u003e {\n autoUpdater.checkForUpdatesAndNotify().catch(() =\u003e {});\n }, 6 * 60 * 60 * 1000);\n }\n});\n```\n\n### 4. UI: \"Update available\" indicator\nPer global CLAUDE.md guidance (\"Always show when a new version is available\"), add a subtle indicator in the user menu / footer:\n- Listen for `autoUpdater.on('update-available', ...)` → set a flag in main, forward to renderer via IPC\n- Renderer shows a small dot next to the version number (already displayed per CLAUDE.md \"Version Display in User Menus\" rule)\n- Clicking the dot opens a \"Restart to update\" dialog backed by `autoUpdater.quitAndInstall()`\n- Listen for `autoUpdater.on('update-downloaded', ...)` → enable the restart option\n\n### 5. Release workflow change\n- electron-builder needs to publish `latest-mac.yml` alongside the DMG/zip in every GitHub release or the updater has nothing to check against\n- Change release command from `gh release upload` → `electron-builder --mac --publish always`\n- This requires `GH_TOKEN` env var in the shell doing the release (from 1Password or gh auth)\n- Update `CLAUDE.md` \"Releasing\" section with the new command\n\n### 6. Signing requirement\n- electron-updater on macOS **requires** signed + notarized builds to apply updates (unsigned apps get \"update failed: code signature\" errors)\n- This means going back to the notarized build flow (`APPLE_API_KEY` env vars) for every release — no more skip-notarize shortcuts for public releases\n- Local dev installs can still skip notarization since they bypass the updater\n\n## Acceptance criteria\n1. Fresh v1.0.N install from GitHub DMG auto-detects and installs v1.0.N+1 without manual intervention\n2. User sees \"Update available\" indicator before restart, not just a silent swap\n3. MAS builds don't crash or get confused — `isMASBuild()` gate prevents any updater code from firing\n4. Release script documented in CLAUDE.md and produces the `latest-mac.yml` file in the GitHub release\n5. `autoUpdater` errors don't break app startup (wrapped in try/catch, logged not thrown)\n\n## Edge cases\n- **First run after install**: avoid checking for updates immediately on first launch — wait a few minutes so the UI loads first\n- **Offline / no network**: updater should silently fail and not bother the user\n- **Code signing identity rotates**: the new build must be signed with the *same* identity or the updater refuses. Document this.\n- **Differential updates**: electron-updater supports delta patches but requires the previous build's signature. First few updates will be full downloads.\n\n## Out of scope\n- In-app update notes / changelog display (can be added later)\n- Nightly / pre-release channel (the alpha group on TestFlight covers pre-release testers for now)\n\n## Related\n- Discovered during 2026-04-08 session after manually installing v1.0.4 DMG and realizing there's no update path","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-09T05:33:13Z","updated_at":"2026-04-09T05:33:13Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-kfr","title":"Resolve TestFlight external review rejection for v1.0.4 build 1773489007","description":"**Status**: Both recent MAS builds were rejected for external TestFlight testing:\n- Build 1773489007 (v1.0.4) uploaded 2026-03-14, rejected 2026-03-17\n- Build 1773226755 (v1.0.4) uploaded 2026-03-11, rejected 2026-03-13\n\nInternal TestFlight works fine (IN_BETA_TESTING on the 'alpha' group). Only external review failed.\n\n**Rejection reason is NOT in the rejection emails** — Apple only puts it in the Resolution Center on App Store Connect. Emails just say 'visit the App Review page'. The API also doesn't expose the rejection text.\n\n**Action required from Jacob**: Open https://appstoreconnect.apple.com/apps/6758376669/testflight/ios, click the rejected build, read the App Review message in the Resolution Center, and paste the reason into this ticket.\n\n**Likely suspects** (to narrow down once we see the reason):\n- macOS 26.3 crash (fixed in 6d379bb on 2026-03-14 — upgrade Electron 40.1.0 → 41.0.2). The 1773489007 build was uploaded the same day as the fix commit, so it may or may not contain it.\n- Missing beta test notes or reviewer demo info (betaAppReviewDetails shows notes=null, demoAccountRequired=false, but reviewer might need extra context)\n- Sandbox entitlement issue\n- Helper app signing issue\n- Hardcoded paths\n\n**Blocks**: markdown-reader-xwc (Local-Only edition) — it makes no sense to submit a second MAS edition when we can't get the first through beta review.\n\n**Next step after cause identified**: bump to v1.0.5, rebuild with current main.js (which includes Electron 41.0.2, agent-native socket, Unix IPC fixes, and editor-per-tab improvements), upload via scripts/build-mas.sh --upload, resubmit for external review.","status":"in_progress","priority":1,"issue_type":"bug","created_at":"2026-04-08T00:04:24Z","updated_at":"2026-04-08T00:20:02Z","comments":[{"id":"39143fd5-9f14-4c52-9d91-29cbb114a766","issue_id":"markdown-reader-kfr","author":"jacobcole","text":"Resolved the rejection cause and resubmitted:\n\n**Rejection reason** (from Resolution Center): Guideline 2.1(a) — App Completeness. 'We were unable to review the app as it crashed on launch on Mac running macOS 26.3.' (Confirmed via Resolution Center on 2026-04-07; the email notification had no details.)\n\n**Root cause**: The rejected build 1773489007 was uploaded on 2026-03-14 at 04:54 PT. The Electron 40→41 fix for the macOS 26.3 crash was committed 18 minutes later at 05:12 PT (commit 6d379bb). The fix was never rebuilt + re-uploaded — it sat in source for ~3 weeks while Apple rejected the broken build on 2026-03-17 / 2026-03-18.\n\n**Resubmitted 2026-04-07**:\n- Build: v1.0.5 (1775607178)\n- Electron: 41.0.2 (fix confirmed in package.json)\n- Commit: 417356a on feature/daily-notes\n- Also includes: agent-native Unix socket, wikilink resolver, editor-per-tab, folder support, and 3 weeks of other improvements\n- Added to 'friendsext' external beta group\n- Submitted to Apple beta review, state: WAITING_FOR_REVIEW\n- Apple typically reviews within 24-48 hours\n\n**Process improvements committed to prevent repeat**:\n1. scripts/build-mas.sh now has a Step 0 version safeguard that aborts if package.json version matches the last uploaded build (with --auto-bump flag to auto-increment patch version)\n2. scripts/submit-mas-for-external-review.py automates the manual step of adding build to group and submitting for review (previously done by hand in the App Store Connect UI)\n\n**Next**: Monitor beta review state at https://appstoreconnect.apple.com/apps/6758376669/testflight/ios. Close ticket when Apple approves the build or if we need to iterate.","created_at":"2026-04-08T00:20:02Z"}],"dependency_count":0,"dependent_count":1,"comment_count":1} +{"_type":"issue","id":"markdown-reader-a4h","title":"Undo history is lost on mode toggle / tab switch / rich↔plain toggle","description":"**Problem**: Undo state is repeatedly wiped by normal UI actions. User types for 10 minutes, hits Escape to preview, goes back to edit → Cmd+Z does nothing.\n\n**Three places undo is lost** (found in renderer.js):\n\n1. **Edit → Preview → Edit (plain textarea mode)** — renderer.js:1212 'showEditor(content)' does 'editor.value = content' every time. Assigning .value to a textarea programmatically **resets the browser's native undo stack**. So any mode toggle clears undo.\n\n2. **Rich mode ↔ Plain mode toggle** — renderer.js:5597-5602 'destroyRichEditor()' calls 'easyMDE.toTextArea()', which tears down the entire CodeMirror instance. All undo history gone. The reverse direction pipes via 'easyMDE.value(editor.value)' (line 5611) which also starts a fresh history.\n\n3. **Tab switching** — likely same issue: returning to a tab re-runs 'showEditor(tab.content)' → textarea .value reassignment → undo wiped. Needs verification but the pattern is suspicious.\n\n**Why this matters now**: The proposed Escape-to-exit-edit-mode feature (markdown-reader-kq3) would make this 10x more frequent. Mis-tapping Escape shouldn't lose 20 minutes of undo.\n\n**Fix directions** (in order of effort):\n- **Cheap**: In plain mode, don't reassign 'editor.value' if the content hasn't actually changed from what the user last saved or what's currently in the textarea. Mode toggle becomes pure show/hide.\n- **Medium**: Persist **per-tab editor state** so that switching tabs (or modes) restores the textarea/CodeMirror instance rather than re-populating from content.\n- **Right answer**: One editor instance per tab, kept alive across mode/tab changes. Bigger refactor but it's the correct model — matches VS Code/Obsidian/any real editor.\n\n**Current escape hatch**: 'tab.originalContent' (renderer.js:1178) gives a 'revert all' via the Cancel button, but that's all-or-nothing — no granular undo.\n\n**Acceptance**: After typing, hitting Escape/preview toggle, switching tabs, or toggling rich/plain mode, Cmd+Z should still step back through all edits in the session.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-07T11:27:17Z","updated_at":"2026-04-07T22:56:11Z","closed_at":"2026-04-07T15:56:11Z","close_reason":"Implemented per-tab editor refactor. Each tab now owns its own textarea (tab.editorEl) and EasyMDE instance (tab.easyMDE), both lazy-created and kept alive across tab switches and preview toggles. Verified end-to-end via the new _debug-editor-state agent command: setting distinct content in two tabs and switching between them preserves each tab's CodeMirror state independently. Preview-toggle round-trip also preserves the editor instance (no destroy/recreate). Within-tab rich/plain mode toggle still loses undo on the OLD mode — that's a separate, smaller concern documented in the new follow-up.","dependency_count":0,"dependent_count":2,"comment_count":0} +{"_type":"issue","id":"markdown-reader-ie3","title":"Wikilink [[...]] not resolving even with project folder open","description":"**Reproduction**: File /Users/jacobcole/Documents/Main/2023-08-23.md contains [[Todos before BM]]. Project directory is open but the wikilink renders as raw [[...]] text even though a file named `Todos before BM.md` exists.\n\n**Earlier (incorrect) suspicion — RETRACTED**: Case sensitivity is NOT the issue. renderer.js already lowercases both sides of the lookup: index keys at lines 239, 242, and the lookup name at line 274. Ruled out on re-read.\n\n**Real root causes** (three bugs, all must be fixed):\n\n1. **Missing index rebuild on 3 of 5 cache-write sites.** `buildWikiLinkIndex()` was only called at the openDirectory prefetch (renderer.js:1753) and refreshSidebarForExternalMove (renderer.js:3305). These 3 other sites populated `allFilesCache` WITHOUT rebuilding the index:\n - renderer.js:1844 — renderRecentFilesTree fallback fetch\n - renderer.js:1975 — renderRecentFilesTimeline fallback fetch\n - renderer.js:4490 — showCommandPalette fallback fetch\n\n2. **Race condition on the happy path.** In openDirectory, the prefetch at renderer.js:1749 is async, but renderMarkdown → processWikiLinks (renderer.js:3913) is synchronous. If a tab was already open when the folder opened, the file rendered before the index existed, so `processWikiLinks` bailed out at the `size === 0` guard (renderer.js:264/291) and left the `[[...]]` verbatim in innerHTML.\n\n3. **No re-render after index builds.** Once `processWikiLinks` emitted the raw `[[...]]` into markdownBody.innerHTML, nothing invalidated that state when the index later finished loading.\n\n**Fix applied** (renderer.js):\n- Added a `setAllFilesCache(files)` helper (~line 261) that assigns the cache, calls `buildWikiLinkIndex()`, AND re-renders the active tab via `renderContent(tab.content, tab.fileName)` if it's a non-editing preview with visible markdownBody. This closes bugs #2 and #3 together.\n- Replaced all 5 happy-path `allFilesCache = files` assignments with `setAllFilesCache(files)`:\n - renderer.js:1781 (openDirectory prefetch .then)\n - renderer.js:1872 (renderRecentFilesTree fallback)\n - renderer.js:2003 (renderRecentFilesTimeline fallback)\n - renderer.js:3332 (refreshSidebarForExternalMove)\n - renderer.js:4517 (showCommandPalette fallback)\n- Removed the now-redundant explicit `buildWikiLinkIndex()` calls (old lines 1753, 3305).\n- Left reset/error paths alone (`allFilesCache = null` / `= []`) — those shouldn't trigger a rebuild.\n\n**Status**: Code change complete, `node --check renderer.js` passes. Ready to verify in app.\n\n**Acceptance**: Opening a folder with a tab already showing [[Todos before BM]] resolves the link to the matching file on first visible paint.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-04-07T11:23:39Z","updated_at":"2026-04-07T22:11:09Z","closed_at":"2026-04-07T15:11:09Z","close_reason":"Already fixed in commit fbed0e8 (wikilink resolver via setAllFilesCache helper). Verified in renderer.js — all 5 cache assignment sites now call setAllFilesCache which builds the index AND re-renders the active tab.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-xwc","title":"Ship 'OpenMarkdownReader Local-Only' as a second MAS edition","description":"**Goal**: Ship a second edition of OpenMarkdownReader on the Mac App Store aimed at enterprise users (Anthropic, banks, law firms, anyone with data-exfiltration policies). The killer positioning: the only markdown app on the Mac App Store that cannot leak your documents.\n\n**Product decisions** (finalized 2026-04-07):\n- **Name**: \"OpenMarkdownReader Local-Only\" (NOT \"Secure\" or \"Private\" — those would imply the standard edition isn't, which is a bad marketing signal)\n- **Distribution**: Mac App Store only (both editions live side-by-side on MAS)\n- **Standard edition**: keeps Share button, Report Issue, Noos feedback widget, auto-updater (and continues to ship as direct-download DMG/ZIP too)\n- **Local-Only edition**: MAS-only, sandboxed, ZERO network egress for document data\n\n**Two MAS listings from one codebase**:\n\n| | Standard | Local-Only |\n|---|---|---|\n| Distribution | MAS + direct DMG/ZIP | MAS only |\n| Bundle ID | `com.jacobcole.openmarkdownreader` | `com.jacobcole.openmarkdownreader.localonly` |\n| productName | OpenMarkdownReader | OpenMarkdownReader Local-Only |\n| Share-to-web button | ✅ | ❌ hidden |\n| Report Issue menu | ✅ | ❌ hidden |\n| Noos feedback widget | ✅ | ❌ not loaded |\n| Auto-updater | ✅ (direct build) / managed by MAS | managed by MAS |\n| `network.client` entitlement | ✅ | ❌ removed — sandbox physically blocks all outbound connections |\n| Icon | standard | variant (TBD — maybe subtle lock/house overlay) |\n\n**Current network egress paths that must be gated off in Local-Only build**:\n- `renderer.js:2776` — Share button POSTs document content to `https://globalbr.ai/api/files/anonymous`\n- `renderer.js:3116` — Report Issue modal POSTs to `https://globalbr.ai/api/nodes/anonymous-submit`\n- `vendor/noos-feedback.js` + `index.html:457` — Noos feedback widget (GET on open, POST on send)\n- Auto-updater (already gated via `isMASBuild()`)\n\n**Architecture** (decided):\n\nSingle codebase, three layers of enforcement:\n\n1. **Build-edition constant** (`build-edition.js`, generated at build time from `BUILD_EDITION` env var):\n ```js\n module.exports = {\n edition: 'standard' | 'local-only',\n hasCloudShare: boolean,\n hasReportIssue: boolean,\n hasNoosWidget: boolean,\n productName: string,\n bundleId: string,\n };\n ```\n Every network-feature call site checks this constant and hides/disables UI.\n\n2. **Build-time file exclusion** — electron-builder `files` pattern drops `vendor/noos-feedback.js` from local-only builds. Script tag in `index.html` becomes a 404 at runtime, so even if gating breaks, no code to execute.\n\n3. **Entitlement removal** — local-only `entitlements.mas.plist` removes `com.apple.security.network.client`. Apple's sandbox itself blocks every outbound connection. This makes \"local only\" auditable: a security researcher can verify it with `codesign -d --entitlements - OpenMarkdownReader\\ Local-Only.app`.\n\n**Build commands**:\n```bash\nnpm run build:mac # Standard universal DMG/ZIP (unchanged)\nnpm run build:mas # Standard edition on MAS (unchanged)\nnpm run build:mas-local-only # Local-Only edition on MAS (new)\n```\n\n**Acceptance criteria**:\n1. Both MAS editions share \u003e95% of source code; only divergence is the `BUILD_EDITION` constant, electron-builder config, and entitlements.\n2. `npm run build:mas-local-only` produces a MAS package with:\n - No `noos-feedback.js` in the bundle\n - No `network.client` entitlement (verifiable via `codesign -d --entitlements -`)\n - Share button hidden, Report Issue menu item hidden\n3. Static verification: `grep -r globalbr.ai` in the built app bundle finds nothing in the renderer code for the local-only edition.\n4. About dialog on Local-Only shows: \"OpenMarkdownReader Local-Only — Sandboxed, no network\". Standard About dialog is unchanged.\n5. Both editions can be installed simultaneously (different bundle IDs) and share no state.\n6. Marketing copy for Local-Only MAS listing emphasizes: \"No telemetry. No cloud sync. No share-to-web. Your documents never leave your Mac. Verified by Apple's sandbox — we physically cannot send your data anywhere.\"\n\n**Implementation plan** (when ready):\n1. Create `build-edition.js` generator script (similar to `scripts/generate-build-info.js`)\n2. Add `build-edition` import to `main.js` and `renderer.js`\n3. Gate all three network paths in `renderer.js` behind `buildEdition.hasCloudShare` etc.\n4. Add `package.json` build variant with `mac-local-only` config (different `files`, `mac.appId`, `productName`, `mas.entitlements`)\n5. Create `build/entitlements.mas.local-only.plist` (copy of current without `network.client`)\n6. Create `scripts/build-mas-local-only.sh` (variant of current `build-mas.sh`)\n7. Add \"Local-Only edition — Sandboxed, no network\" badge in About dialog\n8. Update README.md with both editions\n9. Create second App Store Connect listing for the new bundle ID\n10. Test: install both on same Mac, confirm no network calls from local-only via `tcpdump` / Little Snitch\n\n**Open questions** (remaining):\n- Should we ship Local-Only as the FIRST MAS release and hold Standard back until we have both? Or ship Standard first and add Local-Only later?\n- Icon variant design — subtle lock overlay? Different color? Or same icon?\n- Do we use a shared README or two separate App Store Connect descriptions?\n\n**Related tickets**:\n- markdown-reader-il6 (agent-native Unix socket — must work in both editions since it's local IPC)\n- markdown-reader-ztt (audit MAS sandbox-unsafe paths — informs gating)\n- markdown-reader-st8 (browsing history — must be local-only storage in both editions)","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-03T06:48:02Z","updated_at":"2026-04-07T23:53:06Z","dependencies":[{"issue_id":"markdown-reader-xwc","depends_on_id":"markdown-reader-kfr","type":"blocks","created_at":"2026-04-07T17:04:33Z","created_by":"auto-import","metadata":"{}"}],"comments":[{"id":"08728a4f-6b99-4208-b06b-3bb252e527c3","issue_id":"markdown-reader-xwc","author":"jacobcole","text":"Icon decision finalized 2026-04-07: slate/graphite gradient background (#475569 → #0F172A) with 'LOCAL' ribbon across the bottom. Assets committed: build/icon-local-only.{svg,png,icns} and build/icon-local-only-dev.{svg,png} (dev variant shows 'LOCAL • DEV' ribbon, DEV in orange to match existing dev icon convention). Candidates explored in build/icon-variants/: v1-green (too hobbyist), v2-slate-padlock (padlock invisible at small sizes), v3-blue-house (insufficient differentiation), v4-slate-ribbon (WINNER — slate says 'premium/enterprise', LOCAL ribbon stays readable down to 32px dock size). main.js:1943 updated to pick build/icon-local-only-dev.png as the dev dock icon when OMR_EDITION=local-only env var is set; this env var will eventually come from the BUILD_EDITION constant once the dual-edition system lands.","created_at":"2026-04-07T23:59:47Z"},{"id":"8cbed4d4-7dfc-4a11-9295-a041c9f74c18","issue_id":"markdown-reader-xwc","author":"jacobcole","text":"Blocked on markdown-reader-TBD (the TestFlight rejection ticket — will add dep once created). The Local-Only edition cannot be submitted until we can ship ANY edition through external beta review successfully. The Standard edition has been rejected twice for external testing (builds 1773226755 and 1773489007, both v1.0.4), reason unknown until Jacob reads the Resolution Center. Also: the Local-Only build itself does not exist yet — only icon assets and the implementation plan are committed. Actual code gating, entitlement variant, build script, and package.json variants are still pending per the 10-step implementation plan above.","created_at":"2026-04-08T00:04:29Z"}],"dependency_count":1,"dependent_count":1,"comment_count":2} +{"_type":"issue","id":"markdown-reader-il6","title":"Agent-native control: Unix socket + CLI commands for full programmatic control","status":"in_progress","priority":1,"issue_type":"epic","created_at":"2026-04-03T06:48:00Z","updated_at":"2026-04-03T07:39:09Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-7ol","title":"Bug: updateCommandPaletteSelection is not defined when opening Cmd+P","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-03-11T10:39:53Z","updated_at":"2026-03-11T10:43:42Z","closed_at":"2026-03-11T03:43:42Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-b90","title":"Fix Command-F input losing focus after first character","description":"Find box/search input currently drops focus after typing one character.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-27T01:25:19Z","updated_at":"2026-02-27T04:15:06Z","closed_at":"2026-02-26T20:15:06Z","close_reason":"Fixed find bar focus loss by preserving input focus during live match updates in editor search flow.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-i20","title":"Fix back button navigation to previous tab/history item","description":"Back button should navigate to previous tab/history entry reliably; currently not working as expected.","notes":"Reproduced regression by tracing tab switch flow: renderer.js has two switchToTab implementations, and the later EasyMDE override (active at runtime) did not call pushNavHistory(). As a result, tab switches stopped recording history, so Back could not navigate to prior tab/history entries. Fixed by restoring pushNavHistory(tabId, tab.filePath) in the EasyMDE switchToTab override before updateTabUI(). Targeted validation: rg confirmed pushNavHistory present in both switchToTab paths; node --check renderer.js passed.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-27T01:25:19Z","updated_at":"2026-02-27T04:15:06Z","closed_at":"2026-02-26T20:15:06Z","close_reason":"Fixed back/forward reliability by ensuring tab switches push consistent navigation history entries.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-2ww","title":"Detect and reconcile on-disk renames/moves","description":"If a file is renamed on disk outside the app, detect it and update open tabs/sidebar references without breaking state.","notes":"Implemented external rename/move reconciliation using inode-based detection in file watchers; emit file-path-changed and update renderer tab/sidebar references to prevent broken state. Added unit tests for rename and move detection in file-watch-utils.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-27T01:25:18Z","updated_at":"2026-02-27T01:47:20Z","closed_at":"2026-02-26T17:47:20Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-7lp","title":"Standardize rename UX and fix double-click rename bug","description":"Add right-click Rename in tab bar and left sidebar; make double-click rename reliable and consistent with VS Code behavior.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-27T01:25:18Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Standardized rename entry points by adding Rename actions in tab/sidebar context menus and wiring to rename flows.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-9a5","title":"Fix Command-Shift-S shortcut handling","description":"Cmd+Shift+S is currently not working; shortcut should trigger expected Save As / mapped action.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-27T01:25:18Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Restored Cmd+Shift+S handling via keyboard shortcut path to save-as flow.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-39u","title":"Live filesystem watch for left sidebar","description":"Left sidebar should watch filesystem changes and refresh live for add/remove/rename/move events.","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-02-27T01:25:17Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Added live sidebar filesystem refresh watcher that auto-reloads tree on external add/remove/rename changes.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-tw1","title":"Daily note opens directly in edit mode","description":"Creating a new daily note should immediately enter edit mode instead of preview/read mode.","notes":"Reproduced by tracing daily-note flow: createDailyNote() writes new file, then calls loadMarkdownFile() without forceEdit, so renderer opens in preview/read mode. Implemented fix in main.js: track newly created file and call loadMarkdownFile(win, filePath, { forceEdit: createdNewFile }). Existing daily notes still open in current mode; only newly created notes force edit mode. Verification: node --check main.js passed.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-02-27T01:25:16Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Daily note creation now opens newly created note directly in edit mode.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-cz3","title":"Fix publish error - handle 'File storage not configured' gracefully with helpful link","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-30T12:59:01Z","updated_at":"2026-01-30T13:06:20Z","closed_at":"2026-01-30T05:06:20Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-40u","title":"Improve wiki link path resolution (support folder paths)","description":"Wiki links with folder paths aren't resolving correctly.\n\n**Example that failed:**\n[[topics/Sussman_s_paper_on_controlled_hallucinations|Sussman's paper on controlled hallucinations]]\n\n**Expected behavior:**\n- Support [[folder/filename|display]] syntax\n- Match by relative path from folder root\n- Fall back to filename-only match if path doesn't match\n\n**Also add:**\n- Hover on opened folder path shows full path\n- Right-click on folder path to copy path","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-15T08:41:49Z","updated_at":"2026-01-15T08:46:59Z","closed_at":"2026-01-15T00:46:59Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-yqc","title":"Fix Publish button: CSP, icon direction, size","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-01-14T17:01:59Z","updated_at":"2026-01-14T17:09:55Z","closed_at":"2026-01-14T09:09:55Z","close_reason":"Fixed: CSP, icon direction, button size all resolved","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-va5","title":"Add one-click publish to noos (globalbr.ai)","description":"Add publish button that uploads current file to noos anonymously and copies shareable URL to clipboard","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-14T16:45:15Z","updated_at":"2026-01-14T16:56:24Z","closed_at":"2026-01-14T08:56:24Z","close_reason":"Implemented publish button that uploads to noos anonymous endpoint","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-8wt","title":"Default to edit mode when creating new file","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-28T08:51:34Z","updated_at":"2026-01-17T12:48:04Z","closed_at":"2026-01-17T04:48:04Z","close_reason":"Implemented in this session","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-fc1","title":"Command-F search not working in edit mode","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-27T03:13:52Z","updated_at":"2025-12-27T03:19:30Z","closed_at":"2025-12-26T19:19:30Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-7f6","title":"Preserve scroll position when switching between edit and preview modes","description":"When switching from preview to edit mode (or vice versa), the view jumps to the top. Should preserve scroll position using percentage-based or content-matching approach.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-27T03:11:50Z","updated_at":"2025-12-27T03:21:43Z","closed_at":"2025-12-26T19:21:43Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-1i5","title":"Research Proof by Every as related project","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-28T01:41:00Z","updated_at":"2026-05-28T01:43:51Z","closed_at":"2026-05-27T18:43:51Z","close_reason":"Added Proof research note, linked it from requirements/handoff docs, and updated web viewer ticket notes.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-c45","title":"Watch remote URL tabs for changes","description":"Remote URL tabs opened via Cmd+P are currently one-time snapshots. Add watch-mode support for remote URL sources by polling while listening mode is enabled, using ETag/Last-Modified when available and falling back to content hashing. Refresh the tab when the remote content changes, preserving local unsaved edits/conflict behavior.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T08:58:44Z","updated_at":"2026-05-22T08:58:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-jyh","title":"Open remote files and folders over SFTP","description":"Add a real remote filesystem backend for SSH-accessible machines. Support sftp://host/path/file.md and remote folders using hosts from ~/.ssh/config where possible, remote stat/read/list/write operations, sidebar browsing, and polling-based watch support for opened remote files. This builds on markdown-reader-571 and should keep MAS/local-only constraints in mind.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T08:58:44Z","updated_at":"2026-05-22T08:58:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-pcb","title":"Open remote markdown URLs from Quick Open","description":"Cmd+P currently detects http/https URLs but sends them to shell.openExternal. Implement remote text/markdown URL fetching in main process and open fetched content in an app tab, keeping document links external.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-22T08:51:34Z","updated_at":"2026-05-22T08:56:01Z","closed_at":"2026-05-22T01:56:01Z","close_reason":"Implemented Cmd+P remote text/markdown URL opening inside the app","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-2wa","title":"Refresh Cmd+P file cache when project files change externally","description":"Cmd+P uses allFilesCache, which is populated on folder open / first palette use. External filesystem changes detected by the sidebar live watcher do not refresh that cache, so newly-created files may not appear in command palette search until the folder is reopened or another cache reset path runs. Acceptance: when the project file signature changes, refresh allFilesCache, rebuild wikilinks, and update Cmd+P results if the palette is open.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-08T04:04:33Z","updated_at":"2026-05-08T04:06:10Z","closed_at":"2026-05-07T21:06:10Z","close_reason":"Fixed: sidebar live refresh now refreshes allFilesCache from the recursive filesystem snapshot, rebuilds wikilinks, and updates Cmd+P results when open.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-lrp","title":"Keep expanded sidebar folders in sync with external filesystem changes","description":"The sidebar live watcher detects recursive filesystem changes but only reloads the root directory tree. If a nested folder is already expanded, its child list can go stale or disappear after external files are added/removed. Acceptance: before re-rendering after an external refresh, reload children for currently-expanded folders so visible nested contents stay current.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-05-08T04:04:33Z","updated_at":"2026-05-08T04:06:10Z","closed_at":"2026-05-07T21:06:10Z","close_reason":"Fixed: sidebar live refresh now reloads children for folders that are currently expanded before re-rendering the tree.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-6ln","title":"Add backlinks panel: show all files linking to the current file","description":"Obsidian-style backlinks. When viewing a markdown file, show a panel listing every other file in the current folder (or workspace) that links to it via wiki-link `[[name]]` or relative markdown link `[label](path/to/file.md)`.\n\n**Why:** Makes manifest files (like the new active-projects dashboard) two-way navigable. Today `active-projects.md` links to `sideboard/README.md`, but from inside the README there's no surfaced indication that the manifest references it. Backlinks close that loop and turn any markdown set into a navigable graph.\n\n**Scope (v1):**\n- Index links across the loaded folder/workspace (not just open tabs)\n- Resolve both `[[name]]` wiki-links and `[label](path)` markdown links to absolute paths\n- Show a collapsible 'Linked from' panel below the rendered content (or in the sidebar — UX TBD)\n- Click a backlink → opens the source file\n- Update incrementally as files change (watch mode already exists)\n- Handle the existing `Wiki link name conflicts detected` case\n\n**Out of scope (v1):**\n- Cross-folder/global index\n- Block-level / heading-level backlinks (Obsidian-style `#section`)\n- Unlinked mentions (text-match without an actual link)\n\n**First user:** the Active Projects Dashboard build (dashboard profile). Manifest → README is one-way today; backlinks make the dashboard appear in each project's README without anyone editing it.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-05T05:43:24Z","updated_at":"2026-05-05T05:43:24Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-wlp","title":"Render YAML frontmatter as collapsed metadata block instead of markdown","description":"YAML frontmatter at the top of a markdown file is currently passed directly to marked.parse(), which mangles it: single tildes in paths like ~/Downloads/... trigger strikethrough, the --- delimiters become horizontal rules / setext headings, and wiki links mixed with YAML punctuation create bizarre inline wrapping. Repro: /Users/jacobcole/code/RealtimeMeetingOutline/wiki/meta/ideaflow-slack-export.md. Fix: extract leading YAML frontmatter and render it as a collapsed \u003cdetails\u003e block with syntax-highlighted YAML, then render the body as markdown normally.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-16T06:02:28Z","updated_at":"2026-04-16T06:21:19Z","closed_at":"2026-04-15T23:21:19Z","close_reason":"Fixed: extract YAML frontmatter into collapsed \u003cdetails\u003e block, render remainder as markdown. Repro file now renders correctly instead of showing mangled strikethrough/horizontal-rule/wiki-link soup.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-1ui","title":"Quick access to reveal file in Finder / open containing folder","description":"## Implemented (2026-04-10)\nAdded three access points for revealing the active file's parent folder:\n\n1. **File menu**: File \u003e Reveal in Finder (⇧⌘R)\n2. **Command palette**: \"Reveal in Finder\" and \"Open Containing Folder\" commands (type \u003e to see commands)\n3. **Existing**: sidebar right-click already had \"Reveal in Finder\" and \"Open in Finder\"\n\n\"Reveal in Finder\" selects the file in its parent folder (shell.showItemInFolder).\n\"Open Containing Folder\" opens the parent directory directly (shell.openPath).\n\nKeyboard shortcut: ⇧⌘R (matches VS Code convention).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-10T11:12:50Z","updated_at":"2026-04-10T11:12:56Z","closed_at":"2026-04-10T04:12:56Z","close_reason":"Implemented in commit 9ff7bd9","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-4y1","title":"Auto-save new/untitled files to daily note or personal wiki folder","description":"## Goal\nWhen the user creates a new tab and starts typing (scratchpad use case), auto-save the content to a persistent location instead of losing it when the app closes. Makes OpenMarkdownReader useful as a quick-capture scratchpad with built-in persistence.\n\n## Proposed behavior\n- New untitled tabs auto-save to a configurable folder (default: the daily-notes folder if set, or ~/Documents/OpenMarkdownReader/)\n- Filename auto-generated: timestamp-based like `2026-04-09-scratch-1.md` or integrated into the daily note as an appended section\n- Setting: \"Auto-save new files\" (default: ON)\n- Setting: \"Auto-save location\" — choices:\n - **Daily note** (append to today's daily note file, e.g. ~/memory/daily/2026-04-09.md) — best for scratchpad/quick capture\n - **Wiki folder** (save as individual files in a configured folder) — best for growing a personal wiki\n - **Ask each time** (prompt for save location on first auto-save)\n\n## Why this matters\nJacob uses OpenMarkdownReader as a scratchpad — opens it, starts typing quick notes, then closes. Right now that content is lost if he forgets to Cmd+S and pick a location. With auto-save-to-daily-note, every scratchpad session automatically ends up in his daily note (~/memory/daily/) where it's searchable and persistent.\n\n## Integration with existing features\n- The app already has `config.dailyNotesFolder` and a daily-note command (`daily-note` agent command)\n- Auto-save can reuse the daily note path resolution logic\n- The existing auto-save feature (`config.autoSave`) saves edits to EXISTING files — this feature is about saving NEW/untitled files to a default location\n\n## Implementation sketch\n1. When a new tab is created and the user starts typing, start a debounced auto-save timer (e.g., 3 seconds after last keystroke)\n2. On first auto-save trigger:\n - If mode is \"daily note\": append content under a `## Scratch` or `## Notes` heading in today's daily note\n - If mode is \"wiki folder\": create a new file with timestamp name\n - If mode is \"ask\": show save dialog\n3. Subsequent edits in the same tab auto-save to the same location (like existing autoSave behavior)\n4. Tab title updates to reflect the saved filename once persisted\n\n## Edge cases\n- Multiple untitled tabs: each gets its own scratch entry or file\n- Daily note doesn't exist yet: create it with standard daily note template\n- App crashes before auto-save: accept data loss (same as any editor)\n- Large paste operations: don't auto-save mid-paste, wait for debounce\n\n## Settings UI\nAdd to Settings menu:\n- [x] Auto-save new files (checkbox, default ON)\n- Location: [Daily note | Wiki folder | Ask each time] (dropdown)\n- Wiki folder path: [...] (folder picker, only shown when \"Wiki folder\" selected)","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-10T08:39:46Z","updated_at":"2026-04-10T08:39:46Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-2yb","title":"JSONL files always render in dark mode regardless of theme setting","description":"## Symptom\nOpening a .jsonl file in OpenMarkdownReader always displays with a dark background/theme, even when the app is set to light mode or system theme (and system is in light mode).\n\n## Likely causes\n- JSONL files hit the syntax-highlighted code path (via highlight.js) which may have its own theme stylesheet that doesn't respect the app's light/dark toggle\n- The app loads both `vendor/github.min.css` (light) and `vendor/github-dark.min.css` (dark) for highlight.js — the wrong one may be active for non-markdown files\n- JSON/JSONL content is likely wrapped in a `\u003cpre\u003e\u003ccode\u003e` block where the highlight.js theme overrides the app's CSS variables\n- The theme switching logic in renderer.js may only toggle markdown-related styles, not the highlight.js code theme\n\n## Investigation checklist\n- [ ] Open a .jsonl file in light mode, inspect the `\u003cpre\u003e\u003ccode\u003e` element — which highlight.js stylesheet is active?\n- [ ] Search renderer.js for theme switching logic — does it swap the highlight.js CSS file?\n- [ ] Check if .json files have the same issue (same rendering path)\n- [ ] Check styles.css for any `.hljs` overrides that force dark backgrounds\n\n## Fix (likely)\nSwap the highlight.js theme stylesheet when the app theme changes:\n- Light mode: load `vendor/github.min.css`\n- Dark mode: load `vendor/github-dark.min.css`\nOr use CSS variables to override `.hljs` background/foreground to match the app theme.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-09T20:11:04Z","updated_at":"2026-04-10T08:39:46Z","closed_at":"2026-04-10T01:39:46Z","close_reason":"Fixed in commit 91a08be — replaced all hardcoded dark colors with CSS variables","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-g9e","title":"Create product homepage highlighting OpenMarkdownReader differentiators","description":"Build a homepage / landing page for OpenMarkdownReader that explains why someone should use it instead of other markdown apps.\n\nKey differentiators to cover:\n- Open arbitrary markdown/text files directly, not just a managed vault\n- Strong local-first workflow\n- Auto-save / low-friction editing\n- Fast preview + editor workflow\n- Obsidian compatibility where relevant (for example wikilinks), without requiring an Obsidian-only workflow\n- Other differentiators discovered in the app during implementation should be surfaced too\n\nPossible scope:\n- A simple static marketing page in-repo is fine for v1\n- Should be easy to host later\n- Should include clear headline, supporting sections, screenshots/placeholders if available, and a concise feature comparison / positioning angle\n\nAcceptance ideas:\n1. A homepage exists in the repo with a clear entrypoint.\n2. Messaging explains the product in plain language and names the key differentiators above.\n3. The page works on desktop and mobile.\n4. The implementation path is documented enough that it can be hosted/deployed later.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-09T05:04:23Z","updated_at":"2026-04-09T05:12:21Z","closed_at":"2026-04-08T22:12:21Z","close_reason":"Implemented a standalone static homepage under `site/` with clear product positioning, plus alternative concepts under `site/alternatives/claude/` and `site/alternatives/nash/`. Messaging covers arbitrary file support, local-first workflow, low-friction editing/auto-save, fast preview/edit flow, and Obsidian compatibility without vault lock-in.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-lc6","title":"File-tree labels overflow right edge of sidebar (esp. sample Obsidian vault)","description":"## Symptom\nLong filenames — especially in sample Obsidian Vault files — overflow past the right edge of the left sidebar instead of being truncated or wrapping.\n\n## Repro (needs confirmation)\n1. Open the bundled sample Obsidian vault\n2. Notice one or more file-tree entries whose title visibly bleeds past the sidebar's right border\n3. Probably worse when the sidebar is at default width and worse on files deep in a nested folder (indent eats horizontal space)\n\n## Suspected cause\nPossibly one or more of:\n- Missing/insufficient `overflow: hidden` or `text-overflow: ellipsis` on `.file-name` / tree-node label CSS\n- A flex layout where the label has `flex-shrink: 0` or `min-width` blocking truncation\n- Wiki-link rendering extension recently added (commit `207b6c4`) — worth checking whether it changed tree rendering too, or only document rendering\n- Obsidian titles with spaces and unicode may be computed-width differently than ASCII-only\n\n## Investigation checklist\n- [ ] Open sample vault, screenshot the overflow in both collapsed and expanded states\n- [ ] Inspect offending node in DevTools; note computed `width`, `overflow`, `text-overflow`, `flex` on each ancestor up to the sidebar container\n- [ ] Check styles.css rules for `.file-name`, `.file-tree-item`, `.file-tree-label`, etc.\n- [ ] Verify the same filename in a non-sample folder — is it Obsidian-specific or any long name?\n- [ ] Test edge cases: emoji in name, CJK characters, very long unbroken strings (no spaces)\n\n## Fix (likely)\nAdd the standard text-truncation pattern to the label element:\n```css\n.file-tree-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0; /* crucial: allows flex children to shrink below content size */\n}\n```\nPlus ensure the parent flex row has `min-width: 0` too (common flex gotcha).\n\n## Bonus\nOnce truncation works, add a tooltip (`title` attribute or custom) showing the full filename on hover so users can still read long names.","notes":"Claimed for implementation. Plan: fix sidebar row flex/truncation so long file/folder labels ellipsize within the sidebar and keep full path/name available on hover.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-04-09T04:58:38Z","updated_at":"2026-04-09T05:03:15Z","closed_at":"2026-04-08T22:03:15Z","close_reason":"Fixed sidebar tree row truncation by giving rows and labels proper flex shrink/min-width behavior, adding explicit label elements, and preserving full path/name tooltips through render and rename flows.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-571","title":"Open folders on remote SSH hosts (SFTP-backed browsing/editing)","description":"## Goal\nLet the user open a folder on a remote machine they're already SSH-connected to (e.g. `hostmyapple`, `macincloud`, `noos-prod`) and browse/read markdown files as if it were a local folder.\n\n## Motivation\nJacob frequently SSHs into Mac mini (hostmyapple), Hetzner box (jcortex), and others — and often wants to read markdown notes or READMEs living on those boxes without scp'ing them down first.\n\n## Feasibility: Yes\nSeveral viable approaches, in order of preference:\n\n### Option A — SFTP via `ssh2-sftp-client` (RECOMMENDED)\n- npm: `ssh2-sftp-client` (wraps `ssh2`, pure JS with optional native crypto). Both are well-maintained.\n- Parses `~/.ssh/config` via `ssh-config` package → lets user pick an existing Host alias (`hostmyapple`, `jcortex`, etc.) instead of retyping creds.\n- Uses existing SSH keys — no password entry for key-based hosts.\n- New IPC surface in main.js: `remote-fs:connect`, `remote-fs:list`, `remote-fs:read`, `remote-fs:stat`, `remote-fs:write` (for edit mode).\n- File tree builds an in-memory `fileTree` just like local, but every node carries a `remoteId`.\n- Renderer treats remote paths as a new scheme, e.g. `sftp://hostmyapple/Users/Jacob/notes/foo.md`.\n- Cache small files locally (`~/Library/Application Support/OpenMarkdownReader/remote-cache/\u003chost\u003e/`) for offline re-open + diff.\n\n### Option B — sshfs/macFUSE mount\n- User mounts remote dir via macFUSE + sshfs; app just opens the mount point as a normal local folder.\n- Zero code in OpenMarkdownReader, but requires user to install macFUSE (kext/system extension, macOS is actively hostile to this).\n- Not a good default, but document as a workaround.\n\n### Option C — Remote agent (VS Code style)\n- Ship a tiny companion binary to the remote host, speak a custom protocol over SSH stdio.\n- Overkill for a markdown reader. Skip.\n\n## Proposed UX\n- **File → Open Remote Folder…** menu item (new)\n- Dialog shows hosts parsed from `~/.ssh/config`, plus a \"Custom…\" row\n- After picking host, prompt for path (or show remote home dir browser)\n- Opened remote folder appears in the sidebar with a small 🌐 or hostname badge\n- Titlebar shows `hostmyapple:~/notes` so it's always clear which machine you're reading from\n- Recent Remote Folders section in File menu (mirror of Recent Folders)\n\n## Edge cases to consider\n- **Edit mode + write-back**: save over SFTP, show spinner in tab, revert on failure\n- **Large folders**: lazy-load subtrees instead of walking entire tree (unlike local mode)\n- **File watching**: no easy SFTP notify; poll `mtime` on currently-open files every N seconds, or just refresh-on-focus\n- **Wiki links \u0026 cross-file navigation**: all resolves must stay within the same remote root\n- **Disconnects**: detect, show \"reconnect\" toast, queue writes or fail them\n- **MAS sandbox**: SFTP will likely NOT work under App Sandbox (outbound network + arbitrary file access). Feature should be gated to the non-MAS / \"Local-Only\" edition, OR make it Pro/non-MAS only. Coordinate with `markdown-reader-xwc` (Local-Only MAS edition).\n- **Security**: only read from `~/.ssh/config` + `~/.ssh/known_hosts`; never prompt for or store passwords in plaintext; rely on key agent (ssh-agent) where possible.\n\n## Out of scope for v1\n- Real-time collab on remote files\n- Remote terminal inside the app\n- Writing back to remote via git\n\n## Acceptance criteria\n1. \"File → Open Remote Folder…\" works against `hostmyapple`, showing markdown files in sidebar\n2. Clicking a file opens it read-only in a new tab with correct rendering (including wiki links and images, at least for those inside the same remote root)\n3. Edit mode saves back to the remote host and the tab's dirty indicator clears on success\n4. Disconnecting/reconnecting doesn't crash the renderer (see existing dead-renderer guards)\n5. Works against at least one non-Mac remote (Linux box like jcortex) to prove portability\n\n## Related\n- Blocks / interacts with: `markdown-reader-xwc` (Local-Only MAS edition) — remote support must live in the non-sandboxed build","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-09T04:46:39Z","updated_at":"2026-04-09T04:46:39Z","dependencies":[{"issue_id":"markdown-reader-571","depends_on_id":"markdown-reader-xwc","type":"blocks","created_at":"2026-04-08T21:46:49Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-hjc","title":"More aggressive, visible build number — increment per build, surface in version label","description":"**Problem**: Two builds of the same commit get the SAME build number, because scripts/generate-build-info.js currently sets buildNumber = 'git rev-list --count HEAD' (commit count, not build count). Worse, the build number is hidden inside the About dialog — the user-facing version label just says 'v1.0.4', so the user can't tell at a glance whether they're running an old install vs a fresh build. This bit us today: an install from Dec 26 2025 and a working-tree-with-uncommitted-fix both display as v1.0.4.\n\n**Goal**:\n1. **Per-build increment** — every invocation of generate-build-info.js bumps the build number, even on the same commit. Current 'git rev-list --count HEAD' approach is too coarse.\n2. **Visible in the version label**, not just the About modal. Render as something like 'v1.0.4.128' or 'v1.0.4 (b128)' wherever the version is shown to the user (status bar, window title, sidebar footer, tab tooltips).\n3. **Git hash stays** but as secondary info — the build number is the primary 'are you on the latest?' signal.\n\n**Implementation options for the increment**:\n- **A. Persistent counter in build-info.json**: read existing buildNumber, increment by 1, write back. Simple, monotonic. Risk: counter file conflicts in CI / multiple machines. Mitigation: store on a server-side gitignored file or accept per-machine drift.\n- **B. Epoch seconds since v1.0.0 release**: like the MAS build does (date +%s). Always unique, always increasing, machine-independent. Less human-friendly (huge numbers).\n- **C. Combined**: 'gitCount + .build N' where N is per-machine, e.g., '128.7' meaning 'commit 128, 7th local build of that commit'.\n\n**Recommendation**: Option A for the local file, Option B for MAS (already done). Track the counter in build-info.json and gitignore it.\n\n**Display format**: Render as 'v1.0.4.128' in user-visible labels (status bar, sidebar footer, tab tooltips). Apple constraint: CFBundleVersion is capped at 3 dot-separated integers, so we keep package.json version at '1.0.4' but the display in the JS UI can include the build number as a 4th segment. CFBundleVersion in Info.plist can be set to the build number itself for MAS uniqueness (which is already done).\n\n**Where to surface the new label**:\n- Window title (e.g. 'OpenMarkdownReader v1.0.4.128')\n- Status bar (already shows nothing? check)\n- Sidebar footer (per CLAUDE.md guidance)\n- About dialog (already shows it inside)\n\n**Related**: \n- Closed ticket markdown-reader-g8f covers 'auto-increment build number' but it's clearly insufficient for this use case\n- markdown-reader-7a5 (closed) is the 'update available' indicator — both should agree on what 'latest version' means\n- markdown-reader-jbx (closed) is the manual update check menu\n\n**Acceptance**:\n1. Two consecutive 'npm run build:mac' commands on the same commit produce two different build numbers\n2. The version label visible to the user without opening About includes the build number\n3. Easy to compare two installs at a glance ('I'm on .128, you're on .131')","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T12:57:42Z","updated_at":"2026-04-07T22:15:32Z","closed_at":"2026-04-07T15:15:32Z","close_reason":"Implemented Option A from ticket: scripts/generate-build-info.js now reads previous buildNumber from build-info.json and uses max(gitCount, previous+1), so each invocation strictly increments. Also made the dev-badge in the titlebar visible on packaged builds (subtle gray pill showing 'b\u003cn\u003e'), giving every install a glance-able build number without opening About. Verified: two consecutive runs produced 130 → 131 on the same commit.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-qcz","title":"Smart dev watcher: renderer reload vs full app restart","description":"**Goal**: Make the dev iteration loop dramatically faster by differentiating which source files changed.\n\n**Today**: main.js:3332-3353 watches all source files and unconditionally fires 'source-code-changed' which triggers a full app.relaunch(). That's slow (~3-5s) and loses BrowserWindow state, sidebar collapse state, scroll position, etc.\n\n**Proposal**:\n- main.js / preload.js / build-info.json change → full app.relaunch() (must — main process is stale)\n- renderer.js / index.html / styles.css / vendor/* change → webContents.reload() per window (much faster, preserves BrowserWindow + main state)\n\n**Implementation sketch** (main.js:3332-3353):\n1. Group sourceFiles into 'mainProcessFiles' and 'rendererFiles'\n2. fs.watch callback inspects filename, sends either 'source-code-changed' (existing, full restart) or 'renderer-changed' (new event, soft reload)\n3. Renderer 'renderer-changed' handler shows the existing pulsing button but with text 'Reload' instead of 'Restart' and triggers webContents.reload() via a new IPC handler\n4. Main process IPC handler 'reload-renderer' calls win.webContents.reload() on focused window (or all windows)\n\n**Acceptance**:\n- Editing only renderer.js shows 'Reload' button → click reloads in \u003c500ms, preserves window\n- Editing main.js shows 'Restart' button → click full restarts as today\n- Toast confirms which mode fired\n\n**Related**: markdown-reader-788 (closed) shipped the basic restart button this builds on.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T11:56:23Z","updated_at":"2026-04-07T11:57:56Z","closed_at":"2026-04-07T04:57:56Z","close_reason":"Implemented in working tree (not yet committed). Smart dev watcher: main.js:3332-3380. Restart accelerator: main.js:1006-1013. DEV badge tooltip: renderer.js:6421-6448. New IPC: preload.js, main.js reload-renderer handler. User to review + commit.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-ztt","title":"Audit MAS build for sandbox-unsafe code paths + surface silent failures","description":"**Context**: MAS build (markdown-reader-il6 uses isMASBuild() gating) runs inside Apple's sandbox with entitlements: app-sandbox, files.user-selected.read-write, files.downloads.read-write, network.client. Anything writing outside those scopes silently fails in MAS but works fine in the notarized build.\n\n**Goal**: Audit renderer.js and main.js for file-system, shell, and IPC operations that could silently fail under sandbox, and either (a) gate them off with isMASBuild() checks or (b) surface a clear error toast to the user when they fail.\n\n**Suspects to review**:\n- Recent files persistence / security-scoped bookmarks — do we reestablish bookmarks on relaunch so recents still work in MAS?\n- Exports (PDF/HTML/DOCX) that write outside Downloads or user-selected paths\n- Backup / auto-save paths writing to arbitrary locations\n- Any fs.writeFile / fs.writeFileSync outside known-good sandbox scopes\n- Any child_process / spawn / exec calls (shell access is not granted by default)\n- open-in-external-editor flows, 'Reveal in Finder' (should work via shell.showItemInFolder)\n- Global settings / config writes (should go through app.getPath('userData'))\n- Log file writes (electron-log should use a sandbox-safe path by default, verify)\n- Update check / download paths (already gated, but worth double-checking)\n- CLI-install flow (already gated correctly)\n\n**Acceptance**:\n1. Audit document listing every fs/shell/exec call and whether it is safe under sandbox\n2. Each unsafe path is either gated with isMASBuild() or wrapped to show a toast/error on failure\n3. About dialog shows a 'Sandboxed build' badge so the user can tell at a glance (separate from the existing MAS build: true/false line in the debug info)\n4. No silent failures: every file write under sandbox either succeeds or produces a user-visible error\n\n**Related**: Not a blocker on anything, but worth doing before the next MAS release since v1.0.1 had signing issues that masked whether feature parity was actually there.","status":"open","priority":2,"issue_type":"task","created_at":"2026-04-07T11:50:37Z","updated_at":"2026-04-07T11:50:37Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-kq3","title":"Escape key to exit edit mode (auto-save or prompt)","description":"Currently Escape doesn't leave edit mode. Proposal: Escape switches from edit → preview mode.\n\n**Options to consider:**\n1. **Auto-save + switch (recommended)**: Escape silently saves any pending changes and switches to preview. Clean, no dialogs, matches Obsidian's Ctrl+E toggle feel. Relies on having autosave or a synchronous save-on-toggle.\n2. **Prompt on unsaved**: Escape shows 'Save changes before exiting edit mode?' Save / Discard / Cancel. More explicit but friction.\n3. **Toggle only (no save)**: Escape switches mode but leaves the unsaved state as-is — the tab shows the blue dot. Safest, least decision, matches current Cmd+S ergonomics.\n\n**Recommendation**: Option 1 if autosave is reliable; Option 3 otherwise. Avoid option 2 unless the app regularly loses work.\n\n**Also consider**: What if user is in a modal/command palette/search bar when Escape is pressed? Those already consume Escape, so this should only fire when the editor has focus and no overlay is open.\n\n**Reference**: Obsidian uses Ctrl+E to toggle; VS Code has no edit/preview split; Typora auto-saves.","notes":"Claimed for implementation. Plan: Escape exits edit mode when the editor has focus and no overlay is open, preserving unsaved state rather than reverting or silently saving.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T11:23:47Z","updated_at":"2026-04-09T05:03:15Z","closed_at":"2026-04-08T22:03:15Z","close_reason":"Implemented Escape-to-preview behavior for active editor focus. Escape now exits edit mode without forcing a revert or silent save, preserving dirty state and using the same preview transition path as the explicit toggle.","dependencies":[{"issue_id":"markdown-reader-kq3","depends_on_id":"markdown-reader-a4h","type":"blocks","created_at":"2026-04-07T04:28:24Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-7qf","title":"Open folder as project: Cmd+P folder results + sidebar context menu","description":"Two related UX improvements for opening folders as the workspace root:\n\n1) **Cmd+P folder results** — When Cmd+P search matches a folder (not just a file), show the folder in results. Selecting a folder opens it as the active project/workspace root (same as File → Open Folder). Use a visual distinction (folder icon + 'Open folder' hint) so it's clear it's not a file.\n\n2) **Sidebar right-click → Open as project** — Right-clicking a folder in the left sidebar exposes actions to open that folder as its own workspace root. Options to consider:\n - 'Open Folder in New Window' (primary, VS Code-style, non-destructive — recommended default)\n - 'Open Folder Here' (replaces current workspace, with confirmation if there are unsaved tabs)\n - (Deferred) 'Add Folder to Workspace' — multi-root workspaces, larger refactor\n\n**Recommendation**: Ship 'Open in New Window' first as the safer/clearer option, matching VS Code. Skip multi-root workspaces for now — it's a significant refactor and most users get what they want from a new window.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-04-07T11:17:51Z","updated_at":"2026-04-07T23:00:48Z","closed_at":"2026-04-07T16:00:48Z","close_reason":"Implemented both parts:\n1. Sidebar right-click → 'Open in New Window' menu item added to both folder context menus in main.js (show-folder-context-menu and show-sidebar-folder-item-context-menu).\n2. Cmd+P shows folders: getAllFilesRecursive now optionally includes directories (gated behind opts.includeDirs), and the renderer's get-all-files-recursive IPC handler enables it. Folder items in Cmd+P show a 'Folder' badge + 📂 icon and are routed to a new openFolderInNewWindow IPC method that calls createWindow(folderPath).\n3. Bonus: 'omr --cmd open /path --new-window' agent command flag for headless testing.\nVerified end-to-end: passing newWindow:true creates a second browser window with the folder as its sidebar root.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-st8","title":"Add browsing/navigation history feature","status":"open","priority":2,"issue_type":"feature","created_at":"2026-04-03T06:48:02Z","updated_at":"2026-04-03T06:48:02Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-msv","title":"Web-based markdown viewer — paste URL or upload file to render","description":"A hosted web version of OpenMarkdownReader where anyone can paste a markdown URL or upload a file and view it rendered nicely, no app install needed. Consider integrating with noos (knowledge graph) for saving/linking notes.","notes":"2026-05-27 Proof by Every research added at research/proof-by-every.md. Default v1 should be read-only publish plus raw/JSON agent endpoints; defer comments/suggestions and realtime collaboration as explicit later product choices.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-03-23T22:51:35Z","updated_at":"2026-05-28T01:43:29Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-r12","title":"Add collapse-all feature for sidebar/outline","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-03-23T22:35:23Z","updated_at":"2026-04-07T22:13:17Z","closed_at":"2026-04-07T15:13:17Z","close_reason":"Added Collapse All button to sidebar header. Clicking it clears expandedFolders and re-renders the file tree. Only acts when in tree view mode (no-op for recent/timeline modes which don't have folder state).","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-d12","title":"Support tilde (~) expansion in Cmd+P open paths","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-23T22:32:13Z","updated_at":"2026-04-07T22:11:52Z","closed_at":"2026-04-07T15:11:52Z","close_reason":"Fixed: open-file-by-path IPC handler now expands ~/path to home directory. Single change in main.js handles all 18 callers (Cmd+P, sidebar, recent files, wikilinks, etc.).","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-0gz","title":"Noos bot: post-restart task queue","description":"The Noos Slack bot (running as Claude Code CLI inside Docker on Lightsail) can now self-restart via exit(1). But it can't queue a follow-up command to run after restart. Implement a startup hook: before restarting, write a pending task to a file (e.g. /app/.pending-task.json), and on boot check for it and execute. This enables the bot to modify its own code, restart, and verify the change worked — all autonomously.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-03-17T13:11:52Z","updated_at":"2026-03-17T13:13:37Z","closed_at":"2026-03-17T06:13:37Z","close_reason":"Created in wrong project, moving to noos","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-trs","title":"Feature: Open markdown files from URL in command palette (Cmd+P)","status":"open","priority":2,"issue_type":"feature","created_at":"2026-03-11T10:39:54Z","updated_at":"2026-03-11T10:39:54Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-av2","title":"Fix chat code fence rendering corruption","description":"Backticks inside fenced code blocks were being converted to inline code in chat view.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-08T03:52:24Z","updated_at":"2026-04-07T22:12:26Z","closed_at":"2026-04-07T15:12:26Z","close_reason":"Already fixed in commit fcd87e9 (renderer.js:4146-4166). Fenced code blocks are protected via @@CHAT_CODE_BLOCK_N@@ placeholders before inline-code processing, then restored. Verified by reading the current code.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-a8y","title":"PDF export broken: only first page, sidebar visible","description":"PDF export has two issues in the current installed version: (1) Only the first page renders — multi-page documents are truncated. (2) The sidebar is visible in the PDF output. A previous fix (markdown-reader-f2q) addressed print stylesheet overrides but these issues persist in the installed app, suggesting the fix was either not included in the installed build or is insufficient. Needs investigation.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-02T05:06:59Z","updated_at":"2026-03-03T01:22:41Z","closed_at":"2026-03-02T17:22:41Z","close_reason":"Fixed PDF export: Added comprehensive print CSS to hide sidebar and enable multi-page rendering","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-lg4","title":"Blue dot (unsaved indicator) persists after saving a file","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-03-02T05:06:58Z","updated_at":"2026-03-03T01:22:41Z","closed_at":"2026-03-02T17:22:41Z","close_reason":"Fixed unsaved indicator: Blue dot now shows for modified files, edit mode shows pencil symbol","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-f2q","title":"Print/PDF export should render only document content","description":"PDF export and print include full app chrome (title bar/sidebar/overlays) and card width styling. Restrict print output to page content area with print-specific layout rules.","notes":"Implemented print stylesheet overrides to hide app UI and normalize document width in printed/PDF output.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-02-27T04:36:19Z","updated_at":"2026-02-27T04:44:02Z","closed_at":"2026-02-26T20:44:02Z","close_reason":"Added print handling for EasyMDE UI/split preview and improved page-break behavior for headings/tables/code blocks.","comments":[{"id":"3b8de054-aa0e-4913-877f-138b1505bab3","issue_id":"markdown-reader-f2q","author":"jacobcole","text":"Adding additional rich-editor print cleanup and pagination refinements","created_at":"2026-02-27T04:43:58Z"}],"dependency_count":0,"dependent_count":0,"comment_count":1} +{"_type":"issue","id":"markdown-reader-lzy","title":"Add DOCX import and export support","description":"Allow users to export current markdown documents to .docx and open/import .docx files into the app. Include menu actions (Open..., Export...), reasonable markdown↔docx fidelity for headings/lists/links/code blocks, and clear handling for unsupported formatting.","acceptance_criteria":"1) Users can open a .docx file and it loads as editable markdown content. 2) Users can export the active document to .docx from the app menu. 3) File dialogs include .docx in supported types where relevant. 4) Unsupported DOCX constructs are handled gracefully without crashes and with user-visible notice when needed.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-27T04:16:20Z","updated_at":"2026-02-27T04:16:20Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-0d4","title":"Add advanced global search controls (match case, regex, include/exclude, replace)","description":"Current global search supports plain text matches but lacks common VS Code controls. Add UX controls for match case, regex mode, include/exclude globs, and replace across results to reduce context switching to external editors.","acceptance_criteria":"1) Global search UI includes toggles for Match Case and Regex. 2) Include/Exclude pattern inputs are available and applied during search. 3) Results can be replaced per-match and per-file with undo confirmation. 4) Keyboard flow remains usable (Cmd+Shift+F opens, Enter/arrow navigation still works).","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:45:46Z","updated_at":"2026-02-27T01:45:46Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-mwv","title":"Add VS Code-style split editor view (side-by-side tabs)","description":"Add split editor workflow to view/edit two files side-by-side (or split same file), with tab-to-split actions and resizeable divider similar to standard editors.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:42:08Z","updated_at":"2026-02-27T01:42:08Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-br6","title":"Research UX gaps vs VS Code and propose parity roadmap","description":"Audit markdown-reader against standard VS Code behaviors (navigation, sidebar, tabs, search, rename/move, context menus, split editors, update flow). Deliver prioritized gaps with concrete acceptance criteria and map to existing/new bd tickets.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-02-27T01:42:07Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Added VS Code parity gap analysis and research notes with prioritized mapping to tickets.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-7gp","title":"Drag and drop files into folders in left sidebar","description":"Enable drag-and-drop reorganization of files into folders in the left sidebar.","notes":"Implemented sidebar file-\u003efolder drag and drop with validated move-file-to-directory IPC, tree state sync, open-tab path updates, and new unit tests for file move safety + tree move behavior.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:18Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Implemented drag-and-drop move of files into folders in the sidebar tree with move validation.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-ds7","title":"Open in Finder action for files/folders across app","description":"Provide Open in Finder from left sidebar, tab bar, and other relevant file context menus.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:18Z","updated_at":"2026-02-27T04:15:07Z","closed_at":"2026-02-26T20:15:07Z","close_reason":"Added Open in Finder/Revel in Finder actions across tab, sidebar file/folder, and folder-path context menus.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-jbx","title":"Menu item for update status and manual check/apply update","description":"Add explicit update status and update action in the app menu, complementing passive update indicator.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:18Z","updated_at":"2026-02-27T04:15:08Z","closed_at":"2026-02-26T20:15:08Z","close_reason":"Added update status indicator and manual Check for Updates action in app menu with available/download state.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-09i","title":"Highlight active file in left sidebar when tab is focused","description":"When a tab is active and present in the sidebar tree, visually highlight the matching sidebar item.","notes":"Implemented sidebar active-file highlighting for tree/recent/timeline views using a shared path-matching helper; synced highlight on tab focus switches, folder expansion, and save-as path updates. Added node:test coverage in test/sidebar-highlight.test.js and verified with npm test.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:17Z","updated_at":"2026-02-27T01:45:58Z","closed_at":"2026-02-26T17:45:58Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-8ls","title":"Create new file directly inside selected folder from left sidebar","description":"Support creating a new file in the currently selected folder from left sidebar context.","notes":"Implemented selected-folder file creation from sidebar tree: right-click folder -\u003e New File Here, plus command palette path (Sidebar: New File in Selected Folder). Added selected folder state + nested temp file insertion/rename flow and case-insensitive collision utility tests.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:17Z","updated_at":"2026-02-27T01:49:34Z","closed_at":"2026-02-26T17:49:34Z","close_reason":"Completed: create-new-file in selected sidebar folder with context menu + command path, collision validation coverage, and tests.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-av3","title":"Clarify sidebar sort mode/status in UI","description":"Make current sidebar sort mode obvious (label/tooltip/indicator) and improve legibility so users understand what ordering is active.","notes":"Implemented clear sidebar sort status with persistent label + indicator + tooltip. Added shared helper (sidebar-sort-indicator.js), wired renderer sort UI updates via updateSidebarSortUI(), updated sidebar header markup/styles for legible status pill, and added node tests in tests/sidebar-sort-indicator.test.js. Verified with npm test (all passing).","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:17Z","updated_at":"2026-02-27T01:45:53Z","closed_at":"2026-02-26T17:45:53Z","close_reason":"Implemented and tested sort mode status indicator UI","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-j45","title":"Show full path tooltip for tabs and left sidebar items","description":"Hovering a file item in top tab bar or left sidebar should show full path tooltip.","notes":"Verified full-path tooltips on top tabs and left sidebar file items (tree/recent/timeline). Added tab-title tooltip propagation and ensured sidebar file elements expose full path via title attribute.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:17Z","updated_at":"2026-02-27T01:48:08Z","closed_at":"2026-02-26T17:48:08Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-dvb","title":"Resizable left sidebar via drag handle","description":"Allow the left sidebar width to be expanded/collapsed by dragging, similar to standard editors.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:16Z","updated_at":"2026-02-27T04:15:08Z","closed_at":"2026-02-26T20:15:08Z","close_reason":"Implemented draggable sidebar resizer with constrained width and session persistence.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-s8i","title":"Show word count for current document","description":"Add visible word count for the active markdown document.","notes":"Implemented a titlebar word-count indicator for the active document. Added shared countWords utility (Unicode-aware, handles contractions/hyphenation), wired live updates for preview/plain/rich edit flows, and added node tests in tests/word-count.test.js.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:16Z","updated_at":"2026-02-27T01:45:05Z","closed_at":"2026-02-26T17:45:05Z","close_reason":"Completed: current-document word count visible in UI with tests.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-ytp","title":"Native macOS editor context menu actions in content area","description":"Right-click context menu should include standard actions like Copy, Paste, Look Up, and Speech (Speak/Start Speaking) where appropriate, matching normal macOS app behavior.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-02-27T01:25:16Z","updated_at":"2026-02-27T04:15:08Z","closed_at":"2026-02-26T20:15:08Z","close_reason":"Added native macOS-style text context menu actions (edit, Look Up, Speech) via webContents context-menu handling.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-7a5","title":"Update-available indicator when new GitHub release exists","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-30T12:58:59Z","updated_at":"2026-01-30T13:06:20Z","closed_at":"2026-01-30T05:06:20Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-g8f","title":"Auto-increment build number on every build","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-30T12:58:57Z","updated_at":"2026-01-30T13:06:20Z","closed_at":"2026-01-30T05:06:20Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-18u","title":"Quick Open URL support","description":"Support pasting URLs into the Quick Open (Cmd+P) palette to quickly open them in the default browser.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-23T22:13:50Z","updated_at":"2026-01-24T04:55:36Z","closed_at":"2026-01-23T20:55:36Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-p87","title":"Formalize frontend log forwarding","description":"Ensure frontend console logs are always forwarded to the main process terminal in development mode for easier debugging. Currently implemented ad-hoc in renderer.js.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-23T20:03:41Z","updated_at":"2026-01-24T04:55:41Z","closed_at":"2026-01-23T20:55:41Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-zn7","title":"Fix heading collapse arrow wrapping","description":"On narrow screens, the collapse arrow (triangle) for headings wraps to the line above the heading text. It should remain inline with the heading using proper flexbox or white-space handling.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-23T06:36:55Z","updated_at":"2026-01-23T06:44:09Z","closed_at":"2026-01-22T22:44:09Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-32n","title":"Reveal folder in tree from recent view","description":"Clicking on a folder header in the 'Recent Changes' view should switch the sidebar back to the standard 'Tree View', expand the clicked folder, and scroll it into view.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-23T06:36:49Z","updated_at":"2026-01-23T20:03:57Z","closed_at":"2026-01-23T12:03:57Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-k8x","title":"Timeline view for recent changes","description":"Add a new view mode to the 'Recent Changes' feature that groups modified files by date (Today, Yesterday, Previous 7 Days) and then by parent folder. This provides a timeline-based perspective on work.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-23T06:36:44Z","updated_at":"2026-01-23T06:53:49Z","closed_at":"2026-01-22T22:53:49Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-o5i","title":"Sort files by recency in sidebar","description":"Add a sort toggle button to the sidebar header to switch between 'Name' (A-Z) and 'Date Modified' (Newest First) sorting for the standard file tree view.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-23T06:36:38Z","updated_at":"2026-01-23T06:48:35Z","closed_at":"2026-01-22T22:48:35Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-788","title":"Add dev mode restart button","description":"Add a feature to detect source code changes in dev mode and show a restart button in the titlebar.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-23T06:26:26Z","updated_at":"2026-04-07T11:56:07Z","closed_at":"2026-04-07T04:56:07Z","close_reason":"Already fully implemented in code: file watcher (main.js:3332-3353), restart-app IPC (main.js:3355-3359), button HTML (index.html:38-43), pulsing styles (styles.css:656-696), DEV badge (index.html:37, renderer.js:6421-6428), source-code-changed handler with toast (renderer.js:1426-1436). Closing as done.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-kw7","title":"Show recently modified files in the current open folder","description":"Design and implement a feature to view recently modified files in the currently open folder, sorted by recency. This helps users quickly identify which files have been updated.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-22T23:09:11Z","updated_at":"2026-01-22T23:19:11Z","closed_at":"2026-01-22T15:19:11Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-huu","title":"Unify content width and margins into single custom setting","description":"## Current State\n- Content Width: presets only (700, 900, 1100, 1300, 1500, 1800, full)\n- Content Margins: presets only (8, 16, 20, 28, 40px padding)\n- No way to set arbitrary values\n\n## Proposed\nConsider unifying into a single 'Content Width' setting that:\n- Allows arbitrary pixel values (input field or slider)\n- Or maybe just add 'Custom...' option that opens input dialog\n- The margin/padding setting may be redundant if width handles it\n\n## Questions\n- Should margins be separate from width?\n- What's the UX for custom values? Submenu with input? Separate dialog?","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-21T03:11:04Z","updated_at":"2026-01-21T03:51:13Z","closed_at":"2026-01-20T19:51:13Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-5n9","title":"Terminal display mode with optional chat parsing","description":"## Core Feature: Terminal View\nA display mode optimized for terminal/CLI content:\n- **Monospace font** throughout\n- **Dark background** (terminal aesthetic)\n- **Preserved whitespace** and formatting\n- **No markdown rendering** - shows content as-is\n\n## Use Cases\n- Saved terminal sessions\n- Log files\n- Build output\n- AI chat transcripts (Claude Code, etc.)\n- Any CLI output\n\n## View Menu\n```\nView\n├── ✓ Standard View\n├── Terminal View ⌘⇧T\n```\n\n## Optional Enhancement: Chat Parsing\nWhen enabled (or auto-detected), layer on:\n- Visual separation between Human/Assistant turns\n- Collapsible sections for tool calls\n- But the base terminal view works without any parsing\n\n## Technical Approach\n1. Add CSS class for terminal mode (monospace, dark bg, preserve whitespace)\n2. View menu toggle with keyboard shortcut\n3. (Later) Add heuristic chat parser as enhancement\n4. (Later) Add JSONL parser for Claude Code sessions","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-21T02:53:41Z","updated_at":"2026-01-21T03:17:44Z","closed_at":"2026-01-20T19:17:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-vji","title":"Add back/forward navigation (browser-style history)","description":"Add browser-style back/forward navigation for file history:\n\n**Features:**\n- Back button (Cmd+[) to go to previous file/location\n- Forward button (Cmd+]) to go forward after going back\n- Navigation history stack tracking opened files\n- Buttons in titlebar or toolbar\n\n**Behavior:**\n- Opening a file pushes to history\n- Back navigates to previous file\n- Forward only available after using back\n- History clears forward stack on new navigation","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-15T08:38:57Z","updated_at":"2026-01-15T08:42:48Z","closed_at":"2026-01-15T00:42:48Z","close_reason":"Implemented back/forward navigation with Cmd+[ and Cmd+], buttons in titlebar, Go menu","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-6ct","title":"Global search within opened folder (VS Code style)","description":"Add a global search feature when a folder is opened, similar to VS Code's Cmd+Shift+F:\n\n**Core features:**\n- Search across all files in the opened folder\n- Show results grouped by file with line previews\n- Click result → open file and jump to that line\n- Highlight matches in the preview\n\n**UI options:**\n- Sidebar panel (like VS Code)\n- Or modal search overlay (like Cmd+P in VS Code)\n- Keyboard shortcut: Cmd+Shift+F\n\n**Search options (nice to have):**\n- Case sensitive toggle\n- Regex support\n- File type filters (*.md only, etc.)\n- Include/exclude patterns\n\n**Performance:**\n- Index files on folder open\n- Debounce search input\n- Virtual scroll for large result sets","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-15T08:11:59Z","updated_at":"2026-01-15T08:23:10Z","closed_at":"2026-01-15T00:23:10Z","close_reason":"Implemented global search with Cmd+Shift+F: search across all files in folder, grouped results, keyboard navigation, match highlighting","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-q1s","title":"Support Obsidian-style wiki links within opened folders","description":"When a folder is opened in OpenMarkdownReader, support Obsidian-style [[wiki links]]:\n\n**Behavior:**\n- Parse `[[page name]]` syntax in markdown files\n- Resolve links by matching against filenames in the opened folder (without .md extension)\n- Click on wiki link → open that file in a new tab (or switch to existing tab)\n\n**Conflict handling:**\n- If multiple files have the same name (in different subdirectories), choose the first match\n- Show a warning/toast when a conflict is detected\n- Could potentially show disambiguation UI in future\n\n**Requirements:**\n- Folder must be opened (not just a single file)\n- Links are relative to the folder root\n- Support both `[[page]]` and `[[page|display text]]` syntax\n\n**Nice to have:**\n- Backlinks panel showing what links to the current page\n- Broken link highlighting (links to non-existent pages)","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-15T08:10:04Z","updated_at":"2026-01-15T08:16:45Z","closed_at":"2026-01-15T00:16:45Z","close_reason":"Implemented Obsidian-style wiki links: [[page]] and [[page|alias]] syntax, conflict warnings, broken link styling","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-o3m","title":"Auto-parse AI chat transcripts into formatted sections","description":"When pasting AI chat history (from Clawd, Claude, etc.), automatically parse and format it:\n- Detect chat patterns (User:/Assistant:, Human:/Claude:, etc.)\n- Convert to formatted sections with headings or visual distinction\n- Make conversations more readable in markdown view\n- Could be auto-detect on paste or a manual 'Format as Chat' action\n\nVisual distinction:\n- Clear visual difference between human messages and AI messages\n- Different styling/colors/backgrounds for each speaker\n- Appropriate margins/spacing between messages for readability\n\nCollapse functionality:\n- Consider 'Collapse all AI responses' button\n- Or leverage existing section collapse features\n- Evaluate if current heading collapse covers this use case or if dedicated chat collapse is needed\n\nTerminal formatting preservation:\n- Research: Can we preserve/import terminal formatting (ANSI colors, syntax highlighting)?\n- Export option to retain terminal colors/highlights from CLI tools\n- Consider parsing ANSI escape codes and converting to styled HTML/markdown\n- Useful for Claude Code transcripts, other CLI chat tools\n\nLayout/Margins:\n- Chat-specific margin settings (tighter or looser spacing between turns)\n- Consider chat bubble style vs linear style options\n- Respect global margin settings but allow chat-specific overrides","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-14T23:05:39Z","updated_at":"2026-01-14T23:22:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-d37","title":"Make content margins fully adjustable with wider max option","description":"Current margin settings are limited. Want:\n1. Fully adjustable/customizable margins (slider or input)\n2. Make 'Spacious' (widest) setting even wider - less margin, more content width\n3. Possibly add preset options: Compact, Normal, Spacious, Full-width","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-14T23:04:55Z","updated_at":"2026-01-17T12:48:05Z","closed_at":"2026-01-17T04:48:05Z","close_reason":"Implemented in this session","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-5ac","title":"Show upload success message after publishing","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-14T17:50:45Z","updated_at":"2026-01-14T17:57:17Z","closed_at":"2026-01-14T09:57:17Z","close_reason":"Implemented toast notifications for publish success/error","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-8cy","title":"Fix widescreen space usage on globalbr.ai/files","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-14T17:03:21Z","updated_at":"2026-01-14T17:03:28Z","closed_at":"2026-01-14T09:03:28Z","close_reason":"Wrong project - should be in noos","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-4go","title":"Right-click in content area shows tab context menu","description":"Right-clicking in the content area should show the same context menu as right-clicking the tab. This eliminates the need to find the active tab when you want to close, duplicate, rename, or perform other tab actions. The user is already focused on the content, so the context menu appears where their attention is. Simple and discoverable.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-13T12:00:03Z","updated_at":"2026-01-13T12:12:38Z","closed_at":"2026-01-13T04:12:38Z","close_reason":"Implemented: right-click in markdown content area now shows tab context menu","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-jd4","title":"Add scroll wheel navigation for tabs","description":"Allow two-finger scroll (trackpad) or scroll wheel to navigate through tabs in the tab bar. Idiomatic approach: Listen for wheel events on .tab-bar and scroll horizontally when tabs overflow. This matches behavior in Chrome, VS Code, and other macOS apps with tab bars.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-01-13T12:00:02Z","updated_at":"2026-01-13T12:23:12Z","closed_at":"2026-01-13T04:23:12Z","close_reason":"Added wheel event listener to convert vertical scroll to horizontal tab bar scroll","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-0ue","title":"Add spacing between sibling heading sections","description":"Consecutive h2 sections (like Topics, Organizations, People) appear cramped with insufficient vertical spacing between them. The CSS removes margin-top from headings inside .md-section containers but doesn't add spacing between sibling sections. Fix: Add margin-top to .md-section + .md-section selector to create proper breathing room between sections.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-13T12:00:01Z","updated_at":"2026-01-13T12:21:11Z","closed_at":"2026-01-13T04:21:11Z","close_reason":"Added .md-section + .md-section { margin-top: 24px } for proper spacing","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-8en","title":"EasyMDE split mode: toolbar disappears and can't close split view","description":"When opening side-by-side split mode in EasyMDE rich editor, the toolbar disappears and there's no way to close the split view.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-27T03:19:42Z","updated_at":"2025-12-27T03:35:21Z","closed_at":"2025-12-26T19:35:21Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-4yq","title":"Add document comments in view mode","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-27T03:13:49Z","updated_at":"2026-04-03T06:48:07Z","labels":["defer"],"dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-r1r","title":"WYSIWYG edit mode that renders markdown inline","description":"**Goal**: Add a Milkdown-based WYSIWYG editor as a new editing mode. Long-term, this could become the default edit mode, with a separate read-only viewing mode preserved.\n\n**Why Milkdown (not Tiptap)**:\n- Built on ProseMirror, like Tiptap, but Markdown is first-class (uses remark) so round-tripping text → tree → text is clean\n- Plugin-based so we can add only what we need\n- Collab path is still open via @milkdown/plugin-collab (see parking ticket markdown-reader-[collab])\n\n**Scope v1**:\n- Ship Milkdown as an **alternative** edit mode behind a toggle / setting — do NOT make it default on day one\n- Preserve current plain-textarea and EasyMDE modes until Milkdown is proven stable on real notes\n- Roundtrip fidelity test: open each file in the user's vault, edit nothing, save, diff — must be zero-change\n- Handle wikilinks [[...]] as a custom node (otherwise they get mangled)\n- Handle frontmatter passthrough\n\n**Scope v2** (after stability):\n- Promote Milkdown to default editing mode\n- Keep a 'Plain / Raw Markdown' mode in the View menu for power users and for cases where Milkdown struggles\n- Read-only preview mode stays untouched\n\n**Blockers / prerequisites**:\n- markdown-reader-a4h (undo persistence across mode/tab switches). A WYSIWYG editor is a much bigger state machine and swapping it in/out while preserving undo is hard. Don't start until editor-per-tab lifecycle is solid.\n\n**Open questions**:\n- Do we ship Milkdown via CDN/vendor or bundle through a proper build step? (likely need a build step — Milkdown isn't a single-file drop-in like EasyMDE)\n- How does it interact with the custom wikilink indexer and the rich-toolbar toggle?\n- Styling parity with current preview CSS\n\n**Merged from**: markdown-reader-pvi (closed as duplicate)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-27T03:11:52Z","updated_at":"2026-04-07T11:35:43Z","labels":["defer"],"dependencies":[{"issue_id":"markdown-reader-r1r","depends_on_id":"markdown-reader-a4h","type":"blocks","created_at":"2026-04-07T04:35:48Z","created_by":"auto-import","metadata":"{}"}],"comments":[{"id":"3983d789-b825-43d6-94be-875d9dc13827","issue_id":"markdown-reader-r1r","author":"jacobcole","text":"## Research Notes\n\n**Options for WYSIWYG/live-preview edit mode:**\n\n| Approach | Raw Text Visible | Rendered Inline | Effort |\n|----------|------------------|-----------------|--------|\n| EasyMDE (current) | Yes | No | N/A |\n| Milkdown/Tiptap | No | Yes (pure WYSIWYG) | Medium |\n| Obsidian-style (CodeMirror 6) | Yes | Yes (decorations) | High |\n| Split pane (EasyMDE built-in) | Yes | Side-by-side | Already available |\n\n**Recommendations:**\n- Milkdown is pure WYSIWYG - hides raw markdown, shows rendered output only\n- Obsidian approach is best of both worlds (see raw syntax but styled) - requires CodeMirror 6 with custom decorations\n- EasyMDE already has side-by-side mode (columns icon in Rich toolbar)\n\n**Libraries to consider:**\n- Milkdown (ProseMirror-based, ~40kb gzipped)\n- Tiptap (ProseMirror-based, very flexible)\n- CodeMirror 6 with markdown decorations (what Obsidian uses)","created_at":"2025-12-27T03:17:10Z"}],"dependency_count":1,"dependent_count":1,"comment_count":1} +{"_type":"issue","id":"markdown-reader-4qt","title":"Dedupe untitled-tab creation across new-file entry points","description":"Welcome-screen new-file-btn, sidebarNewFileBtn (no-directory branch), and onNewFile IPC handler each replicate the same createTab+isEditing+showEditor block in renderer.js. Extract a createUntitledTab() helper so behavior (e.g. focus) can't drift between entry points.","status":"open","priority":3,"issue_type":"task","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:22:37Z","created_by":"tmad4000","updated_at":"2026-07-10T19:22:37Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-j1s","title":"Visually indicate empty folders in sidebar file tree","description":"Sidebar folders currently give no indication that they're empty until you click to expand, at which point nothing appears. Adds dimmed chevron + folder icon + muted label for folders containing no visible (non-dotfile) entries. Uses an isEmpty flag populated server-side by a cheap opendirSync-based check. State is re-synced on expansion to catch external filesystem changes.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-16T07:31:55Z","updated_at":"2026-04-16T07:32:02Z","closed_at":"2026-04-16T00:32:02Z","close_reason":"Dimmed chevron/icon/label on empty folders; isEmpty populated server-side by cheap opendirSync check and re-synced on expand to catch external filesystem changes.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-aad","title":"Prompt to become default handler for .md/.jsonl on first launch","description":"## Goal\nOn first launch (or when the app detects it's not the default handler), show a non-intrusive banner or dialog asking: \"Make OpenMarkdownReader your default app for Markdown files?\"\n\n## Current state (2026-04-09)\n- .md and .jsonl defaults set manually via `duti -s com.jacobcole.openmarkdownreader .md all`\n- .jsonl added to fileAssociations in package.json (will be in Info.plist after next build)\n- Stale \"OpenMarkdownReader 2.app\" (TestFlight wrapper) was poisoning LaunchServices; fixed by unregistering via lsregister\n\n## Implementation sketch\n1. On `app.whenReady()`, check if `app.isDefaultProtocolClient()` or equivalent for file types\n2. Electron doesn't have a built-in \"is default for file extension\" check, so use `duti -x md` or `LSCopyDefaultRoleHandlerForContentType` via native module\n3. If not default, show a subtle banner (not a modal) with \"Set as default\" / \"Not now\" / \"Don't ask again\"\n4. Store preference in config: `defaultHandlerPromptDismissed: true`\n5. Gate behind `!isMASBuild()` — MAS apps can't call `duti` or `lsregister`\n\n## File types to check\n- .md (primary)\n- .markdown, .mdown, .mkd (variants)\n- .jsonl (newly added)\n- NOT .json, .txt, .yaml — too aggressive, users likely want VS Code/other for those\n\n## UX reference\nSimilar to Chrome's \"Make Chrome your default browser?\" or VS Code's \"Make VS Code your default editor?\"\n\n## Out of scope\n- Auto-setting without asking (bad UX, user should consent)\n- Setting defaults for ALL registered file types (only markdown family + jsonl)","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-09T20:06:35Z","updated_at":"2026-04-09T20:06:35Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-rx4","title":"Choose homepage variant and wire a hosting/deployment path","description":"The repo now has a primary marketing homepage in `site/` and two alternatives in `site/alternatives/claude/` and `site/alternatives/nash/`.\n\nFollow-up needed:\n- Decide which concept becomes the canonical public homepage\n- Fold best ideas from the alternates into the chosen version if needed\n- Pick a hosting path (GitHub Pages, static host, app site, etc.)\n- Add a simple local preview/deploy workflow if we want the page to live outside the repo only as source\n\nAcceptance ideas:\n1. One homepage variant is selected as canonical.\n2. Hosting/deployment path is documented and tested.\n3. Public URL or publish procedure exists.\n4. Repo docs link to the chosen homepage entrypoint and workflow.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-09T05:12:21Z","updated_at":"2026-04-09T05:12:21Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-1wc","title":"Evaluate default auto-save and simplify top-bar toggle affordance","description":"Consider making auto-save easier to discover and enable from the top bar.\n\nContext:\n- The app already has an auto-save mode and an autosave indicator/button in the titlebar.\n- Current behavior may be too hidden or require menu hunting.\n- User request: consider making auto-save a more obvious, easy-to-enable option from the top bar, with the button state updating immediately and clearly.\n\nQuestions to resolve:\n- Should auto-save remain opt-in, or become default-on for files with a path?\n- If it stays opt-in, should the top-bar autosave control be more prominent or clearer about enabled/disabled state?\n- Should clicking the top-bar control both toggle auto-save and update nearby UI/state immediately without ambiguity?\n- How should untitled files behave when auto-save is enabled?\n- How does this interact with external file watching/conflict handling?\n\nAcceptance ideas:\n1. Auto-save can be enabled/disabled directly from an obvious top-bar control.\n2. The control's visual state always matches the actual setting after click/menu changes.\n3. If default-on is chosen, the app handles unsaved/untitled files and external-change conflicts clearly.\n4. Copy/tooltips make it obvious whether auto-save is on, off, or unavailable for the current tab.","status":"open","priority":3,"issue_type":"task","created_at":"2026-04-09T05:03:47Z","updated_at":"2026-04-09T05:03:47Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-iqz","title":"Within-tab rich/plain toggle still loses undo on old mode","description":"Phase 2 follow-up to markdown-reader-a4h. Tab switches and preview toggles now preserve undo (per-tab editorEl + easyMDE kept alive), but toggling rich↔plain WITHIN a single tab still loses the OLD mode's undo history because:\n\n- enterRichMode() may call easyMDE.value(textarea.value) to sync, which triggers CM setValue and clears CM history\n- leaveRichMode() syncs textarea.value = easyMDE.value(), which resets the textarea's native undo stack\n\nTo preserve both stacks across in-tab toggles, we'd need to either (a) re-parent the textarea between the EasyMDEContainer and the bare host without triggering value reassignments, or (b) keep both editors visible/positioned but only one focused and accept duplicate state.\n\nLower priority than markdown-reader-a4h was — most users switch tabs, fewer toggle modes within a tab. Revisit only if anyone complains.","status":"open","priority":3,"issue_type":"bug","created_at":"2026-04-07T22:56:25Z","updated_at":"2026-04-07T22:56:25Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-1la","title":"Add Cmd+Alt+R accelerator to Restart menu item","description":"The Restart menu item (main.js:1006-1011) has no keyboard accelerator. Cmd+R is already taken (refresh current file, main.js:1095). Add Cmd+Alt+R as the Restart accelerator so dev iteration is keyboard-driven.\n\n**Why this priority**: trivial 1-line fix, immediate quality of life improvement for dev work.\n\n**Acceptance**: Cmd+Alt+R triggers the Restart menu item from anywhere in the app.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-07T11:56:31Z","updated_at":"2026-04-07T11:57:56Z","closed_at":"2026-04-07T04:57:56Z","close_reason":"Implemented in working tree (not yet committed). Smart dev watcher: main.js:3332-3380. Restart accelerator: main.js:1006-1013. DEV badge tooltip: renderer.js:6421-6448. New IPC: preload.js, main.js reload-renderer handler. User to review + commit.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-fgg","title":"DEV badge tooltip: show git hash + build date + version","description":"The DEV badge (index.html:37, renderer.js:6421-6428) is visible in dev mode but has no tooltip. We already have getBuildInfo() returning version, buildNumber, gitHash, buildDate. Surface this in the badge title attribute so hovering reveals exactly what's running.\n\n**Format**: 'DEV build • v1.0.x (build N) • abc1234 • 2026-04-07 14:30'\n\n**Bonus**: also use this for the dev-restart-btn tooltip when it's visible (currently says 'Source code changed. Click to restart.').","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-07T11:56:28Z","updated_at":"2026-04-07T11:57:56Z","closed_at":"2026-04-07T04:57:56Z","close_reason":"Implemented in working tree (not yet committed). Smart dev watcher: main.js:3332-3380. Restart accelerator: main.js:1006-1013. DEV badge tooltip: renderer.js:6421-6448. New IPC: preload.js, main.js reload-renderer handler. User to review + commit.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-n36","title":"Add breadcrumb path bar for active file navigation","description":"Standard editors expose active-file location with clickable breadcrumbs. Add a breadcrumb bar above content showing workspace-relative path segments and current heading/file context to reduce navigation friction in nested folders.","acceptance_criteria":"1) Breadcrumbs show workspace root -\u003e folder segments -\u003e file name for active tab. 2) Each folder segment is clickable and reveals that folder in sidebar. 3) Breadcrumbs update on tab switch and file rename/move. 4) Hidden/overflow handling works on small window widths.","status":"open","priority":3,"issue_type":"feature","created_at":"2026-02-27T01:45:58Z","updated_at":"2026-02-27T01:45:58Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-6v2","title":"Review settings vs View menu placement for layout controls","description":"Audit whether content margin/layout controls belong in Settings or View menu; consolidate for clearer IA.","status":"open","priority":3,"issue_type":"task","created_at":"2026-02-27T01:25:19Z","updated_at":"2026-02-27T01:25:19Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-b79","title":"Markdown diff and track-changes mode for writing","description":"Add a writing workflow with diffs/track changes similar to editor review flows (VS Code-style compare/inline change visibility).","status":"open","priority":3,"issue_type":"feature","created_at":"2026-02-27T01:25:17Z","updated_at":"2026-02-27T01:25:17Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-f9j","title":"Add more App Store screenshots","description":"Consider adding additional screenshots to the Mac App Store listing. Current: 1 screenshot (1440x900 dark mode with features list). Could add: light mode, editing view, multiple tabs, file browser sidebar.","status":"open","priority":3,"issue_type":"task","created_at":"2026-01-28T10:50:23Z","updated_at":"2026-01-28T10:50:23Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-wdj","title":"JSONL parser for Claude Code sessions","description":"Parse Claude Code session files (~/.claude/projects/*.jsonl):\n- Auto-detect format on file open\n- Extract human/assistant/tool messages\n- Render with Terminal View + chat parsing\n- Show timestamps, thinking blocks (toggleable)","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-01-21T03:11:02Z","updated_at":"2026-01-21T03:51:13Z","closed_at":"2026-01-20T19:51:13Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-3oq","title":"Chat parsing for terminal view","description":"Layer on top of Terminal View:\n- Detect Human:/Assistant: patterns\n- Visual separation between conversation turns\n- Collapsible sections for tool calls\n- Works with pasted terminal output and structured JSONL","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-01-21T03:10:59Z","updated_at":"2026-01-21T03:51:13Z","closed_at":"2026-01-20T19:51:13Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-n6w","title":"EasyMDE preview doesn't render lists with dashes as bullets","description":"In split/side-by-side mode, dashes (-) aren't being rendered as bullet points. This is NOT intentional - EasyMDE is using its own bundled markdown parser instead of the app's configured marked.js with proper rendering. Fix: Add previewRender option to EasyMDE config that uses the app's marked instance.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-27T03:20:07Z","updated_at":"2025-12-27T03:35:21Z","closed_at":"2025-12-26T19:35:21Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-q3q","title":"Finish broader Obsidian compatibility beyond parser-level wiki links","description":"Parser-level support for `[[page]]`, `[[page|alias]]`, and same-note heading links is now in the desktop renderer via a marked extension. Remaining Obsidian compatibility work should be tracked separately:\n- `![[embed]]` embeds\n- cross-file heading navigation (`[[note#Heading]]` should open note and jump)\n- block refs (`[[note#^block]]`)\n- audit any metadata/backlink panes that may still serialize links as markdown text instead of rendering them","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-08T04:03:24Z","updated_at":"2026-04-08T04:03:24Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-e7r","title":"Far-future: Real-time collaborative editing via Yjs + Milkdown","description":"**Not urgent — parking ticket** to preserve the decision context from the 2026-04-02 session.\n\n**Goal**: Eventually support real-time collaborative editing on markdown files (multiple users editing the same doc with live cursors and awareness).\n\n**Approach**:\n- Milkdown (ProseMirror-based) already has @milkdown/plugin-collab which wraps Yjs + y-prosemirror — the same stack Tiptap uses. Adding Milkdown as the editor (markdown-reader-r1r) is the enabling move; collab is a plugin on top.\n- Tiptap has a more mature commercial collab story (Tiptap Cloud), but we're choosing Milkdown for other reasons. Collab capability on Milkdown is fine — just less polish on the DX.\n- Yjs is the CRDT library. Transport options: y-websocket (self-hosted, simple), y-webrtc (P2P, NAT pain), y-indexeddb (local persistence).\n\n**Hard problems to solve before shipping collab**:\n1. **Backend/transport**: where does the Yjs server live? Self-host a tiny y-websocket server? Piggyback on noos / IdeaFlow backend? This decision is upstream of everything.\n2. **On-disk reconciliation**: OpenMarkdownReader is a file-based editor. If someone else edits the .md file on disk while a collab session is live, we have a classic local-first conflict problem. Need a merge strategy.\n3. **Markdown round-tripping under collab**: Yjs operates on the ProseMirror document tree, not the Markdown string. Serialization to .md happens at save time. Two users with slightly different serialization preferences (e.g. ATX vs setext headings) could produce diff noise.\n4. **Auth / identity / presence**: who is the other user? Needs some notion of identity.\n5. **Why this matters for the product**: collab is probably the natural meeting point between OpenMarkdownReader and noos / IdeaFlow / Thoughtstream. Revisit when those products' roadmaps are clearer.\n\n**Prerequisites**:\n- markdown-reader-r1r (Milkdown editor) must ship first.\n\n**Do not work on this without explicit user green-light.** It's here to preserve context, not as a signal to build.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-07T11:36:07Z","updated_at":"2026-04-07T11:36:07Z","dependencies":[{"issue_id":"markdown-reader-e7r","depends_on_id":"markdown-reader-r1r","type":"blocks","created_at":"2026-04-07T04:36:10Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-rhj","title":"RTF with formatting support","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T08:54:42Z","updated_at":"2025-12-28T08:54:42Z","dependencies":[{"issue_id":"markdown-reader-rhj","depends_on_id":"markdown-reader-pvi","type":"relates-to","created_at":"2025-12-28T00:54:57Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-pvi","title":"Consider full WYSIWYG editing mode","status":"closed","priority":4,"issue_type":"feature","created_at":"2025-12-28T08:52:31Z","updated_at":"2026-04-07T11:35:50Z","closed_at":"2026-04-07T04:35:50Z","close_reason":"Merged into markdown-reader-r1r (Milkdown WYSIWYG editor plan). The two tickets were near-duplicates; r1r is now the active home for WYSIWYG work.","dependencies":[{"issue_id":"markdown-reader-pvi","depends_on_id":"markdown-reader-rhj","type":"relates-to","created_at":"2025-12-28T00:54:57Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-ypl","title":"Marktree support","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T08:52:03Z","updated_at":"2025-12-28T08:52:03Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-nzs","title":"Obsidian markdown support","notes":"Investigating current wiki-link rendering path and restoring Obsidian-style [[...]] support without flattening links into saved markdown.","status":"closed","priority":4,"issue_type":"feature","assignee":"codex","created_at":"2025-12-28T08:52:02Z","updated_at":"2026-04-08T04:03:46Z","closed_at":"2026-04-07T21:03:46Z","close_reason":"Implemented parser-level Obsidian-style wiki link support in the desktop renderer via a marked extension. `[[page]]`, `[[page|alias]]`, and same-note heading links now render without rewriting markdown source; remaining broader Obsidian compatibility is tracked in markdown-reader-q3q.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-qn6","title":"Make pasting terminal output friendly","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T08:51:32Z","updated_at":"2026-04-16T07:32:02Z","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/renderer.js b/renderer.js index d7f0e79..2b891fd 100644 --- a/renderer.js +++ b/renderer.js @@ -6308,8 +6308,9 @@ richModeBtn.addEventListener('click', () => { richModeBtn.classList.remove('active'); leaveRichMode(); if (richToolbarBtn) richToolbarBtn.classList.add('hidden'); - if (editor && editor.focus) editor.focus(); } + const tab = tabs.find(t => t.id === activeTabId); + focusActiveEditor(tab); }); function updateRichToolbarUI() { @@ -6338,6 +6339,21 @@ if (richToolbarBtn) { // Overridden Functions to support EasyMDE // ------------------------------------------ +// Put keyboard focus in the active tab's editing surface so the next +// keystroke lands in the document. In rich mode the underlying textarea is +// hidden inside the EasyMDE wrapper — focusing it does nothing, so the +// CodeMirror instance must be focused instead. +function focusActiveEditor(tab) { + if (!tab) return; + // tab.easyMDE survives leaveRichMode (kept for undo history), so mode — + // not instance presence — decides which surface is visible. + if (settings.richEditorMode && tab.easyMDE) { + try { tab.easyMDE.codemirror.focus(); } catch {} + } else if (tab.editorEl) { + tab.editorEl.focus(); + } +} + // Per-tab showEditor: make sure the active tab's editor (textarea or EasyMDE // wrapper) is the visible one, and seed content only if the editor doesn't // already have it (preserves undo on preview/mode toggles). @@ -6373,8 +6389,9 @@ showEditor = function(content) { richModeBtn.classList.remove('active'); if (richToolbarBtn) richToolbarBtn.classList.add('hidden'); if (tab.easyMDE) leaveRichMode(); - if (tab.editorEl) tab.editorEl.focus(); } + + focusActiveEditor(tab); }; // Per-tab hideEditor: capture in-flight content into tab.content and hide diff --git a/tests/new-file-focus.test.js b/tests/new-file-focus.test.js new file mode 100644 index 0000000..f7478c3 --- /dev/null +++ b/tests/new-file-focus.test.js @@ -0,0 +1,43 @@ +const test = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('node:fs'); +const path = require('node:path'); + +const renderer = fs.readFileSync(path.join(__dirname, '..', 'renderer.js'), 'utf8'); + +// Jacob: "when I create a new page it should focus." Every new-file path +// (Cmd+N, welcome-screen New File, sidebar inline-create with forceEdit) +// funnels through showEditor. The per-tab showEditor override used to focus +// only the plain-mode textarea; in rich mode (the default) the underlying +// textarea is hidden inside the EasyMDE wrapper, so focusing it was a no-op +// and keyboard focus never reached the editor. + +test('focusActiveEditor focuses CodeMirror in rich mode and the textarea in plain mode', () => { + const helperMatch = renderer.match(/function focusActiveEditor\(tab\) \{[\s\S]*?\n\}/); + assert.ok(helperMatch, 'renderer should define focusActiveEditor'); + + const helperBody = helperMatch[0]; + assert.match(helperBody, /settings\.richEditorMode && tab\.easyMDE/, + 'rich-mode focus must check the mode, not just instance presence (tab.easyMDE survives leaveRichMode)'); + assert.match(helperBody, /tab\.easyMDE\.codemirror\.focus\(\)/); + assert.match(helperBody, /tab\.editorEl\.focus\(\)/); +}); + +test('showEditor override ends by focusing the active editing surface', () => { + const overrideMatch = renderer.match(/showEditor = function\(content\) \{[\s\S]*?\n\};/); + assert.ok(overrideMatch, 'per-tab showEditor override should exist'); + assert.match(overrideMatch[0], /focusActiveEditor\(tab\);/, + 'showEditor must hand keyboard focus to the editor in both rich and plain mode'); +}); + +test('new-file entry points enter edit mode through showEditor', () => { + const newFileHandler = renderer.match(/window\.electronAPI\.onNewFile\(\(\) => \{[\s\S]*?\n\}\);/); + assert.ok(newFileHandler, 'renderer should handle the New File menu request'); + assert.match(newFileHandler[0], /showEditor\(''\)/); +}); + +test('rich/plain mode toggle refocuses the editor', () => { + const toggleMatch = renderer.match(/richModeBtn\.addEventListener\('click', \(\) => \{[\s\S]*?\n\}\);/); + assert.ok(toggleMatch, 'rich mode toggle handler should exist'); + assert.match(toggleMatch[0], /focusActiveEditor\(tab\);/); +}); From 4c596e4a1323dc6fa408333ebcd56200c15b1ff5 Mon Sep 17 00:00:00 2001 From: tmad4000 Date: Fri, 10 Jul 2026 12:24:02 -0700 Subject: [PATCH 2/3] chore: sync beads state, ignore embedded dolt runtime files Co-Authored-By: Claude Fable 5 --- .beads/.gitignore | 6 ++++++ .beads/interactions.jsonl | 1 + 2 files changed, 7 insertions(+) diff --git a/.beads/.gitignore b/.beads/.gitignore index 65bd4ae..9fe9763 100644 --- a/.beads/.gitignore +++ b/.beads/.gitignore @@ -18,6 +18,12 @@ bd.sock db.sqlite bd.db +# Embedded dolt runtime state (local working copies, not source of truth) +backup/ +embeddeddolt/ +export-state.json +last-touched + # Merge artifacts (temporary files from 3-way merge) beads.base.jsonl beads.base.meta.json diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index e69de29..4c4a8dc 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -0,0 +1 @@ +{"id":"int-a77088af","kind":"field_change","created_at":"2026-07-10T19:15:23.854851Z","actor":"tmad4000","issue_id":"markdown-reader-zi2","extra":{"field":"status","new_value":"in_progress","old_value":"open"}} From 884adf4a1369b83ceaff713066d82c9a1735f5f2 Mon Sep 17 00:00:00 2001 From: tmad4000 Date: Fri, 10 Jul 2026 12:26:33 -0700 Subject: [PATCH 3/3] chore: close markdown-reader-zi2 in beads Co-Authored-By: Claude Fable 5 --- .beads/interactions.jsonl | 1 + .beads/issues.jsonl | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index 4c4a8dc..ac7f1f4 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -1 +1,2 @@ {"id":"int-a77088af","kind":"field_change","created_at":"2026-07-10T19:15:23.854851Z","actor":"tmad4000","issue_id":"markdown-reader-zi2","extra":{"field":"status","new_value":"in_progress","old_value":"open"}} +{"id":"int-efa978ed","kind":"field_change","created_at":"2026-07-10T19:26:23.438204Z","actor":"tmad4000","issue_id":"markdown-reader-zi2","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Fixed in PR #3 (fix/new-file-focus). focusActiveEditor helper focuses CodeMirror in rich mode / textarea in plain mode from showEditor and the rich-plain toggle. Verified via npm test (63/63) and live CDP smoke."}} diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index da3eaf1..4e026a9 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,4 +1,4 @@ -{"_type":"issue","id":"markdown-reader-zi2","title":"New file/page should focus the editor (rich mode never focuses CodeMirror)","description":"Jacob: 'when I create a new page it should focus.' Root cause: the overridden showEditor in renderer.js focuses only in plain mode (tab.editorEl.focus()); in rich mode (default richEditorMode:true) it calls enterRichMode() but never easyMDE.codemirror.focus(), so Cmd+N / welcome-screen New File / sidebar inline-create leave keyboard focus outside the editor. Fix: focus the CodeMirror instance in the rich-mode branch of showEditor.","status":"in_progress","priority":1,"issue_type":"bug","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:15:16Z","created_by":"tmad4000","updated_at":"2026-07-10T19:15:24Z","started_at":"2026-07-10T19:15:24Z","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-zi2","title":"New file/page should focus the editor (rich mode never focuses CodeMirror)","description":"Jacob: 'when I create a new page it should focus.' Root cause: the overridden showEditor in renderer.js focuses only in plain mode (tab.editorEl.focus()); in rich mode (default richEditorMode:true) it calls enterRichMode() but never easyMDE.codemirror.focus(), so Cmd+N / welcome-screen New File / sidebar inline-create leave keyboard focus outside the editor. Fix: focus the CodeMirror instance in the rich-mode branch of showEditor.","status":"closed","priority":1,"issue_type":"bug","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:15:16Z","created_by":"tmad4000","updated_at":"2026-07-10T19:26:23Z","started_at":"2026-07-10T19:15:24Z","closed_at":"2026-07-10T19:26:23Z","close_reason":"Fixed in PR #3 (fix/new-file-focus). focusActiveEditor helper focuses CodeMirror in rich mode / textarea in plain mode from showEditor and the rich-plain toggle. Verified via npm test (63/63) and live CDP smoke.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-0f9","title":"Audit app lag and spinning behavior","description":"Investigate current severe UI lag/spinning in OpenMarkdownReader. Check live process CPU/memory, logs, watch mode behavior, remote URL tabs, renderer/main hot paths, and patch any concrete regressions found.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-22T09:07:38Z","updated_at":"2026-05-22T09:14:57Z","closed_at":"2026-05-22T02:14:57Z","close_reason":"Found root recursive scan loop from second-instance dot path resolving to /; patched argument resolution, broad-root scan guards, and hidden-sidebar watcher behavior.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-l7u","title":"Cmd+F should refocus open find bar in edit mode","description":"When the in-file find bar is already open while editing, pressing Cmd+F again should keep find open and focus/select the query. It currently behaves like a toggle and can close or fail from the editor context.","acceptance_criteria":"Cmd+F opens find from edit mode; Cmd+F with find already open keeps it open, focuses/selects the query, and does not exit edit mode; Esc or close button still closes find.","status":"closed","priority":1,"issue_type":"bug","created_at":"2026-05-12T00:42:59Z","updated_at":"2026-05-12T00:44:04Z","closed_at":"2026-05-11T17:44:04Z","close_reason":"Fixed Cmd+F handling so Find opens or refocuses the find bar instead of toggling it closed. Added capture-phase shortcut handling for edit mode and regression coverage.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-b28","title":"Wire up electron-updater for non-MAS DMG auto-updates","description":"## Goal\nWire up `electron-updater` for the **non-MAS** DMG distribution so Jacob and other direct-download users automatically get new releases without manually downloading DMGs or re-building from source.\n\n## Current state (verified 2026-04-08)\n- `package.json` has **no `build.publish`** config\n- **`electron-updater` is not a dependency**\n- `main.js` never imports `autoUpdater`\n- Result: v1.0.4 users who installed from GitHub are stuck on v1.0.4 forever unless they manually re-download\n\n## Why this matters\n- Currently my workflow to get the latest code running is \"build locally, ditto into /Applications\". That's fine for one user. Not fine for anyone else.\n- The Local-Only MAS edition (markdown-reader-xwc) and MAS Standard get updates via Apple automatically. The non-MAS build is currently the odd one out with *no* update path at all.\n- The non-MAS edition is strategically the most important one for power users (it's where SFTP, shell integration, and future power features will live — see markdown-reader-571). Power users especially need fast update cadence.\n\n## Implementation\n\n### 1. Add dependency\n```bash\nnpm install electron-updater\n```\n**Dep version policy**: per CLAUDE.md, use a version at least one month old. Check npm before installing.\n\n### 2. Configure publishing in `package.json`\n```json\n\"build\": {\n \"publish\": {\n \"provider\": \"github\",\n \"owner\": \"tmad4000\",\n \"repo\": \"OpenMarkdownReader\",\n \"releaseType\": \"release\"\n }\n}\n```\n\n### 3. Wire updater into `main.js`\nGate on non-MAS build using the existing `isMASBuild()` helper — MAS updates are handled by Apple and calling `autoUpdater` from a MAS build will crash or no-op ugly:\n\n```javascript\nconst { autoUpdater } = require('electron-updater');\n\napp.whenReady().then(() =\u003e {\n // ... existing ready logic ...\n if (!isMASBuild()) {\n autoUpdater.checkForUpdatesAndNotify().catch(err =\u003e {\n console.warn('[auto-update] check failed:', err.message);\n });\n // Re-check every 6 hours for long-running instances\n setInterval(() =\u003e {\n autoUpdater.checkForUpdatesAndNotify().catch(() =\u003e {});\n }, 6 * 60 * 60 * 1000);\n }\n});\n```\n\n### 4. UI: \"Update available\" indicator\nPer global CLAUDE.md guidance (\"Always show when a new version is available\"), add a subtle indicator in the user menu / footer:\n- Listen for `autoUpdater.on('update-available', ...)` → set a flag in main, forward to renderer via IPC\n- Renderer shows a small dot next to the version number (already displayed per CLAUDE.md \"Version Display in User Menus\" rule)\n- Clicking the dot opens a \"Restart to update\" dialog backed by `autoUpdater.quitAndInstall()`\n- Listen for `autoUpdater.on('update-downloaded', ...)` → enable the restart option\n\n### 5. Release workflow change\n- electron-builder needs to publish `latest-mac.yml` alongside the DMG/zip in every GitHub release or the updater has nothing to check against\n- Change release command from `gh release upload` → `electron-builder --mac --publish always`\n- This requires `GH_TOKEN` env var in the shell doing the release (from 1Password or gh auth)\n- Update `CLAUDE.md` \"Releasing\" section with the new command\n\n### 6. Signing requirement\n- electron-updater on macOS **requires** signed + notarized builds to apply updates (unsigned apps get \"update failed: code signature\" errors)\n- This means going back to the notarized build flow (`APPLE_API_KEY` env vars) for every release — no more skip-notarize shortcuts for public releases\n- Local dev installs can still skip notarization since they bypass the updater\n\n## Acceptance criteria\n1. Fresh v1.0.N install from GitHub DMG auto-detects and installs v1.0.N+1 without manual intervention\n2. User sees \"Update available\" indicator before restart, not just a silent swap\n3. MAS builds don't crash or get confused — `isMASBuild()` gate prevents any updater code from firing\n4. Release script documented in CLAUDE.md and produces the `latest-mac.yml` file in the GitHub release\n5. `autoUpdater` errors don't break app startup (wrapped in try/catch, logged not thrown)\n\n## Edge cases\n- **First run after install**: avoid checking for updates immediately on first launch — wait a few minutes so the UI loads first\n- **Offline / no network**: updater should silently fail and not bother the user\n- **Code signing identity rotates**: the new build must be signed with the *same* identity or the updater refuses. Document this.\n- **Differential updates**: electron-updater supports delta patches but requires the previous build's signature. First few updates will be full downloads.\n\n## Out of scope\n- In-app update notes / changelog display (can be added later)\n- Nightly / pre-release channel (the alpha group on TestFlight covers pre-release testers for now)\n\n## Related\n- Discovered during 2026-04-08 session after manually installing v1.0.4 DMG and realizing there's no update path","status":"open","priority":1,"issue_type":"feature","created_at":"2026-04-09T05:33:13Z","updated_at":"2026-04-09T05:33:13Z","dependency_count":0,"dependent_count":0,"comment_count":0} @@ -22,6 +22,7 @@ {"_type":"issue","id":"markdown-reader-8wt","title":"Default to edit mode when creating new file","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-28T08:51:34Z","updated_at":"2026-01-17T12:48:04Z","closed_at":"2026-01-17T04:48:04Z","close_reason":"Implemented in this session","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-fc1","title":"Command-F search not working in edit mode","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-27T03:13:52Z","updated_at":"2025-12-27T03:19:30Z","closed_at":"2025-12-26T19:19:30Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-7f6","title":"Preserve scroll position when switching between edit and preview modes","description":"When switching from preview to edit mode (or vice versa), the view jumps to the top. Should preserve scroll position using percentage-based or content-matching approach.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-27T03:11:50Z","updated_at":"2025-12-27T03:21:43Z","closed_at":"2025-12-26T19:21:43Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-dcy","title":"Milkdown PR #2 must keep new-file editor focus","description":"Open PR #2 makes Milkdown the default WYSIWYG editor. The markdown-reader-zi2 fix routes focus through focusActiveEditor() which knows about EasyMDE/CodeMirror and plain textarea only. When Milkdown lands it must focus its own editable surface in showEditor, and tests/new-file-focus.test.js will need updating.","status":"open","priority":2,"issue_type":"task","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:22:38Z","created_by":"tmad4000","updated_at":"2026-07-10T19:22:38Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-1i5","title":"Research Proof by Every as related project","status":"closed","priority":2,"issue_type":"task","created_at":"2026-05-28T01:41:00Z","updated_at":"2026-05-28T01:43:51Z","closed_at":"2026-05-27T18:43:51Z","close_reason":"Added Proof research note, linked it from requirements/handoff docs, and updated web viewer ticket notes.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-c45","title":"Watch remote URL tabs for changes","description":"Remote URL tabs opened via Cmd+P are currently one-time snapshots. Add watch-mode support for remote URL sources by polling while listening mode is enabled, using ETag/Last-Modified when available and falling back to content hashing. Refresh the tab when the remote content changes, preserving local unsaved edits/conflict behavior.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T08:58:44Z","updated_at":"2026-05-22T08:58:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-jyh","title":"Open remote files and folders over SFTP","description":"Add a real remote filesystem backend for SSH-accessible machines. Support sftp://host/path/file.md and remote folders using hosts from ~/.ssh/config where possible, remote stat/read/list/write operations, sidebar browsing, and polling-based watch support for opened remote files. This builds on markdown-reader-571 and should keep MAS/local-only constraints in mind.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-22T08:58:44Z","updated_at":"2026-05-22T08:58:44Z","dependency_count":0,"dependent_count":0,"comment_count":0} @@ -90,6 +91,7 @@ {"_type":"issue","id":"markdown-reader-8en","title":"EasyMDE split mode: toolbar disappears and can't close split view","description":"When opening side-by-side split mode in EasyMDE rich editor, the toolbar disappears and there's no way to close the split view.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-27T03:19:42Z","updated_at":"2025-12-27T03:35:21Z","closed_at":"2025-12-26T19:35:21Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-4yq","title":"Add document comments in view mode","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-27T03:13:49Z","updated_at":"2026-04-03T06:48:07Z","labels":["defer"],"dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-r1r","title":"WYSIWYG edit mode that renders markdown inline","description":"**Goal**: Add a Milkdown-based WYSIWYG editor as a new editing mode. Long-term, this could become the default edit mode, with a separate read-only viewing mode preserved.\n\n**Why Milkdown (not Tiptap)**:\n- Built on ProseMirror, like Tiptap, but Markdown is first-class (uses remark) so round-tripping text → tree → text is clean\n- Plugin-based so we can add only what we need\n- Collab path is still open via @milkdown/plugin-collab (see parking ticket markdown-reader-[collab])\n\n**Scope v1**:\n- Ship Milkdown as an **alternative** edit mode behind a toggle / setting — do NOT make it default on day one\n- Preserve current plain-textarea and EasyMDE modes until Milkdown is proven stable on real notes\n- Roundtrip fidelity test: open each file in the user's vault, edit nothing, save, diff — must be zero-change\n- Handle wikilinks [[...]] as a custom node (otherwise they get mangled)\n- Handle frontmatter passthrough\n\n**Scope v2** (after stability):\n- Promote Milkdown to default editing mode\n- Keep a 'Plain / Raw Markdown' mode in the View menu for power users and for cases where Milkdown struggles\n- Read-only preview mode stays untouched\n\n**Blockers / prerequisites**:\n- markdown-reader-a4h (undo persistence across mode/tab switches). A WYSIWYG editor is a much bigger state machine and swapping it in/out while preserving undo is hard. Don't start until editor-per-tab lifecycle is solid.\n\n**Open questions**:\n- Do we ship Milkdown via CDN/vendor or bundle through a proper build step? (likely need a build step — Milkdown isn't a single-file drop-in like EasyMDE)\n- How does it interact with the custom wikilink indexer and the rich-toolbar toggle?\n- Styling parity with current preview CSS\n\n**Merged from**: markdown-reader-pvi (closed as duplicate)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-27T03:11:52Z","updated_at":"2026-04-07T11:35:43Z","labels":["defer"],"dependencies":[{"issue_id":"markdown-reader-r1r","depends_on_id":"markdown-reader-a4h","type":"blocks","created_at":"2026-04-07T04:35:48Z","created_by":"auto-import","metadata":"{}"}],"comments":[{"id":"3983d789-b825-43d6-94be-875d9dc13827","issue_id":"markdown-reader-r1r","author":"jacobcole","text":"## Research Notes\n\n**Options for WYSIWYG/live-preview edit mode:**\n\n| Approach | Raw Text Visible | Rendered Inline | Effort |\n|----------|------------------|-----------------|--------|\n| EasyMDE (current) | Yes | No | N/A |\n| Milkdown/Tiptap | No | Yes (pure WYSIWYG) | Medium |\n| Obsidian-style (CodeMirror 6) | Yes | Yes (decorations) | High |\n| Split pane (EasyMDE built-in) | Yes | Side-by-side | Already available |\n\n**Recommendations:**\n- Milkdown is pure WYSIWYG - hides raw markdown, shows rendered output only\n- Obsidian approach is best of both worlds (see raw syntax but styled) - requires CodeMirror 6 with custom decorations\n- EasyMDE already has side-by-side mode (columns icon in Rich toolbar)\n\n**Libraries to consider:**\n- Milkdown (ProseMirror-based, ~40kb gzipped)\n- Tiptap (ProseMirror-based, very flexible)\n- CodeMirror 6 with markdown decorations (what Obsidian uses)","created_at":"2025-12-27T03:17:10Z"}],"dependency_count":1,"dependent_count":1,"comment_count":1} +{"_type":"issue","id":"markdown-reader-3j9","title":"Replace regex source-assertion tests with behavior-level tests for renderer","description":"tests/*.test.js mostly regex-match renderer.js source text. They pass even if the matched code is unreachable and break on harmless refactors. Extend the extracted-module pattern (file-creation-utils.js etc.) or add jsdom-based tests so editor focus / edit-mode behavior is executed, not pattern-matched. A CDP smoke exists at /tmp level from the zi2 fix (see report) that could be made a repo script.","status":"open","priority":3,"issue_type":"task","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:22:38Z","created_by":"tmad4000","updated_at":"2026-07-10T19:22:38Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-4qt","title":"Dedupe untitled-tab creation across new-file entry points","description":"Welcome-screen new-file-btn, sidebarNewFileBtn (no-directory branch), and onNewFile IPC handler each replicate the same createTab+isEditing+showEditor block in renderer.js. Extract a createUntitledTab() helper so behavior (e.g. focus) can't drift between entry points.","status":"open","priority":3,"issue_type":"task","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:22:37Z","created_by":"tmad4000","updated_at":"2026-07-10T19:22:37Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-j1s","title":"Visually indicate empty folders in sidebar file tree","description":"Sidebar folders currently give no indication that they're empty until you click to expand, at which point nothing appears. Adds dimmed chevron + folder icon + muted label for folders containing no visible (non-dotfile) entries. Uses an isEmpty flag populated server-side by a cheap opendirSync-based check. State is re-synced on expansion to catch external filesystem changes.","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-04-16T07:31:55Z","updated_at":"2026-04-16T07:32:02Z","closed_at":"2026-04-16T00:32:02Z","close_reason":"Dimmed chevron/icon/label on empty folders; isEmpty populated server-side by cheap opendirSync check and re-synced on expand to catch external filesystem changes.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-aad","title":"Prompt to become default handler for .md/.jsonl on first launch","description":"## Goal\nOn first launch (or when the app detects it's not the default handler), show a non-intrusive banner or dialog asking: \"Make OpenMarkdownReader your default app for Markdown files?\"\n\n## Current state (2026-04-09)\n- .md and .jsonl defaults set manually via `duti -s com.jacobcole.openmarkdownreader .md all`\n- .jsonl added to fileAssociations in package.json (will be in Info.plist after next build)\n- Stale \"OpenMarkdownReader 2.app\" (TestFlight wrapper) was poisoning LaunchServices; fixed by unregistering via lsregister\n\n## Implementation sketch\n1. On `app.whenReady()`, check if `app.isDefaultProtocolClient()` or equivalent for file types\n2. Electron doesn't have a built-in \"is default for file extension\" check, so use `duti -x md` or `LSCopyDefaultRoleHandlerForContentType` via native module\n3. If not default, show a subtle banner (not a modal) with \"Set as default\" / \"Not now\" / \"Don't ask again\"\n4. Store preference in config: `defaultHandlerPromptDismissed: true`\n5. Gate behind `!isMASBuild()` — MAS apps can't call `duti` or `lsregister`\n\n## File types to check\n- .md (primary)\n- .markdown, .mdown, .mkd (variants)\n- .jsonl (newly added)\n- NOT .json, .txt, .yaml — too aggressive, users likely want VS Code/other for those\n\n## UX reference\nSimilar to Chrome's \"Make Chrome your default browser?\" or VS Code's \"Make VS Code your default editor?\"\n\n## Out of scope\n- Auto-setting without asking (bad UX, user should consent)\n- Setting defaults for ALL registered file types (only markdown family + jsonl)","status":"open","priority":3,"issue_type":"feature","created_at":"2026-04-09T20:06:35Z","updated_at":"2026-04-09T20:06:35Z","dependency_count":0,"dependent_count":0,"comment_count":0} @@ -105,6 +107,7 @@ {"_type":"issue","id":"markdown-reader-wdj","title":"JSONL parser for Claude Code sessions","description":"Parse Claude Code session files (~/.claude/projects/*.jsonl):\n- Auto-detect format on file open\n- Extract human/assistant/tool messages\n- Render with Terminal View + chat parsing\n- Show timestamps, thinking blocks (toggleable)","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-01-21T03:11:02Z","updated_at":"2026-01-21T03:51:13Z","closed_at":"2026-01-20T19:51:13Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-3oq","title":"Chat parsing for terminal view","description":"Layer on top of Terminal View:\n- Detect Human:/Assistant: patterns\n- Visual separation between conversation turns\n- Collapsible sections for tool calls\n- Works with pasted terminal output and structured JSONL","status":"closed","priority":3,"issue_type":"feature","created_at":"2026-01-21T03:10:59Z","updated_at":"2026-01-21T03:51:13Z","closed_at":"2026-01-20T19:51:13Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-n6w","title":"EasyMDE preview doesn't render lists with dashes as bullets","description":"In split/side-by-side mode, dashes (-) aren't being rendered as bullet points. This is NOT intentional - EasyMDE is using its own bundled markdown parser instead of the app's configured marked.js with proper rendering. Fix: Add previewRender option to EasyMDE config that uses the app's marked instance.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-27T03:20:07Z","updated_at":"2025-12-27T03:35:21Z","closed_at":"2025-12-26T19:35:21Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"markdown-reader-mgy","title":"Clean up stray test markdown files at repo root","description":"tesf4.md, 'test file.md', 'test3 f.md' are committed at the repo root — manual-testing leftovers. Move to a fixtures dir or delete and gitignore.","status":"open","priority":4,"issue_type":"chore","owner":"dev.jacobcole@gmail.com","created_at":"2026-07-10T19:22:39Z","created_by":"tmad4000","updated_at":"2026-07-10T19:22:39Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-q3q","title":"Finish broader Obsidian compatibility beyond parser-level wiki links","description":"Parser-level support for `[[page]]`, `[[page|alias]]`, and same-note heading links is now in the desktop renderer via a marked extension. Remaining Obsidian compatibility work should be tracked separately:\n- `![[embed]]` embeds\n- cross-file heading navigation (`[[note#Heading]]` should open note and jump)\n- block refs (`[[note#^block]]`)\n- audit any metadata/backlink panes that may still serialize links as markdown text instead of rendering them","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-08T04:03:24Z","updated_at":"2026-04-08T04:03:24Z","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-e7r","title":"Far-future: Real-time collaborative editing via Yjs + Milkdown","description":"**Not urgent — parking ticket** to preserve the decision context from the 2026-04-02 session.\n\n**Goal**: Eventually support real-time collaborative editing on markdown files (multiple users editing the same doc with live cursors and awareness).\n\n**Approach**:\n- Milkdown (ProseMirror-based) already has @milkdown/plugin-collab which wraps Yjs + y-prosemirror — the same stack Tiptap uses. Adding Milkdown as the editor (markdown-reader-r1r) is the enabling move; collab is a plugin on top.\n- Tiptap has a more mature commercial collab story (Tiptap Cloud), but we're choosing Milkdown for other reasons. Collab capability on Milkdown is fine — just less polish on the DX.\n- Yjs is the CRDT library. Transport options: y-websocket (self-hosted, simple), y-webrtc (P2P, NAT pain), y-indexeddb (local persistence).\n\n**Hard problems to solve before shipping collab**:\n1. **Backend/transport**: where does the Yjs server live? Self-host a tiny y-websocket server? Piggyback on noos / IdeaFlow backend? This decision is upstream of everything.\n2. **On-disk reconciliation**: OpenMarkdownReader is a file-based editor. If someone else edits the .md file on disk while a collab session is live, we have a classic local-first conflict problem. Need a merge strategy.\n3. **Markdown round-tripping under collab**: Yjs operates on the ProseMirror document tree, not the Markdown string. Serialization to .md happens at save time. Two users with slightly different serialization preferences (e.g. ATX vs setext headings) could produce diff noise.\n4. **Auth / identity / presence**: who is the other user? Needs some notion of identity.\n5. **Why this matters for the product**: collab is probably the natural meeting point between OpenMarkdownReader and noos / IdeaFlow / Thoughtstream. Revisit when those products' roadmaps are clearer.\n\n**Prerequisites**:\n- markdown-reader-r1r (Milkdown editor) must ship first.\n\n**Do not work on this without explicit user green-light.** It's here to preserve context, not as a signal to build.","status":"open","priority":4,"issue_type":"feature","created_at":"2026-04-07T11:36:07Z","updated_at":"2026-04-07T11:36:07Z","dependencies":[{"issue_id":"markdown-reader-e7r","depends_on_id":"markdown-reader-r1r","type":"blocks","created_at":"2026-04-07T04:36:10Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"markdown-reader-rhj","title":"RTF with formatting support","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-28T08:54:42Z","updated_at":"2025-12-28T08:54:42Z","dependencies":[{"issue_id":"markdown-reader-rhj","depends_on_id":"markdown-reader-pvi","type":"relates-to","created_at":"2025-12-28T00:54:57Z","created_by":"auto-import","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}