@peaske7/readit 0.2.0 → 0.3.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +118 -76
- package/.claude/commands/review.md +1 -1
- package/.claude/roadmap.md +32 -9
- package/.claude/user-stories.md +100 -15
- package/AGENTS.md +30 -26
- package/Makefile +32 -0
- package/README.md +90 -2
- package/biome.json +18 -8
- package/bun.lock +426 -568
- package/bunfig.toml +2 -0
- package/docs/perf-baseline.md +56 -1
- package/docs/superpowers/specs/2026-03-27-go-server-rewrite-design.md +284 -0
- package/e2e/comments.spec.ts +14 -58
- package/e2e/document-load.spec.ts +1 -23
- package/e2e/export.spec.ts +4 -4
- package/e2e/perf/add-comment.spec.ts +9 -11
- package/e2e/perf/fixtures/generate.ts +1 -5
- package/e2e/perf/screenshot-final.png +0 -0
- package/e2e/perf/utils/metrics.ts +73 -9
- package/e2e/persistence-file.spec.ts +41 -26
- package/e2e/utils/selection.ts +17 -73
- package/go/cmd/readit/main.go +416 -0
- package/go/go.mod +20 -0
- package/go/go.sum +41 -0
- package/go/internal/server/anchor.go +302 -0
- package/go/internal/server/anchor_test.go +111 -0
- package/go/internal/server/comments.go +390 -0
- package/go/internal/server/documents.go +113 -0
- package/go/internal/server/embed.go +17 -0
- package/go/internal/server/headings.go +33 -0
- package/go/internal/server/headings_test.go +75 -0
- package/go/internal/server/htmltext.go +123 -0
- package/go/internal/server/markdown.go +157 -0
- package/go/internal/server/markdown_bench_test.go +42 -0
- package/go/internal/server/markdown_test.go +79 -0
- package/go/internal/server/server.go +453 -0
- package/go/internal/server/server_bench_test.go +122 -0
- package/go/internal/server/settings.go +110 -0
- package/go/internal/server/sse.go +140 -0
- package/go/internal/server/storage.go +275 -0
- package/go/internal/server/storage_test.go +152 -0
- package/go/internal/server/template.go +66 -0
- package/go/internal/server/types.go +101 -0
- package/go/internal/server/watcher.go +74 -0
- package/index.html +4 -14
- package/nvim-readit/lua/readit/health.lua +64 -0
- package/nvim-readit/lua/readit/init.lua +463 -0
- package/nvim-readit/plugin/readit.lua +19 -0
- package/package.json +20 -28
- package/shell/_readit +158 -0
- package/shell/readit.zsh +87 -0
- package/src/App.svelte +890 -0
- package/src/cli.ts +183 -21
- package/src/components/ActionsMenu.svelte +95 -0
- package/src/components/CommentBadge.svelte +67 -0
- package/src/components/CommentErrorBanner.svelte +33 -0
- package/src/components/CommentInput.svelte +75 -0
- package/src/components/CommentListItem.svelte +95 -0
- package/src/components/CommentManager.svelte +129 -0
- package/src/components/CommentNav.svelte +109 -0
- package/src/components/DocumentViewer.svelte +233 -0
- package/src/components/FloatingComment.svelte +107 -0
- package/src/components/Header.svelte +76 -0
- package/src/components/InlineEditor.svelte +72 -0
- package/src/components/MarginNote.svelte +167 -0
- package/src/components/MarginNotesContainer.svelte +33 -0
- package/src/components/MermaidEnhancer.svelte +218 -0
- package/src/components/MermaidModal.svelte +67 -0
- package/src/components/RawModal.svelte +126 -0
- package/src/components/ReanchorConfirm.svelte +30 -0
- package/src/components/SettingsModal.svelte +220 -0
- package/src/components/ShortcutCapture.svelte +82 -0
- package/src/components/ShortcutList.svelte +145 -0
- package/src/components/TabBar.svelte +52 -0
- package/src/components/TableOfContents.svelte +125 -0
- package/src/components/ui/ActionLink.svelte +40 -0
- package/src/components/ui/{Button.tsx → Button.svelte} +19 -20
- package/src/components/ui/Dialog.svelte +97 -0
- package/src/components/ui/DropdownMenu.svelte +85 -0
- package/src/components/ui/DropdownMenuItem.svelte +38 -0
- package/src/components/ui/DropdownMenuSeparator.svelte +11 -0
- package/src/components/ui/{Text.tsx → Text.svelte} +18 -23
- package/src/env.d.ts +6 -0
- package/src/index.css +141 -166
- package/src/lib/__fixtures__/bench-data.ts +0 -13
- package/src/lib/anchor.bench.ts +1 -12
- package/src/lib/anchor.test.ts +0 -8
- package/src/lib/anchor.ts +0 -4
- package/src/lib/comment-storage.bench.ts +49 -0
- package/src/lib/comment-storage.test.ts +103 -33
- package/src/lib/comment-storage.ts +25 -18
- package/src/lib/export.bench.ts +21 -0
- package/src/lib/export.ts +0 -1
- package/src/lib/fetch-or-throw.test.ts +59 -0
- package/src/lib/fetch-or-throw.ts +12 -0
- package/src/{hooks/useHeadings.test.ts → lib/headings.test.ts} +10 -24
- package/src/{hooks/useHeadings.ts → lib/headings.ts} +11 -13
- package/src/lib/highlight/core.test.ts +0 -5
- package/src/lib/highlight/dom.ts +52 -216
- package/src/lib/highlight/highlight-registry.ts +221 -0
- package/src/lib/highlight/highlight.bench.ts +92 -0
- package/src/lib/highlight/highlighter.ts +112 -132
- package/src/lib/highlight/resolver.ts +5 -79
- package/src/lib/highlight/types.ts +0 -5
- package/src/lib/html-text.test.ts +162 -0
- package/src/lib/html-text.ts +161 -0
- package/src/lib/i18n/en.ts +34 -0
- package/src/lib/i18n/ja.ts +34 -0
- package/src/lib/i18n/types.ts +33 -0
- package/src/lib/key-lock.test.ts +104 -0
- package/src/lib/key-lock.ts +23 -0
- package/src/lib/margin-layout.bench.ts +61 -0
- package/src/lib/margin-layout.ts +0 -7
- package/src/lib/markdown-renderer.test.ts +154 -0
- package/src/lib/markdown-renderer.ts +178 -0
- package/src/lib/mermaid-config.ts +38 -0
- package/src/lib/mermaid-renderer.ts +162 -0
- package/src/lib/mermaid-worker.ts +60 -0
- package/src/lib/positions.ts +31 -24
- package/src/lib/shortcut-registry.ts +244 -0
- package/src/lib/utils.ts +0 -29
- package/src/main.ts +16 -0
- package/src/schema.ts +16 -5
- package/src/server.ts +355 -95
- package/src/stores/app.svelte.ts +231 -0
- package/src/stores/locale.svelte.ts +46 -0
- package/src/stores/settings.svelte.ts +90 -0
- package/src/stores/shortcuts.svelte.ts +104 -0
- package/src/stores/ui.svelte.ts +12 -0
- package/src/template.ts +104 -0
- package/src/test-setup.ts +47 -0
- package/svelte.config.js +5 -0
- package/tsconfig.json +2 -2
- package/vite.config.ts +23 -3
- package/vscode-readit/.mcp.json +7 -0
- package/vscode-readit/.vscodeignore +7 -0
- package/vscode-readit/bun.lock +78 -0
- package/vscode-readit/icon.svg +10 -0
- package/vscode-readit/package.json +110 -0
- package/vscode-readit/src/extension.ts +117 -0
- package/vscode-readit/src/server-manager.ts +272 -0
- package/vscode-readit/src/webview-provider.ts +204 -0
- package/vscode-readit/tsconfig.json +20 -0
- package/e2e/fixtures/sample.html +0 -13
- package/src/App.tsx +0 -368
- package/src/components/ActionsMenu.tsx +0 -91
- package/src/components/DocumentViewer/CodeBlock.tsx +0 -160
- package/src/components/DocumentViewer/DocumentViewer.tsx +0 -230
- package/src/components/DocumentViewer/MermaidDiagram.tsx +0 -136
- package/src/components/Header.tsx +0 -54
- package/src/components/InlineEditor.tsx +0 -74
- package/src/components/MarginNote.tsx +0 -185
- package/src/components/MarginNotes.tsx +0 -23
- package/src/components/RawModal.tsx +0 -144
- package/src/components/ReanchorConfirm.tsx +0 -36
- package/src/components/SettingsModal.tsx +0 -232
- package/src/components/TabBar.tsx +0 -60
- package/src/components/TableOfContents.tsx +0 -108
- package/src/components/comments/CommentBadge.tsx +0 -49
- package/src/components/comments/CommentInput.tsx +0 -86
- package/src/components/comments/CommentListItem.tsx +0 -90
- package/src/components/comments/CommentManager.tsx +0 -129
- package/src/components/comments/CommentNav.tsx +0 -109
- package/src/components/ui/ActionLink.tsx +0 -28
- package/src/components/ui/Dialog.tsx +0 -116
- package/src/components/ui/DropdownMenu.tsx +0 -158
- package/src/contexts/CommentContext.tsx +0 -198
- package/src/contexts/LocaleContext.tsx +0 -76
- package/src/contexts/PositionsContext.tsx +0 -16
- package/src/contexts/SettingsContext.tsx +0 -133
- package/src/hooks/useClickOutside.ts +0 -31
- package/src/hooks/useCommentNavigation.ts +0 -107
- package/src/hooks/useComments.ts +0 -311
- package/src/hooks/useDocument.ts +0 -157
- package/src/hooks/useScrollSpy.ts +0 -77
- package/src/hooks/useTextSelection.ts +0 -86
- package/src/lib/highlight/worker.ts +0 -45
- package/src/main.tsx +0 -13
- package/src/store.ts +0 -222
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
package server
|
|
2
|
+
|
|
3
|
+
type Comment struct {
|
|
4
|
+
ID string `json:"id"`
|
|
5
|
+
SelectedText string `json:"selectedText"`
|
|
6
|
+
Comment string `json:"comment"`
|
|
7
|
+
CreatedAt string `json:"createdAt"`
|
|
8
|
+
StartOffset int `json:"startOffset"`
|
|
9
|
+
EndOffset int `json:"endOffset"`
|
|
10
|
+
LineHint string `json:"lineHint,omitempty"`
|
|
11
|
+
AnchorConfidence string `json:"anchorConfidence,omitempty"`
|
|
12
|
+
AnchorPrefix string `json:"anchorPrefix,omitempty"`
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type Heading struct {
|
|
16
|
+
ID string `json:"id"`
|
|
17
|
+
Text string `json:"text"`
|
|
18
|
+
Level int `json:"level"`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type FileState struct {
|
|
22
|
+
FilePath string
|
|
23
|
+
FileName string
|
|
24
|
+
Content []byte
|
|
25
|
+
RenderedHTML string
|
|
26
|
+
Headings []Heading
|
|
27
|
+
IsLoaded bool
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type ShortcutBinding struct {
|
|
31
|
+
Key string `json:"key"`
|
|
32
|
+
Alt bool `json:"alt,omitempty"`
|
|
33
|
+
Ctrl bool `json:"ctrl,omitempty"`
|
|
34
|
+
Meta bool `json:"meta,omitempty"`
|
|
35
|
+
Shift bool `json:"shift,omitempty"`
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type Keybinding struct {
|
|
39
|
+
ID string `json:"id"`
|
|
40
|
+
Binding *ShortcutBinding `json:"binding,omitempty"`
|
|
41
|
+
Enabled bool `json:"enabled"`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type Settings struct {
|
|
45
|
+
Version int `json:"version"`
|
|
46
|
+
FontFamily string `json:"fontFamily"`
|
|
47
|
+
Keybindings []Keybinding `json:"keybindings,omitempty"`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type CommentFile struct {
|
|
51
|
+
Source string
|
|
52
|
+
Hash string
|
|
53
|
+
Version int
|
|
54
|
+
Comments []Comment
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type InlineData struct {
|
|
58
|
+
Files []FileRef `json:"files"`
|
|
59
|
+
ActiveFile string `json:"activeFile"`
|
|
60
|
+
Clean bool `json:"clean"`
|
|
61
|
+
WorkingDir string `json:"workingDirectory"`
|
|
62
|
+
Documents map[string]InlineDocData `json:"documents"`
|
|
63
|
+
Settings Settings `json:"settings"`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
type FileRef struct {
|
|
67
|
+
Path string `json:"path"`
|
|
68
|
+
FileName string `json:"fileName"`
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type InlineDocData struct {
|
|
72
|
+
Headings []Heading `json:"headings"`
|
|
73
|
+
Comments []Comment `json:"comments"`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const (
|
|
77
|
+
AnchorExact = "exact"
|
|
78
|
+
AnchorNormalized = "normalized"
|
|
79
|
+
AnchorFuzzy = "fuzzy"
|
|
80
|
+
AnchorUnresolved = "unresolved"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
const (
|
|
84
|
+
FontSerif = "serif"
|
|
85
|
+
FontSansSerif = "sans-serif"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
const (
|
|
89
|
+
FormatVersion = 1
|
|
90
|
+
HashLength = 16
|
|
91
|
+
MaxSelectionLength = 1000
|
|
92
|
+
TruncationMarker = "\n...\n"
|
|
93
|
+
AnchorPrefixLength = 200
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const (
|
|
97
|
+
DefaultSearchWindow = 500
|
|
98
|
+
DefaultFuzzyThreshold = 5
|
|
99
|
+
MaxFuzzyTextLength = 200
|
|
100
|
+
FuzzySearchWindow = 2000
|
|
101
|
+
)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
package server
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"sync"
|
|
5
|
+
"time"
|
|
6
|
+
|
|
7
|
+
"github.com/fsnotify/fsnotify"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
type Watcher struct {
|
|
11
|
+
fsWatcher *fsnotify.Watcher
|
|
12
|
+
debounce map[string]*time.Timer
|
|
13
|
+
onChange func(filePath string)
|
|
14
|
+
mu sync.Mutex
|
|
15
|
+
done chan struct{}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func NewWatcher(onChange func(string)) (*Watcher, error) {
|
|
19
|
+
fsw, err := fsnotify.NewWatcher()
|
|
20
|
+
if err != nil {
|
|
21
|
+
return nil, err
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
w := &Watcher{
|
|
25
|
+
fsWatcher: fsw,
|
|
26
|
+
debounce: make(map[string]*time.Timer),
|
|
27
|
+
onChange: onChange,
|
|
28
|
+
done: make(chan struct{}),
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
go w.loop()
|
|
32
|
+
return w, nil
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func (w *Watcher) loop() {
|
|
36
|
+
for {
|
|
37
|
+
select {
|
|
38
|
+
case event, ok := <-w.fsWatcher.Events:
|
|
39
|
+
if !ok {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if event.Has(fsnotify.Write) || event.Has(fsnotify.Create) {
|
|
43
|
+
w.debounceChange(event.Name)
|
|
44
|
+
}
|
|
45
|
+
case _, ok := <-w.fsWatcher.Errors:
|
|
46
|
+
if !ok {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
case <-w.done:
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
func (w *Watcher) debounceChange(path string) {
|
|
56
|
+
w.mu.Lock()
|
|
57
|
+
defer w.mu.Unlock()
|
|
58
|
+
|
|
59
|
+
if t, ok := w.debounce[path]; ok {
|
|
60
|
+
t.Stop()
|
|
61
|
+
}
|
|
62
|
+
w.debounce[path] = time.AfterFunc(100*time.Millisecond, func() {
|
|
63
|
+
w.onChange(path)
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
func (w *Watcher) Add(path string) error {
|
|
68
|
+
return w.fsWatcher.Add(path)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
func (w *Watcher) Close() {
|
|
72
|
+
close(w.done)
|
|
73
|
+
_ = w.fsWatcher.Close()
|
|
74
|
+
}
|
package/index.html
CHANGED
|
@@ -3,20 +3,10 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>readit
|
|
7
|
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
-
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📖</text></svg>">
|
|
10
|
-
<script>
|
|
11
|
-
(() => {
|
|
12
|
-
var t = localStorage.getItem("readit:theme");
|
|
13
|
-
var d = t === "dark" || (t !== "light" && matchMedia("(prefers-color-scheme: dark)").matches);
|
|
14
|
-
if (d) document.documentElement.classList.add("dark");
|
|
15
|
-
})();
|
|
16
|
-
</script>
|
|
6
|
+
<title>readit</title>
|
|
17
7
|
</head>
|
|
18
|
-
<body
|
|
19
|
-
<div id="
|
|
20
|
-
<script type="module" src="/src/main.
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
21
11
|
</body>
|
|
22
12
|
</html>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
-- Health check for readit.nvim
|
|
2
|
+
-- Run with :checkhealth readit
|
|
3
|
+
|
|
4
|
+
local M = {}
|
|
5
|
+
|
|
6
|
+
function M.check()
|
|
7
|
+
vim.health.start("readit.nvim")
|
|
8
|
+
|
|
9
|
+
-- Check bun
|
|
10
|
+
local readit = require("readit")
|
|
11
|
+
local bun_path = readit.config.bun_path or "bun"
|
|
12
|
+
local bun_exec = vim.fn.exepath(bun_path)
|
|
13
|
+
|
|
14
|
+
if bun_exec ~= "" then
|
|
15
|
+
local version = vim.fn.system(bun_path .. " --version")
|
|
16
|
+
vim.health.ok("bun found: " .. vim.trim(version) .. " (" .. bun_exec .. ")")
|
|
17
|
+
else
|
|
18
|
+
vim.health.error(
|
|
19
|
+
"bun not found",
|
|
20
|
+
{ "Install Bun: https://bun.sh", "Or set bun_path in setup()" }
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
-- Check readit CLI
|
|
25
|
+
local readit_exec = vim.fn.exepath("readit")
|
|
26
|
+
if readit_exec ~= "" then
|
|
27
|
+
vim.health.ok("readit CLI found: " .. readit_exec)
|
|
28
|
+
else
|
|
29
|
+
local dist = vim.fn.expand("~/.readit/dist/index.js")
|
|
30
|
+
if vim.fn.filereadable(dist) == 1 then
|
|
31
|
+
vim.health.ok("readit dist found: " .. dist)
|
|
32
|
+
else
|
|
33
|
+
vim.health.warn(
|
|
34
|
+
"readit CLI not in PATH",
|
|
35
|
+
{ "Install: npm install -g @peaske7/readit", "Or: bun add -g @peaske7/readit" }
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
-- Check curl (needed for server communication)
|
|
41
|
+
if vim.fn.exepath("curl") ~= "" then
|
|
42
|
+
vim.health.ok("curl found")
|
|
43
|
+
else
|
|
44
|
+
vim.health.error("curl not found (required for server API calls)")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
-- Check server status
|
|
48
|
+
if readit._server_port then
|
|
49
|
+
vim.health.ok("Server running on port " .. readit._server_port)
|
|
50
|
+
else
|
|
51
|
+
vim.health.info("Server not running (will start on :ReaditOpen)")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
-- Check for comments directory
|
|
55
|
+
local comments_dir = vim.fn.expand("~/.readit/comments")
|
|
56
|
+
if vim.fn.isdirectory(comments_dir) == 1 then
|
|
57
|
+
local count = #vim.fn.glob(comments_dir .. "/**/*.comments.md", false, true)
|
|
58
|
+
vim.health.ok("Comments directory exists (" .. count .. " comment files)")
|
|
59
|
+
else
|
|
60
|
+
vim.health.info("No comments directory yet (~/.readit/comments/)")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return M
|