@youtyan/code-viewer 0.5.5 → 0.6.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
@@ -10,8 +10,8 @@ Requires Node.js 20 or newer when installed from npm. Development uses
10
10
  - Browse repository files and folders in a persistent sidebar with live
11
11
  worktree change updates over SSE.
12
12
  - View git diffs with unified or split layout, lazy loading, viewed-file
13
- state, ignore-whitespace and hide-tests toggles, and per-line "reference
14
- pills" that copy `@path#start-end` for AI agents.
13
+ state, ignore-whitespace and hide-tests toggles, and dismissible per-line
14
+ "reference pills" that copy `@path#start-end` for AI agents.
15
15
  - Browse commit history per branch and open any commit's changed files and
16
16
  diff, with shareable `/history?ref=<branch>&commit=<sha>` links.
17
17
  - Open per-file Blame and History tabs on a file detail page (GitHub-style):
@@ -20,8 +20,9 @@ Requires Node.js 20 or newer when installed from npm. Development uses
20
20
  same commit list and diff renderer used by `/history` inside the file's
21
21
  tab shell, filtered to that path. Both tabs keep the Repository sidebar
22
22
  visible.
23
- - Open files directly from the repository or diff view, including large
24
- generated files (virtualized source viewer with copy/open-full-view).
23
+ - Open files directly from the repository or diff view, including text-like
24
+ config/prompt files and large generated files (virtualized source viewer
25
+ with copy/open-full-view).
25
26
  - Preview Markdown with a table of contents, task lists, Mermaid diagrams
26
27
  (click to enlarge), and Shiki code highlighting.
27
28
  - Preview browser-safe media and show metadata for binary files that cannot
@@ -40,14 +41,21 @@ Requires Node.js 20 or newer when installed from npm. Development uses
40
41
  toggled by the 🩺 icon in the header): runtime (Node / Bun / ABI),
41
42
  `@youtyan/code-viewer` version and execution origin (npx cache vs
42
43
  local), SQLite driver and snapshot store, Git, discovery summary,
44
+ per-source datastore connectivity (each discovered SQLite / docker
45
+ SQL / Redis / Elasticsearch / S3 source gets one row with a 2s
46
+ minimal-read probe; failure rows include a paste-safe retry hint),
43
47
  Docker / Compose health (config dry-parse + `compose ps` per service),
44
48
  and the listening port. Useful when `npx` cache mismatch (e.g.
45
- `NODE_MODULE_VERSION` errors) needs a remediation hint.
49
+ `NODE_MODULE_VERSION` errors) needs a remediation hint, or when a
50
+ docker compose datastore is discovered but unreachable.
46
51
  - Open repository folders (and parent folders of files) in the OS file
47
52
  manager, create folders, and trash/restore files from localhost-only
48
53
  actions.
49
54
  - Upload files into worktree folders. Uploads are enabled by default for
50
55
  worktree targets; toggle them off from Viewer Settings.
56
+ - Expose a local, read-only MCP endpoint (`/_mcp`) on the running server so
57
+ AI agents can call status, file, search, and datastore tools directly
58
+ over JSON-RPC instead of spawning CLI subprocesses.
51
59
 
52
60
  ## Usage
53
61
 
@@ -284,43 +292,377 @@ Open Datastores in the global navigation to access:
284
292
 
285
293
  ### CLI
286
294
 
287
- AI agents can run read-only queries, search content across tables, and
288
- capture snapshots / diffs from the command line. The same operations are
289
- mirrored under the Datastores tab in the browser UI, and every CLI result is
290
- written to the per-repository history visible in the browser.
295
+ AI agents can run read-only queries, search across tables, and capture
296
+ snapshots / diffs from the command line. Query results are written to the
297
+ per-repository history visible in the browser; search results are returned
298
+ by the CLI and mirror the browser Search tab; snapshots are stored in the
299
+ snapshot store. The same operations are available in the browser's
300
+ Datastores tab (Query History, Search, and Snapshot tabs).
291
301
 
292
302
  ```sh
303
+ # Discover datastore ids the running server has detected (SQLite files plus
304
+ # any PostgreSQL / MySQL / Redis / Elasticsearch / S3 services from a nearby
305
+ # docker-compose). Use the printed id as --db on every other command.
306
+ code-viewer query sources --json
307
+ # Or skip composing the next SQL call yourself: --commands prints
308
+ # shell-pasteable schema/exec lines for SQL sources, plus paste-safe
309
+ # `list --db ... --json` and `snapshot list --db ... --json` so you can
310
+ # step into the existing query history and snapshot store without
311
+ # rebuilding those commands. Redis sources get
312
+ # `redis databases / redis keys` lines, Elasticsearch sources get
313
+ # `elasticsearch indices / elasticsearch docs` lines, and S3 sources get
314
+ # `s3 buckets / s3 objects` lines with `--bucket <bucket-name>` as a
315
+ # placeholder. Every emitted SQL command line pins --server '<url>' to the
316
+ # same server URL this invocation resolved, so pasting them elsewhere
317
+ # never silently re-runs auto-discovery. --json and --commands are
318
+ # mutually exclusive. Notice/comment metadata is collapsed to one line
319
+ # so copied command blocks stay intact.
320
+ code-viewer query sources --commands
321
+
322
+ # Introspect tables and columns without writing dialect-specific SQL.
323
+ # `query schema --json` adds paste-safe `columnsCommand` / `ddlCommand` fields
324
+ # to every tables[] element (each pins --server and single-quotes the db /
325
+ # schema / table) so AI/human can drill into a specific table without
326
+ # rebuilding the call.
327
+ code-viewer query schemas --db docker:pg-svc --json
328
+ code-viewer query schema --db app.db --json
329
+ code-viewer query schema --db docker:pg-svc --schema analytics --with-columns --json
330
+ code-viewer query columns --db app.db --table users --json
331
+ code-viewer query ddl --db app.db --table users
332
+
293
333
  code-viewer query exec --db data.db --sql "SELECT * FROM users LIMIT 10" \
294
334
  --title "Sample users" --body "Checking user data shape."
335
+ code-viewer query exec --db docker:pg-svc --schema analytics \
336
+ --sql "SELECT * FROM events LIMIT 10"
295
337
 
296
338
  code-viewer query exec --db app.db --sql "SELECT count(*) FROM orders" \
297
339
  --max-rows 1 --no-save
298
340
 
341
+ # Show saved query history. `list --json` enriches each entries[] element
342
+ # with a paste-safe `replayCommand` — `code-viewer query --server '<url>'
343
+ # exec --db '<dbId>' [--schema '<schema>'] --sql '<sql>' [--title '<title>']
344
+ # --no-save` — so AI/human can re-run a past query without rebuilding the
345
+ # call. server URL / dbId / schema / sql / title are POSIX single-quoted;
346
+ # `--no-save` is fixed so replay does not re-pollute history (drop it if you
347
+ # do want the replay saved).
299
348
  code-viewer query list --db app.db --json
300
349
  code-viewer query clear --db app.db
350
+ # PostgreSQL multi-schema query history: keep list/clear scoped to one schema.
351
+ code-viewer query list --db docker:pg-svc --schema analytics --json
352
+ code-viewer query clear --db docker:pg-svc --schema analytics
301
353
 
302
- code-viewer query search --db app.db --term "john@example.com" \
303
- --tables users,orders --include-non-text --max-hits 20
354
+ # Locate a value across every table (default: text-like columns only).
355
+ # Blocks until the scan finishes or --timeout (default 60s) expires.
356
+ code-viewer query search --db app.db --term "needle@example.com" --json
357
+ code-viewer query search --db app.db --term "needle@example.com" \
358
+ --tables users,orders --max-hits 20 --include-non-text --json
304
359
 
305
360
  code-viewer query snapshot create --db app.db --tables users,orders \
306
361
  --note "Before user registration test"
362
+ # The no-wait output also prints a paste-safe "Poll with: ..." line that
363
+ # pins --server '<url>' and single-quotes db/schema, so AI/human paste never
364
+ # silently falls back to auto-discovery. The same string is available as a
365
+ # pollCommand field in --json ack output.
366
+ # Block until the snapshot finishes (default --timeout 120s) and emit the
367
+ # final meta as JSON — handy when an AI agent needs the snapshot id without
368
+ # polling snapshot list separately.
369
+ code-viewer query snapshot create --db app.db --tables users,orders \
370
+ --note "Before user registration test" --wait --json
371
+ # `snapshot list --json` enriches each snapshots[] element with paste-safe
372
+ # `deleteCommand` and `noteCommand` fields. Each pins --server '<url>' and
373
+ # single-quotes the snapshot id; `noteCommand` quotes the current note as-is
374
+ # so AI/human can paste and edit the value to update.
307
375
  code-viewer query snapshot list --db app.db --json
376
+ # PostgreSQL multi-schema: pin both create and list to the same schema so
377
+ # the before/after pair and --wait polling stay scoped to that schema.
378
+ code-viewer query snapshot create --db docker:pg-svc --schema analytics \
379
+ --tables events --note "Before backfill" --wait --json
380
+ code-viewer query snapshot list --db docker:pg-svc --schema analytics --json
308
381
  code-viewer query snapshot note --id snap-abc123 --note "Updated context"
309
382
  code-viewer query snapshot delete --id snap-abc123
310
383
 
311
- code-viewer query diff create --before snap-abc123 --after snap-def456 \
312
- --note "User registration test"
313
- code-viewer query diff tables --id diff-xyz789
314
- code-viewer query diff rows --id diff-xyz789 --table users --type inserted
315
- code-viewer query diff list --db app.db --json
316
- code-viewer query diff delete --id diff-xyz789
384
+ # diff tables prints per-table summary lines plus a paste-safe "# diff rows: ..."
385
+ # hint per table, and --json adds a diffRowsCommand field to each tables[] element
386
+ # so AI/human can copy the exact row-detail command without rebuilding it.
387
+ code-viewer query diff tables --before snap-abc123 --after snap-def456 --json
388
+ code-viewer query diff rows --before snap-abc123 --after snap-def456 \
389
+ --table users --json
317
390
  ```
318
391
 
392
+ `query exec` prints pretty JSON with `dbId`, `columns`, `columnTypes`, `rows`,
393
+ `rowCount`, `truncated`, `elapsedMs`, and optional `schema` / `executedSql`.
394
+ Check `truncated` before treating the result as complete.
395
+
319
396
  `code-viewer query --help` shows all command syntax. `code-viewer query
320
397
  agent-help` prints a longer guide for AI agents covering query shape and
321
398
  conventions. Both `query` and `annotate` accept `--cwd <repo>` and
322
399
  `--server <url>` for targeting a specific running server.
323
400
 
401
+ For discovered Redis sources, `code-viewer query redis` exposes the same
402
+ read-only endpoints the browser's Datastores tab uses, so AI agents and
403
+ shell scripts can look inside without opening a browser. The CLI calls
404
+ the existing `/_db/redis/databases`, `/_db/redis/keys`, and
405
+ `/_db/redis/value` routes (writes stay browser-only):
406
+
407
+ ```sh
408
+ # List the 16 logical DBs and their key counts.
409
+ code-viewer query redis databases --db docker:redis-svc --json
410
+
411
+ # SCAN-style key paging — re-issue with the returned nextCursor until "0".
412
+ code-viewer query redis keys --db docker:redis-svc --db-index 0 \
413
+ --pattern '*' --count 500 --json
414
+
415
+ # Read a single key's value. Binary content surfaces as binaryBase64.
416
+ code-viewer query redis value --db docker:redis-svc --db-index 0 \
417
+ --key sample:key --json
418
+ ```
419
+
420
+ Default text output is tab-separated (`index<TAB>keyCount` for
421
+ databases, `name<TAB>type` for keys). For `keys` a non-terminal cursor
422
+ appears as a trailing `# nextCursor: <cursor>` line so pagination needs
423
+ no JSON parsing; 0 keys prints `no redis keys` to stderr and exits 0.
424
+ `value`'s default output is the `RedisValue` payload as pretty JSON;
425
+ `--json` wraps the same payload in the full `RedisValueResponse`
426
+ (dbId / dbIndex / key included).
427
+
428
+ For discovered Elasticsearch sources, `code-viewer query elasticsearch`
429
+ exposes the same read-only endpoints the browser's Datastores tab uses.
430
+ The CLI calls the existing `/_db/elasticsearch/indices`, `/mapping`,
431
+ `/docs`, and `/doc` routes (writes stay browser-only):
432
+
433
+ ```sh
434
+ # List indices: name, doc count, byte size, health.
435
+ code-viewer query elasticsearch indices --db docker:es-svc --json
436
+
437
+ # Inspect a single index's mapping (field types / nested properties).
438
+ code-viewer query elasticsearch mapping --db docker:es-svc \
439
+ --index sample-index --json
440
+
441
+ # Search documents with a Lucene query; --size caps hits, --search-after
442
+ # pages by feeding back the previous response's lastSort JSON array.
443
+ code-viewer query elasticsearch docs --db docker:es-svc \
444
+ --index sample-index --q 'status:active' --size 10 --json
445
+ code-viewer query elasticsearch docs --db docker:es-svc \
446
+ --index sample-index --q 'status:active' --size 10 \
447
+ --search-after '[1700000000000,"abc"]' --json
448
+
449
+ # Read a single document by id.
450
+ code-viewer query elasticsearch doc --db docker:es-svc \
451
+ --index sample-index --id sample-id --json
452
+ ```
453
+
454
+ Default text output is tab-separated:
455
+ `name<TAB>docCount<TAB>sizeBytes<TAB>health` for `indices`,
456
+ `_id<TAB>_score` per hit for `docs` (followed by `# lastSort: <json>` and
457
+ `# totalHits: <n> (returned <k>)` trailing lines so paging needs no JSON
458
+ parsing). `mapping` and `doc` default to pretty JSON of the inner payload
459
+ (`EsMapping` and `_source`). 0 hits on `docs` prints `no elasticsearch
460
+ hits` to stderr (exit 0); a missing `doc` id prints
461
+ `not found: <index>/<id>` to stderr (exit 0). `--json` always emits the
462
+ full server response envelope.
463
+
464
+ For discovered S3 sources, `code-viewer query s3` exposes the same
465
+ read-only endpoints the browser's Datastores tab uses. The CLI calls the
466
+ existing `/_db/s3/buckets`, `/objects`, `/folder`, `/head`, and `/text`
467
+ routes (writes and raw byte streams stay browser-only):
468
+
469
+ ```sh
470
+ # List buckets in the source.
471
+ code-viewer query s3 buckets --db docker:s3-svc --json
472
+
473
+ # List objects in a bucket. --mode prefix walks --prefix; --mode contains
474
+ # scans for --q across keys/basenames. Use --token to page.
475
+ code-viewer query s3 objects --db docker:s3-svc --bucket sample-bucket \
476
+ --prefix logs/ --limit 50 --json
477
+
478
+ # Walk one folder level (delimiter "/") — folders and files separately.
479
+ code-viewer query s3 folder --db docker:s3-svc --bucket sample-bucket \
480
+ --prefix logs/ --json
481
+
482
+ # Object metadata only (size / contentType / etag / updatedAt).
483
+ code-viewer query s3 head --db docker:s3-svc --bucket sample-bucket \
484
+ --key logs/sample.json --json
485
+
486
+ # Preview a text-shaped object's body (server caps at 512KiB and sets
487
+ # truncated=true when it had to cut). Non-text keys return HTTP 415.
488
+ code-viewer query s3 text --db docker:s3-svc --bucket sample-bucket \
489
+ --key logs/sample.json
490
+ ```
491
+
492
+ Default text output is tab-separated:
493
+ `name<TAB>createdAt-or-"?"` for `buckets`,
494
+ `key<TAB>sizeBytes<TAB>updatedAt-or-"?"<TAB>contentType-or-"?"` per object
495
+ for `objects` (with `# nextToken: <token>` / `# scanLimitReached: true`
496
+ trailing lines when the server returned them), and `DIR<TAB><prefix>` /
497
+ `OBJ<TAB><key><TAB><sizeBytes>` rows for `folder`. 0 hits on `objects`
498
+ prints `no s3 objects` to stderr (exit 0); an empty `folder` listing
499
+ prints `no s3 folder entries` to stderr (exit 0). `head` defaults to
500
+ pretty JSON of `S3ObjectHeadResponse`. `text` prints the object body to
501
+ stdout and adds `text truncated` to stderr when the server flagged
502
+ truncation. `--json` always emits the full server response envelope.
503
+
504
+ AI agents who don't yet know which subcommand they need can run
505
+ `code-viewer agent-help` once. It prints a short index of the seven
506
+ AI-facing entry points (`status`, `query`, `annotate`, `search`,
507
+ `file`, `skill`, `doctor`) with the exact `code-viewer <name>
508
+ agent-help` command for each full guide. The index runs without any
509
+ preflight, so it works even before SQLite or a running server is set
510
+ up.
511
+
512
+ ### Workspace status CLI
513
+
514
+ `code-viewer status` prints a one-shot snapshot of the current repo so
515
+ an AI agent (or you) can orient yourself in a single call: current
516
+ branch, remote URL, every file that differs from HEAD (staged +
517
+ unstaged + untracked), the staged subset, the most recent commits, and
518
+ a paste-safe shortlist of follow-up `code-viewer` commands. It runs
519
+ locally over `git` — no running server, no SQLite preflight — so it is
520
+ safe to call as the first command after entering any repository.
521
+
522
+ ```sh
523
+ # Human-readable summary.
524
+ code-viewer status
525
+
526
+ # Structured payload for agents.
527
+ code-viewer status --json
528
+
529
+ # Override the ref / depth used for "recent commits".
530
+ code-viewer status --ref main --limit 20 --json
531
+ ```
532
+
533
+ The `nextCommands` field pins `--server '<url>'` automatically for
534
+ server-backed follow-ups when a code-viewer server is registered for
535
+ the repo; local follow-ups stay bare. With no server, the snapshot
536
+ itself still succeeds.
537
+
538
+ ### Code search CLI
539
+
540
+ `code-viewer search code` exposes the running server's `/_grep`
541
+ endpoint — the same engine that powers the browser's `Ctrl+G` palette —
542
+ to the command line for AI agents and shell scripts. The search uses
543
+ ripgrep when available and falls back to git grep / fixed-string
544
+ scanning, honours the same scope rules as the UI (`.git`,
545
+ `.code-viewer`, scope-omit directories filtered out), and can target a
546
+ git ref instead of the worktree.
547
+
548
+ ```sh
549
+ # default: fixed-string search across the worktree, plain text output.
550
+ code-viewer search code --term "TODO"
551
+
552
+ # JSON output: { ref, engine, truncated, matches[{path,line,column,preview}] }.
553
+ # Prefer --json from agents — column / engine / truncated drive follow-up logic.
554
+ code-viewer search code --term "TODO" --json
555
+
556
+ # extended-regex search, restricted to two subtrees, on the `main` ref.
557
+ code-viewer search code --term "fn handler" --regex \
558
+ --path src --path tests --ref main --json
559
+ ```
560
+
561
+ Default text output is `path:line:column<TAB>preview`, one line per
562
+ match. An empty result prints `no matches` to stderr and exits 0.
563
+ Parse errors and unreachable servers exit 1. `--max` accepts a positive
564
+ integer up to the server's hard cap; `truncated=true` in the JSON
565
+ response means more matches exist beyond the cap. Run
566
+ `code-viewer search agent-help` for the full AI-agent guide.
567
+
568
+ `code-viewer search files` is the sister command for **filename**
569
+ lookups — the CLI mirror of the browser's `Ctrl+K` palette. It calls
570
+ `/_files` for the ref's full tree, then ranks paths with the same
571
+ `fuzzy + glob` algorithm the palette uses. `--term` auto-switches
572
+ between modes: bare words (e.g. `"auth"`, `"userId"`) use fuzzy
573
+ ranking; patterns containing `*` or `?` (e.g. `"src/**/*.test.ts"`) use
574
+ glob matching, and the mode used is reported in `--json`. The `.git`,
575
+ `.code-viewer`, and scope-omit directories are filtered out just like in
576
+ the palette.
577
+
578
+ ```sh
579
+ # Fuzzy search across the worktree, top 50 paths printed one per line.
580
+ code-viewer search files --term "userId"
581
+
582
+ # Glob: ranked JSON with score / ranges / mode for AI agents.
583
+ code-viewer search files --term "src/**/*.test.ts" --max 200 --json
584
+
585
+ # Look at a specific ref instead of the worktree.
586
+ code-viewer search files --term "config" --ref main --json
587
+ ```
588
+
589
+ Default text output is one path per line, best first. An empty result
590
+ prints `no matching files` to stderr and exits 0. `--json` emits a
591
+ ranked payload `{ ref, generation, query, mode, truncated,
592
+ candidateTruncated, totalCandidates, totalMatches,
593
+ matches[{ path, score, ranges }] }`. `truncated` means the ranked
594
+ matches were sliced by `--max`; `candidateTruncated` means the server
595
+ file-list cap was reached before ranking. The default `--max` is `50`
596
+ (intentionally smaller than `search code` so the result fits an AI
597
+ agent's context window); raise it up to the server-side cap when needed.
598
+
599
+ ### File inspect CLI
600
+
601
+ After `search` locates a path, `code-viewer file` drills into it
602
+ from git refs or the worktree. The CLI reuses the same read paths the
603
+ browser uses for the Blame, History, and Diff tabs and the source viewer,
604
+ so output matches the on-screen views. **No running code-viewer server is
605
+ required** — these commands run locally, which makes them safe to use
606
+ before the server has started (or from CI).
607
+
608
+ ```sh
609
+ # "Who wrote this line?" — porcelain blame for a path, JSON DTO output.
610
+ code-viewer file blame --path src/sample.ts --json
611
+
612
+ # Force a committed-only blame against an explicit ref.
613
+ code-viewer file blame --path src/sample.ts --base HEAD --ref main --json
614
+
615
+ # "What changed on this path recently?" — paginated commit log.
616
+ code-viewer file history --path src/sample.ts --limit 10 --json
617
+ code-viewer file history --path src/sample.ts --query "author:tester" --json
618
+
619
+ # Read the file (or a line range) as of a ref. AI-friendly JSON output
620
+ # includes totalLines / complete so the caller knows what was sliced.
621
+ code-viewer file show --path src/sample.ts --json
622
+ code-viewer file show --path src/sample.ts --start 100 --end 150 --json
623
+ code-viewer file show --path src/sample.ts --ref main --json
624
+
625
+ # Unified diff for one path. Defaults to HEAD..worktree and a preview cap
626
+ # (hunks/lines); pass --full for the entire diff.
627
+ code-viewer file diff --path src/sample.ts --json
628
+ code-viewer file diff --path src/sample.ts --from HEAD~1 --to HEAD --full --json
629
+ code-viewer file diff --path new_sample.ts --untracked --json
630
+ ```
631
+
632
+ Default (non-`--json`) output is tab-separated and easy to grep:
633
+
634
+ - `blame` — `<line><TAB><shortSha or "worktree"><TAB><summary>`. Lines
635
+ with uncommitted edits show `worktree` and `<uncommitted>`.
636
+ - `history` — `<shortSha><TAB><whenISO><TAB><author><TAB><subject>`.
637
+ A path with zero commits prints `no history` to stderr and exits 0.
638
+ - `show` — the worktree file (or sliced lines) by default. Pass `--ref`
639
+ for a committed snapshot. Empty slices succeed.
640
+ - `diff` — the unified diff text. An empty (or worktree == worktree)
641
+ range prints nothing on stdout and exits 0.
642
+
643
+ Run `code-viewer file agent-help` for the full AI-agent guide
644
+ including the JSON contract for each subcommand.
645
+
646
+ ### Doctor CLI
647
+
648
+ The same diagnostic report behind the Environment Doctor sheet (see
649
+ Features above) is available from the terminal without a browser, so AI
650
+ agents and CI can introspect the runtime, SQLite driver, Git, Docker
651
+ discovery, and snapshot store status directly.
652
+
653
+ ```sh
654
+ # Human-readable status summary.
655
+ code-viewer doctor
656
+
657
+ # Full DoctorReport JSON (matches the /_doctor endpoint).
658
+ code-viewer doctor --json
659
+ code-viewer doctor --cwd /path/to/repo --port 64160 --json
660
+ ```
661
+
662
+ The exit code is `1` iff the worst check status is `"error"` (never on
663
+ `"warn"`), so it doubles as a CI gate. Run `code-viewer doctor agent-help`
664
+ for the full AI-agent guide.
665
+
324
666
  ## AI Code Annotations
325
667
 
326
668
  AI coding agents (Claude Code, Codex, Cursor, Gemini, and similar CLI agents)
@@ -375,13 +717,15 @@ sharing it through git.
375
717
 
376
718
  In the browser, the annotation icon in the header opens the side panel. The
377
719
  current explanation is rendered at the top of the panel while the code stays
378
- visible next to it, with the annotated lines highlighted. The history below
379
- groups annotations by session; clicking an entry jumps back to its location,
380
- and entries and sessions can be deleted there too. The "follow" checkbox
381
- controls whether the tab jumps automatically when an agent adds a new
382
- annotation. A built-in player can speak the current annotation aloud with
383
- play/pause, previous/next, mute, and rate controls (TTS state is saved per
384
- project).
720
+ visible next to it, with the annotated lines highlighted. The side panel is
721
+ resizable and remembers its width per project. The history below groups
722
+ annotations by session, shows when each session and entry was created, and
723
+ keeps inline code notes out of the way while the panel is open. Clicking an
724
+ entry jumps back to its location, and entries and sessions can be deleted
725
+ there too. The "follow" checkbox controls whether the tab jumps automatically
726
+ when an agent adds a new annotation. A built-in player can speak the current
727
+ annotation aloud with play/pause, previous/next, mute, and rate controls (TTS
728
+ state is saved per project).
385
729
 
386
730
  A copy button on each annotation produces a paste-ready prompt block that
387
731
  references the annotation by URL for sharing back into the originating agent.
@@ -422,6 +766,41 @@ npx -y @youtyan/code-viewer skill install --agent all # claude, codex,
422
766
  and `--cwd <dir>` to target a specific repository. Running the same command
423
767
  again updates an existing installation in place.
424
768
 
769
+ ## MCP Server
770
+
771
+ While `code-viewer` is running, the same server also exposes a local MCP
772
+ (Model Context Protocol) endpoint at `/_mcp` — for example
773
+ `http://127.0.0.1:<port>/_mcp`, where `<port>` is the port printed at
774
+ startup. It speaks JSON-RPC 2.0 over the Streamable HTTP transport
775
+ (`initialize`, `ping`, `tools/list`, `tools/call`; POST only,
776
+ `application/json`) and is guarded by the same localhost/same-origin check
777
+ as every other route, so MCP clients can call it directly instead of
778
+ spawning `code-viewer` CLI subprocesses.
779
+
780
+ All tools are read-only:
781
+
782
+ | Tool | What it does |
783
+ | --- | --- |
784
+ | `code_viewer_agent_help` | Index of every AI-facing CLI subcommand. |
785
+ | `code_viewer_status` | Branch, remote, changed files, and recent commits. |
786
+ | `code_viewer_file_show` | Read a file (optionally a line range) at any ref. |
787
+ | `code_viewer_file_blame` | Per-line blame (sha / author / time / summary). |
788
+ | `code_viewer_file_history` | Commit history for one path (follows renames). |
789
+ | `code_viewer_file_diff` | Unified diff for one path (preview-capped by default). |
790
+ | `code_viewer_search_files` | Rank repository paths by fuzzy or glob match. |
791
+ | `code_viewer_search_code` | Grep the repository (`rg` / `git grep` / fallback). |
792
+ | `code_viewer_datastore_sources` | Discover read-only datastore source ids. |
793
+ | `code_viewer_datastore_schemas` | List schemas for one SQL datastore. |
794
+ | `code_viewer_datastore_schema` | Inspect tables, indexes, FKs, and columns. |
795
+ | `code_viewer_datastore_columns` | Inspect columns for one SQL table. |
796
+ | `code_viewer_datastore_ddl` | Inspect the `CREATE` statement and triggers. |
797
+ | `code_viewer_datastore_query` | Run a read-only `SELECT` / `PRAGMA` / `EXPLAIN` / `WITH`. |
798
+ | `code_viewer_datastore_history` | Inspect saved query history. |
799
+
800
+ Point any MCP-compatible client (Claude Code, Codex, etc.) at the endpoint
801
+ URL above as a Streamable HTTP MCP server; no separate install step or
802
+ extra process is needed beyond `code-viewer` already running.
803
+
425
804
  ## Development
426
805
 
427
806
  ```sh