Skip to content

feat: add get_note_outline and read_note_lines tools - #146

Open
kartik7704 wants to merge 4 commits into
bitbonsai:mainfrom
kartik7704:feat/note-outline-tools
Open

feat: add get_note_outline and read_note_lines tools#146
kartik7704 wants to merge 4 commits into
bitbonsai:mainfrom
kartik7704:feat/note-outline-tools

Conversation

@kartik7704

Copy link
Copy Markdown

adds two tools for efficient navigation of large notes without loading full file content into context:

get_note_outline — returns all headings with level, text, and line number
read_note_lines — reads a specific line range (1-indexed, inclusive)
Intended usage: call get_note_outline first to get the structure, then read_note_lines to read only the relevant section. Useful for large notes like logs or directories where loading the full content is wasteful.

@kartik7704
kartik7704 force-pushed the feat/note-outline-tools branch from 0e43493 to 122a8dd Compare June 27, 2026 16:04
@bitbonsai

Copy link
Copy Markdown
Owner

Sorry for the slow reply here, day-job has kept me busy.

Hey @kartik7704, thanks for putting this together. get_note_outline and read_note_lines both sound genuinely useful for working with long notes.

The branch is hard to review as-is though: it diverged before a big upstream refactor, so the diff currently shows ~139 changed files (website, dist, skills, the old tree) instead of just your feature. Could you rebase onto current main and resubmit with only the new tools plus their tests? Once the diff is just the feature, I'm happy to take a proper look.

Returns heading structure (level, text, line) without loading full file content.
read_note_lines reads a specific line range for surgical section access.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

# Conflicts:
#	dist/src/createServer.d.ts.map
#	dist/src/createServer.js
#	dist/src/filesystem.d.ts
#	dist/src/filesystem.d.ts.map
#	dist/src/filesystem.js
#	src/createServer.ts
#	src/filesystem.ts
@kartik7704
kartik7704 force-pushed the feat/note-outline-tools branch from 122a8dd to 12eff72 Compare July 28, 2026 12:31
@kartik7704

Copy link
Copy Markdown
Author

Rebased onto current main. Turns out my fork's main was actually sitting on a September 2025 snapshot instead of last month (when i forked it), so it wasn't just normal drift.

The diff is now scoped to just the two new tools and their tests (12 files, down from 139). Also bumped the existing "server registers N tools" test since the new registrations change that count. All tests passing locally. Ready for your approval.

@bitbonsai bitbonsai left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clean rebase — this is exactly the diff I hoped for: feature-only, 31 new tests, green suite, dist in sync. get_note_outline and read_note_lines are both going to get real use.

Two things before I can merge:

  1. readNoteLines skips the path guards. It needs the same normalizePath + pathFilter.isAllowed block readNote has (src/filesystem.ts:137) — right now read_note_lines can read .obsidian/ files that every other tool blocks.
  2. parseOutline counts # lines inside fenced code blocks as headings. Track fence state (``` and ~~~) and skip those lines — patch_note has prior art for the fence handling.

Two smaller ones, take or leave: CRLF frontmatter (---\r\n) isn't skipped, and start/end clamping is asymmetric (end clamps, start errors — I'd clamp both and document it).

Happy to merge as soon as the two blockers are in. The structure (separate outline.ts with its own test file) is nice.

- getNoteOutline and readNoteLines now normalizePath() before the
  pathFilter.isAllowed() check, matching every other method - previously
  both skipped it, so read_note_lines could read files under .obsidian/
  that every other tool is blocked from touching.
- getNoteOutline now tracks fenced code block state (``` and ~~~) and
  skips lines inside one, so a code sample containing a shell comment or
  markdown example no longer gets misdetected as a real heading.
- getNoteOutline now skips the frontmatter block (both LF and CRLF line
  endings) before scanning for headings, so a YAML comment line doesn't
  get misdetected as an H1.
- readNoteLines clamps both startLine and endLine into [1, lines.length]
  instead of passing raw values to Array.slice, which silently wrapped
  to the end of the file for startLine <= 0 via slice's negative-index
  behavior.

Adds 6 new tests covering fences, LF/CRLF frontmatter, and the three
clamping edge cases. Full suite: 257 passed.
@kartik7704

Copy link
Copy Markdown
Author

Both blockers are in:

  1. getNoteOutline and readNoteLines now call normalizePath() before the pathFilter.isAllowed() check, matching every other method. Turned out getNoteOutline had the same gap even though only readNoteLines got called out, fixed both.
  2. getNoteOutline now tracks fence state (``` and ~~~) and skips headings inside code blocks. One correction: I went looking for the patch_note fence-handling you mentioned as prior art and couldn't find it, `patchNote` is a plain string-replace, no fence logic anywhere in it. Wrote it fresh instead.

Also took the two smaller ones:

  • getNoteOutline now skips the frontmatter block (LF and CRLF) before scanning, so a YAML comment doesn't get misread as a heading.
  • readNoteLines clamps both startLine and endLine into valid bounds now instead of just endLine.

Added 6 tests covering fences, LF/CRLF frontmatter, and the three clamping edge cases. Full suite: 257 passing, dist rebuilt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants