chat-logbook 0.3.1 → 0.4.1

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/README.md CHANGED
@@ -2,48 +2,71 @@
2
2
 
3
3
  > _Where your AI conversations live._
4
4
 
5
- chat-logbook is a local-first library for your AI conversations. It reads the
6
- files AI assistants write on your machine starting with Claude Code, with
7
- more tools planned and presents them as a single browsable, searchable,
8
- organizable history.
5
+ A local-first library for the conversations you've had with your AI tools.
6
+ Read by chat-logbook, kept on your machine, browsable and searchable in one
7
+ place even after your AI tool has deleted the original.
9
8
 
10
- > **Status:** Early release (v0.3.0). Browsing, rendering, and
11
- > soft-delete with Trash are working today. Search, tags, and
12
- > annotations are on the way. See [Roadmap](#roadmap).
9
+ > **Status.** A personal side project, moving at side-project pace —
10
+ > development and responses happen as time allows. Early release:
11
+ > browsing, rendering, soft-delete, and a local archive that survives
12
+ > vendor cleanup all work today. Search and tags are next. See
13
+ > [Roadmap](#roadmap).
13
14
 
14
- ## About
15
+ ## What chat-logbook is
15
16
 
16
- You open chat-logbook from the command line, and a browser window opens onto
17
- your conversation history. You can browse it, find anything in it, tag what
17
+ You open it from the command line, and a browser window opens onto your
18
+ conversation history. You can browse it, find anything in it, tag what
18
19
  matters, and pick up where you left off.
19
20
 
21
+ It reads the files your AI tools already write to your machine — Claude Code
22
+ today, with more tools planned. From there it keeps its own copy in a
23
+ private archive on your machine, so the history is yours even when the
24
+ source tool quietly cleans up after itself (Claude Code defaults to deleting
25
+ conversations older than 30 days).
26
+
20
27
  Nothing leaves your machine. There is no account to create. The original
21
- files written by your AI tools are never modified.
28
+ files your AI tools wrote are never modified.
29
+
30
+ We built this because the right place for your AI conversations to live
31
+ isn't inside the next vendor change.
22
32
 
23
- Design principles:
33
+ ## What it gives you
24
34
 
25
- - **Read-only access to source directories.** Original conversation files are
26
- never modified. Today that means `~/.claude/`; the same rule applies to
27
- every agent we add.
35
+ - **Read-only access to source directories.** Original conversation files
36
+ are never modified. Today that means `~/.claude/`; the same rule applies
37
+ to every agent we add.
28
38
  - **Local-only.** No telemetry, no analytics, no third-party calls.
29
39
  - **Zero configuration.** Install and run.
30
40
  - **Drive everything from the keyboard.** A `/` or `⌘K` overlay finds any
31
41
  past conversation in seconds. The mouse still works, but every primary
32
42
  action has a binding.
43
+ - **Your archive is yours.** It's a single SQLite file at
44
+ `~/.chat-logbook/archive.db`. Copy it to back up. Open it with any tool
45
+ that reads SQLite. If chat-logbook disappears tomorrow, the archive
46
+ doesn't.
33
47
 
34
48
  The full problem statement, user stories, and direction live in the
35
49
  [PRD](docs/PRD.md).
36
50
 
37
51
  ## What works today
38
52
 
39
- - **Three-column layout** Resizable panels for filters, session list, and conversation content
40
- - **Rich conversation rendering** — Markdown, syntax-highlighted code blocks, collapsible tool calls with one-line summaries, and collapsible thinking blocks
41
- - **Virtual scrolling** Handles long conversations smoothly with virtualized rendering
42
- - **Solarized Dark theme** Easy on the eyes, consistent with Claude Code's terminal aesthetic
53
+ - **Three-column layout.** Resizable panels for filters, session list,
54
+ and conversation content.
55
+ - **Rich conversation rendering.** Markdown, syntax-highlighted code
56
+ blocks, collapsible tool calls with one-line summaries, and collapsible
57
+ thinking blocks.
58
+ - **Virtual scrolling.** Long conversations scroll smoothly.
59
+ - **Solarized Dark theme.** Easy on the eyes, consistent with Claude
60
+ Code's terminal look.
61
+ - **Soft delete with Trash.** Hide sessions you don't want to see; restore
62
+ them anytime.
63
+ - **Local archive.** Every conversation chat-logbook reads is copied into
64
+ `~/.chat-logbook/archive.db`. The UI reads from the archive, so a
65
+ session stays visible even after the source JSONL is gone.
43
66
 
44
67
  ## Quick start
45
68
 
46
- Requirements: Node.js 20+.
69
+ Requirements: Node.js 20 or later.
47
70
 
48
71
  Install globally for a shorter command:
49
72
 
@@ -64,129 +87,114 @@ You should see:
64
87
  chat-logbook is running at http://localhost:3100
65
88
  ```
66
89
 
67
- Your browser will open automatically, showing a list of your Claude Code sessions on the left and conversation content on the right.
90
+ A browser window opens automatically, showing a list of your Claude Code
91
+ sessions on the left and conversation content on the right.
68
92
 
69
93
  ### Troubleshooting
70
94
 
71
- **"No conversations found"**
72
- Make sure you have Claude Code conversation history at `~/.claude/`. chat-logbook reads from this directory automatically.
73
-
74
- **Port already in use**
75
- By default, chat-logbook runs on port 3100. Use `PORT=8080 chat-log` to specify a different port.
76
-
77
- **Updating to the latest version**
78
- Run `npm install -g chat-logbook@latest` to update. If you use npx, the `@latest` tag ensures you always run the newest version.
79
-
80
- ## Architecture
95
+ **"No conversations found."**
96
+ You need to have Claude Code conversation history at `~/.claude/`.
97
+ chat-logbook reads from this directory automatically.
81
98
 
82
- Monorepo with two workspaces, published as a single npm package:
99
+ **"Port already in use."**
100
+ chat-logbook runs on port 3100 by default. Use `PORT=8080 chat-log` to
101
+ pick a different port.
83
102
 
84
- | Directory | Role | Stack |
85
- | --------- | ------------------------------------------------------------------------- | --------------------------------------- |
86
- | `api/` | Backend reads `~/.claude/` JSONL files, serves session and message data | Hono + @hono/node-server |
87
- | `web/` | Frontend — three-column SPA with conversation rendering | React + Vite + Tailwind CSS + shadcn/ui |
103
+ **Updating to the latest version.**
104
+ Run `npm install -g chat-logbook@latest`. If you use npx, the `@latest`
105
+ tag ensures you always run the newest version.
88
106
 
89
- In production, Hono serves both the API endpoints and the static frontend
90
- assets from a single Node.js process. During development, Vite proxies `/api`
91
- requests to the Hono dev server.
92
-
93
- ### How it reads conversations
94
-
95
- chat-logbook reads conversation data directly from the JSONL files that Claude
96
- Code stores in `~/.claude/`. It **never modifies** these files — your original
97
- conversation data is always left untouched.
107
+ ## FAQ
98
108
 
99
- Only conversations that are written to `~/.claude/` are visible. Ephemeral
100
- interactions that Claude Code does not persist (such as `/btw` side questions)
101
- cannot be displayed.
109
+ ### Does chat-logbook work with Claude Code on the web?
102
110
 
103
- ## Development
111
+ No. chat-logbook reads from local `~/.claude/` files, which are only
112
+ created by the Claude Code CLI on your machine. Conversations run via
113
+ Claude Code on the web (cloud VMs) are not stored locally and aren't
114
+ visible to chat-logbook.
104
115
 
105
- Requirements: Node.js 20+ and pnpm 10+.
116
+ ### Why can't I see my `/btw` conversations?
106
117
 
107
- ```bash
108
- git clone https://github.com/evaaaaawu/chat-logbook.git
109
- cd chat-logbook
110
- pnpm install
111
- pnpm dev
112
- ```
118
+ `/btw` is designed to be ephemeral — questions and answers appear in a
119
+ temporary overlay and are never written to conversation history files.
120
+ For a conversation to be preserved and visible in chat-logbook, send a
121
+ regular message instead.
113
122
 
114
- ### Scripts
123
+ ### Will chat-logbook lose my history if Claude Code deletes its files?
115
124
 
116
- | Command | What it does |
117
- | ---------------- | --------------------------------------------------- |
118
- | `pnpm dev` | Start dev servers for both workspaces (Vite + Hono) |
119
- | `pnpm build` | Build frontend and backend for production |
120
- | `pnpm test` | Run all tests (Vitest) |
121
- | `pnpm typecheck` | Type-check all workspaces |
125
+ Once chat-logbook has read a conversation into its archive, vendor
126
+ cleanup of the original file no longer removes it from chat-logbook.
127
+ The archive's contract: never delete in response to source deletion.
128
+ Only an explicit user action (Hard Delete / Purge) removes archived
129
+ conversations.
122
130
 
123
- A Husky `pre-commit` hook runs Prettier on staged files, type-checks, and runs
124
- the test suite on every commit.
131
+ ### Where is my data stored?
125
132
 
126
- ## FAQ
133
+ Three places, all on your machine:
127
134
 
128
- ### Does chat-logbook work with Claude Code on the web?
135
+ - `~/.claude/` (and equivalents for other tools) read-only source.
136
+ - `~/.chat-logbook/archive.db` — chat-logbook's copy of the
137
+ conversations it has read.
138
+ - `~/.chat-logbook/data.db` — your tags, titles, annotations, and
139
+ soft-delete flags.
129
140
 
130
- No. chat-logbook reads from local `~/.claude/` files, which are only created by the Claude Code CLI running on your machine. Conversations run via Claude Code on the web (cloud VMs) are not stored locally and are not accessible to chat-logbook.
141
+ Back up the two `~/.chat-logbook/` files together; they are the
142
+ complete chat-logbook state.
131
143
 
132
- ### Why can't I see my `/btw` conversations?
144
+ ### Is this affiliated with Anthropic / OpenAI?
133
145
 
134
- `/btw` is designed to be ephemeral — questions and answers appear in a temporary overlay and are never written to conversation history files. If you want a conversation to be preserved and visible in chat-logbook, use a regular message instead of `/btw`.
146
+ No. chat-logbook reads files those tools write on your machine. It
147
+ doesn't talk to their servers and isn't endorsed by them.
135
148
 
136
149
  ## Roadmap
137
150
 
138
- The headline feature on the way is **Spotlight Search** — a `⌘K` / `/` overlay
139
- that searches across sessions, messages, tags, and projects with full keyboard
140
- navigation, full-text matching (SQLite FTS5 trigram), and message-level jump +
141
- highlight. It is tracked as the [Spotlight Search epic (#5)](https://github.com/evaaaaawu/chat-logbook/issues/5).
151
+ Two phases of work are in flight, in this order.
142
152
 
143
- Work is grouped into release milestones:
153
+ **Custom titles and tags.** Rename a session to something you'll
154
+ recognize, attach tags with custom colors, and filter the list by tag or
155
+ by project. This is the path from "I have a lot of conversations" to
156
+ "I can find the one I need."
144
157
 
145
- ### [v0.3.0 Spotlight Alpha](https://github.com/evaaaaawu/chat-logbook/milestone/1)
158
+ **Spotlight search.** A keyboard-driven overlay (`⌘K` or `/`) that
159
+ searches across sessions, messages, tags, and projects from one input.
160
+ A match lands you on the exact message with the term highlighted, and
161
+ you can jump between every match without leaving the overlay.
146
162
 
147
- - **Spotlight overlay skeleton** `⌘K` / `/` opens an overlay; sessions picker; `Enter` opens, `Esc` closes
148
- - **SQLite + soft delete & restore** hide sessions you don't need; recover them anytime
149
- - **Full keyboard contract** Browse + Spotlight bindings unified
163
+ Beyond these three, several smaller things are on the list without firm
164
+ timing live updates while an AI tool is writing, annotations and
165
+ highlights for marking what matters, editing your own past messages,
166
+ CLI commands for working with conversations from a terminal. Some will
167
+ ship; some are still being weighed.
150
168
 
151
- ### [v0.4.0 Spotlight v1](https://github.com/evaaaaawu/chat-logbook/milestone/2)
169
+ Explicit non-goals: semantic / vector search, cloud sync inside the OSS
170
+ core, modification of source directories like `~/.claude/`, and bulk
171
+ export to bespoke formats (the archive itself is the export). See the
172
+ [PRD](docs/PRD.md) for the full out-of-scope list.
152
173
 
153
- - **FTS5 full-text messages search** fast keyword search across all conversations, including CJK and file paths mentioned in tool calls
154
- - **Incremental reindex** newly-arrived messages are searchable within seconds
155
- - **Message-level jump** — Spotlight matches scroll to the exact message and highlight the matched term, with a `n / m matches ↑↓ Esc` navigator bar
156
- - **Tags & Projects pickers** — `Tab`-cycle picker scopes; tag/project selection applies the same filter pipeline as the navigation panel
157
- - **Tag system + tag filtering** — color-coded tags, multi-tag AND filtering
158
- - **Project filtering** — focus on conversations within a specific project
159
- - **Title editing** — customize session titles for easier identification
174
+ This project is **not affiliated with Anthropic, OpenAI, or any other AI
175
+ provider.** It reads files those tools write on your machine; it does
176
+ not talk to their servers and is not endorsed by them.
160
177
 
161
- ### [v0.5.0 — Cross-vendor foundation](https://github.com/evaaaaawu/chat-logbook/milestones)
178
+ ## Changelog
162
179
 
163
- - **Parser plugin architecture** — one plugin per agent, behind a stable
164
- interface, so adding a new tool is a contained change
165
- - **First additional agents** — Codex CLI and Aider plugins, alongside the
166
- existing Claude Code reader
167
- - **`SyncProvider` interface stub** — a no-op default in the OSS core, leaving
168
- the integration point open for an opt-in cloud product later
180
+ See [CHANGELOG.md](CHANGELOG.md) for release notes.
169
181
 
170
- ### Later
182
+ ## Contributing
171
183
 
172
- - **Real-time streaming** watch active conversations update live via SSE
173
- - **Annotations** add notes next to any message in a conversation
174
- - **Highlights** — mark important text within conversations
175
- - **`#tag` / `@project` prefix syntax** in Spotlight (fast-follow)
176
- - **Recent-sessions empty state + onboarding hint** in Spotlight (fast-follow)
184
+ Chat Logbook is in very early development. To keep focus on the current
185
+ goals, we're not taking contributions right now.
177
186
 
178
- Explicit non-goals: semantic / vector search, cloud sync inside the OSS core,
179
- and any modification of source directories like `~/.claude/`. See the
180
- [PRD](docs/PRD.md) for the full out-of-scope list.
181
-
182
- This project is **not affiliated with Anthropic, OpenAI, or any other AI
183
- provider.** It reads files those tools write on your machine; it does not
184
- talk to their servers and is not endorsed by them.
187
+ If there's something you really need or you'd genuinely like to help —
188
+ reach out directly and we can talk through it.
185
189
 
186
190
  ## License
187
191
 
188
- This project is licensed under the [GNU Affero General Public License v3.0](LICENSE) (AGPL-3.0-only).
192
+ This project is licensed under the
193
+ [GNU Affero General Public License v3.0](LICENSE) (AGPL-3.0-only).
189
194
 
190
- You are free to use, modify, and distribute this software under the terms of the AGPL-3.0. If you modify the program and make it available over a network, you must release your modified source code under the same license.
195
+ You are free to use, modify, and distribute this software under the
196
+ terms of the AGPL-3.0. If you modify the program and make it available
197
+ over a network, you must release your modified source code under the
198
+ same license.
191
199
 
192
- For commercial licensing inquiries, please contact the author.
200
+ For commercial licensing inquiries, contact the author.
@@ -0,0 +1,18 @@
1
+ PRAGMA foreign_keys=OFF;
2
+ --> statement-breakpoint
3
+ CREATE TABLE `__new_sessions_meta` (
4
+ `id` text PRIMARY KEY NOT NULL,
5
+ `is_deleted` integer DEFAULT false NOT NULL,
6
+ `custom_title` text,
7
+ `created_at` integer NOT NULL,
8
+ `updated_at` integer NOT NULL
9
+ );
10
+ --> statement-breakpoint
11
+ INSERT INTO `__new_sessions_meta`("id", "is_deleted", "created_at", "updated_at")
12
+ SELECT `session_id`, `is_deleted`, `created_at`, `updated_at` FROM `sessions_meta`;
13
+ --> statement-breakpoint
14
+ DROP TABLE `sessions_meta`;
15
+ --> statement-breakpoint
16
+ ALTER TABLE `__new_sessions_meta` RENAME TO `sessions_meta`;
17
+ --> statement-breakpoint
18
+ PRAGMA foreign_keys=ON;
@@ -0,0 +1,5 @@
1
+ CREATE TABLE `archive_meta` (
2
+ `id` integer PRIMARY KEY NOT NULL,
3
+ `archive_uuid` text NOT NULL,
4
+ `created_at` integer NOT NULL
5
+ );
@@ -0,0 +1,4 @@
1
+ CREATE TABLE `schema_version` (
2
+ `version` integer PRIMARY KEY NOT NULL,
3
+ `applied_at` integer NOT NULL
4
+ );
@@ -0,0 +1,46 @@
1
+ CREATE TABLE `ingestion_events` (
2
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
3
+ `agent` text NOT NULL,
4
+ `session_id` text NOT NULL,
5
+ `source_path` text NOT NULL,
6
+ `event_type` text NOT NULL,
7
+ `detail` text NOT NULL,
8
+ `observed_at` integer NOT NULL
9
+ );
10
+ --> statement-breakpoint
11
+ CREATE TABLE `messages` (
12
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
13
+ `agent` text NOT NULL,
14
+ `session_id` text NOT NULL,
15
+ `message_id` text NOT NULL,
16
+ `role` text NOT NULL,
17
+ `ts` integer NOT NULL,
18
+ `text` text NOT NULL,
19
+ `blocks` text NOT NULL,
20
+ `raw_id` integer NOT NULL,
21
+ FOREIGN KEY (`raw_id`) REFERENCES `raw_messages`(`id`) ON UPDATE no action ON DELETE no action
22
+ );
23
+ --> statement-breakpoint
24
+ CREATE UNIQUE INDEX `messages_canonical_idx` ON `messages` (`agent`,`session_id`,`message_id`);--> statement-breakpoint
25
+ CREATE TABLE `raw_messages` (
26
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
27
+ `agent` text NOT NULL,
28
+ `session_id` text NOT NULL,
29
+ `source_path` text NOT NULL,
30
+ `source_locator` text NOT NULL,
31
+ `raw_payload` text NOT NULL,
32
+ `payload_hash` text NOT NULL,
33
+ `ingested_at` integer NOT NULL
34
+ );
35
+ --> statement-breakpoint
36
+ CREATE UNIQUE INDEX `raw_messages_idem_idx` ON `raw_messages` (`agent`,`session_id`,`payload_hash`);--> statement-breakpoint
37
+ CREATE TABLE `sessions` (
38
+ `id` text PRIMARY KEY NOT NULL,
39
+ `short_code` text NOT NULL,
40
+ `agent` text NOT NULL,
41
+ `source_session_id` text NOT NULL,
42
+ `first_seen_at` integer NOT NULL
43
+ );
44
+ --> statement-breakpoint
45
+ CREATE UNIQUE INDEX `sessions_short_code_unique` ON `sessions` (`short_code`);--> statement-breakpoint
46
+ CREATE UNIQUE INDEX `sessions_agent_source_idx` ON `sessions` (`agent`,`source_session_id`);
@@ -0,0 +1,11 @@
1
+ CREATE TABLE `session_scan_state` (
2
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
3
+ `agent` text NOT NULL,
4
+ `session_id` text NOT NULL,
5
+ `source_path` text NOT NULL,
6
+ `last_mtime_ms` integer NOT NULL,
7
+ `last_size_bytes` integer NOT NULL,
8
+ `last_scanned_at` integer NOT NULL
9
+ );
10
+ --> statement-breakpoint
11
+ CREATE UNIQUE INDEX `session_scan_state_idx` ON `session_scan_state` (`agent`,`session_id`);
@@ -0,0 +1 @@
1
+ ALTER TABLE `sessions` ADD `project` text;
@@ -0,0 +1,49 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "d3a95e23-e94b-48eb-b47f-93125fb0c649",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "archive_meta": {
8
+ "name": "archive_meta",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "integer",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "archive_uuid": {
18
+ "name": "archive_uuid",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "created_at": {
25
+ "name": "created_at",
26
+ "type": "integer",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ }
31
+ },
32
+ "indexes": {},
33
+ "foreignKeys": {},
34
+ "compositePrimaryKeys": {},
35
+ "uniqueConstraints": {},
36
+ "checkConstraints": {}
37
+ }
38
+ },
39
+ "views": {},
40
+ "enums": {},
41
+ "_meta": {
42
+ "schemas": {},
43
+ "tables": {},
44
+ "columns": {}
45
+ },
46
+ "internal": {
47
+ "indexes": {}
48
+ }
49
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "037731f6-9a27-4a72-b757-9ac3c4cedf65",
5
+ "prevId": "d3a95e23-e94b-48eb-b47f-93125fb0c649",
6
+ "tables": {
7
+ "archive_meta": {
8
+ "name": "archive_meta",
9
+ "columns": {
10
+ "id": {
11
+ "name": "id",
12
+ "type": "integer",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "archive_uuid": {
18
+ "name": "archive_uuid",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ },
24
+ "created_at": {
25
+ "name": "created_at",
26
+ "type": "integer",
27
+ "primaryKey": false,
28
+ "notNull": true,
29
+ "autoincrement": false
30
+ }
31
+ },
32
+ "indexes": {},
33
+ "foreignKeys": {},
34
+ "compositePrimaryKeys": {},
35
+ "uniqueConstraints": {},
36
+ "checkConstraints": {}
37
+ },
38
+ "schema_version": {
39
+ "name": "schema_version",
40
+ "columns": {
41
+ "version": {
42
+ "name": "version",
43
+ "type": "integer",
44
+ "primaryKey": true,
45
+ "notNull": true,
46
+ "autoincrement": false
47
+ },
48
+ "applied_at": {
49
+ "name": "applied_at",
50
+ "type": "integer",
51
+ "primaryKey": false,
52
+ "notNull": true,
53
+ "autoincrement": false
54
+ }
55
+ },
56
+ "indexes": {},
57
+ "foreignKeys": {},
58
+ "compositePrimaryKeys": {},
59
+ "uniqueConstraints": {},
60
+ "checkConstraints": {}
61
+ }
62
+ },
63
+ "views": {},
64
+ "enums": {},
65
+ "_meta": {
66
+ "schemas": {},
67
+ "tables": {},
68
+ "columns": {}
69
+ },
70
+ "internal": {
71
+ "indexes": {}
72
+ }
73
+ }