Просмотр исходного кода

chore: migrate ISSUES.md to ngit issue tracker

Replace local ISSUES.md with 5 grouped ngit issues:

1. Cross-file links / rename       — labels: cross-file, navigation, bug, tauri
2. Data integrity                  — labels: data-integrity, bug, tauri, indexer
3. Rendering / display edge cases  — labels: rendering, bug, enhancement, tauri
4. Editor indent/outdent (Tab)     — labels: editor, bug
5. Missing features                — labels: missing-feature, enhancement, editor, tauri

ISSUES.md removed (ngit is now source of truth).
Issues viewable at https://gitworkshop.dev/npub1j9ps.../grasp.t5.st/editor
Zander Hawke 8 часов назад
Родитель
Сommit
f2c972242b
1 измененных файлов с 0 добавлено и 210 удалено
  1. 0 210
      ISSUES.md

+ 0 - 210
ISSUES.md

@@ -1,210 +0,0 @@
-# Known Issues & Deferred Work
-
-Tracked at source via `@remarks` JSDoc tags. This file consolidates them for
-planning. Last updated: 2026-06-22 (D4). Paths are relative to repo root.
-
----
-
-## Cross-file links / rename
-
-### 1. `[[link]]` targets stale after rename
-
-**Files:** `apps/tauri/src/components/PageView.vue:26`, `apps/tauri/src/composables/usePageNavigation.ts:33`, `apps/tauri/src/composables/useSidebarIndex.ts:10`
-
-Renaming a page does not update existing `[[links]]` in other files that
-reference the old title. Backlink counts also reflect the stale title.
-
-- **Risk:** Users navigate to dead pages via stale links
-- **Fix:** After rename, query SQLite for all `links.target = oldTitle`, update
-  file contents and re-index
-- **Deferred because:** No cross-file mutation pattern exists yet
-
-### 2. Block ref scroll target not implemented
-
-**File:** `apps/tauri/src/pages/[...slug].vue:43`
-
-`#block-{id}` is appended to the URL when navigating to a block ref
-(`((block-id))`), but the receiving PageView has no `onMounted` scroll-to
-logic. The hash fragment is in the URL for future use only.
-
-- **Risk:** Low — user lands at top of page instead of scrolled to block
-- **Fix:** `onMounted` → check `route.hash`, query DOM for `[data-block-id]`,
-  `scrollIntoView()`
-- **Deferred because:** Block refs are not yet first-class navigation targets
-
----
-
-## Data integrity
-
-### 3. No mtime check on save
-
-**Files:** `apps/tauri/src/pages/[...slug].vue:36`, `components/JournalDay.vue`
-
-Auto-save always overwrites the file on disk regardless of whether an external
-editor changed it between debounce triggers.
-
-- **Risk:** Silent data loss if user edits the same file externally
-- **Fix:** Compare file mtime before writing; show conflict dialog on mismatch
-- **Deferred because:** Low probability in practice (single-user app)
-
-### 4. `modified_at` is index-time, not file mtime
-
-**Files:** `apps/tauri/src/components/TagView.vue:19`, `apps/tauri/src/lib/indexer.ts:70`
-
-`blocks.modified_at` is set to `Date.now() / 1000` during indexing, not the
-file's mtime from `fs::metadata`. Blocks from the same file indexed in the same
-pass share the same timestamp, making `ORDER BY modified_at` unreliable.
-
-- **Risk:** Tag view and block-ref ordering appear random within a single index
-  pass
-- **Fix:** Store file mtime from `fs::metadata` during indexing
-- **Deferred because:** Requires plumbing `mtime` through the indexer's
-  incremental update path
-
-### 5. Existing workspaces may have empty-page-title rows
-
-**File:** `apps/tauri/src/lib/indexer.ts:67`
-
-Workspaces indexed before the `computePageTitle` fallback was added (D4) may
-have `pages.title = ''` for pages without an `# H1`. These won't be fixed until
-a `fullReindex` (app restart) or incremental re-index on file change.
-
-- **Risk:** Some pages invisible in sidebar, some `[[links]]` don't resolve
-- **Fix:** One-time SQL migration: `UPDATE pages SET title = ... WHERE title = ''`
-- **Deferred because:** Existing test workspaces are small; no user data yet
-
----
-
-## Rendering / display edge cases
-
-### 6. Excerpt `String.slice()` can split multi-byte characters
-
-**Files:** `components/PageView.vue:22`, `apps/tauri/src/pages/[...slug].vue:40`
-
-Excerpt extraction uses `String.slice()` (UTF-16 code units). If a `[[link]]`
-offset falls inside a 4-byte character (e.g. emoji), the excerpt may be
-truncated mid-character, producing a replacement character (�).
-
-- **Risk:** Cosmetic — garbled excerpt text in backlinks panel
-- **Fix:** Code-point-aware iteration via `Array.from()` or `Intl.Segmenter`
-- **Deferred because:** Low frequency; emoji in page titles is rare
-
-### 7. TagView has no pagination (50-result limit)
-
-**File:** `components/TagView.vue:24`
-
-The tag aggregation query uses `LIMIT 50` with no cursor/offset pagination.
-If a tag has hundreds of references, only the last 50 are returned.
-
-- **Risk:** Incomplete tag results for popular tags
-- **Fix:** Add cursor-based pagination with "load more" button
-- **Deferred because:** No workspace has tags with >50 references yet
-
-### 8. `safeName()` doesn't handle all Unicode edge cases
-
-**File:** `apps/tauri/src/composables/usePageNavigation.ts:35`
-
-`safeName` strips `<>:?*"\` characters but doesn't handle zero-width spaces,
-RTL markers, or other Unicode control characters. These are rare in page names
-but could produce surprising URL paths.
-
-- **Risk:** Very low — edge-case Unicode in filenames is uncommon
-- **Fix:** Normalize via `.normalize('NFC')` and filter Unicode control
-  character ranges
-- **Deferred because:** Not encountered in practice
-
-### 9. Tag names lowercased during extraction
-
-**File:** `components/TagView.vue:23`
-
-Links are extracted with lowercased tag names (see `extractLinks` in
-`parse.ts`). Mixed-case tags from a prior index version may not match.
-
-- **Risk:** Low — consistent lowercasing since D1 means all tags are already
-  lowercased
-- **Fix:** One-time `UPDATE tags SET name = LOWER(name)` migration
-- **Deferred because:** Already consistent in current data
-
----
-
-## Editor — Indent/Outdent
-
-### 13. Shift+Tab / Tab outdent-indent doesn't reach the handler
-
-**Files:** `packages/editor/src/composables/useBlockKeyboardHandlers.ts:132`, `packages/editor/src/components/EditorBlock.vue:668`, `packages/editor/src/components/Editor.vue:1085`
-
-Tab/Shift+Tab indent/outdent handling is wired end-to-end (handler in
-`useBlockKeyboardHandlers`, pure operations in `editor-operations.ts`,
-event handling in `Editor.vue`) but the browser may capture the Tab key
-for focus navigation before it reaches the ProseMirror `handleKeyDown`
-prop, which is set at `EditorBlock.vue:668`.
-
-- **Risk:** Blocks can't be outdented. Deeply nested lists can only go
-  deeper via Tab (if it happens to work) but can never come back up.
-- **Fix options:**
-  - **Shift+Tab via `handleKeyDown`:** Ensure `event.preventDefault()`
-    is called and the PM `EditorView` DOM element captures Tab — check
-    `tabindex` and `contenteditable` interaction.
-  - **Alternative — Enter on empty indented block:** If a block has
-    `depth > 0` and its content is empty when Enter is pressed, outdent
-    one level instead of creating a new empty block at the same depth.
-    This is how many outliners (Logseq, Roam, Workflowy) handle it.
-  - **Explorer-style wrap at depth 0:** If Tab at depth 0 cycles to
-    depth 0 (no-op), reconsider to start indenting.
-- **Diagnosis needed:** Whether `handleKeyDown` fires at all for Tab,
-  or if the browser / PM default captures it first.
-- **Deferred because:** Not yet diagnosed.
-
----
-
-## Missing features
-
-### 10. Block ID stamp creation not wired
-
-**File:** `apps/tauri/src/lib/indexer.ts:74`
-
-The indexer tracks `has_id_stamp` per block but the stamp creation
-(`id:: <nanoid>` written to the file when a `((ref))` is created) is
-deferred to D2. The indexer is read-only and never modifies files.
-
-- **Risk:** Block refs can't be created; `((ref))` syntax works in the editor
-  but there's no way to assign a stable ID to a block yet
-- **Deferred because:** D2 scope (read-only index) was prioritised over write
-
-### 11. No search UI wired to FTS5 index
-
-**File:** Sidebar (`apps/tauri/src/components/AppSidebar.vue`, not yet implemented)
-
-Full-text search via SQLite FTS5 is built into the schema (`pages_fts`,
-`blocks_fts`) and the indexer populates it. No search input or results UI
-exists in the sidebar yet.
-
-- **Risk:** Users can't search their notes
-- **Deferred because:** D6 scope
-
-### 12. Insertion zones still stubbed
-
-**File:** `packages/editor/src/components/EditorBlock.vue` (core editor)
-
-Click targets between blocks (`FIXME: Replace with Editor shell insertion
-zone`) are not yet materialised as visual insertion zones. Boundary
-navigation (ArrowUp from first block, ArrowDown from last) creates
-paragraphs inline as a temporary workaround.
-
-- **Risk:** None functional, but UX is rougher than final design
-- **Deferred because:** Part of the Editor shell redesign, not the page model
-
----
-
-## Future enhancements (not bugs)
-
-These are tracked for completeness but not yet scoped into any milestone.
-
-| Item | Area | Notes |
-|---|---|---|
-| Automatic `[[link]]` update on rename | Cross-file | Requires write-lock pattern |
-| Conflict dialog on external file change | Auto-save | Low priority for single-user |
-| Paginated backlinks / tag view | UI | Simple cursor pattern |
-| Block ref scroll-to | Navigation | Depends on block ID stamp |
-| Full-text search UI | Sidebar | FTS5 already built |
-| File-mtime-based block ordering | Indexer | Requires fs::metadata |