Skip to content

feat: add 'notebrain refs' command to list note attachments and external links - #37

Open
nmdra wants to merge 18 commits into
masterfrom
feat/refs-command
Open

feat: add 'notebrain refs' command to list note attachments and external links#37
nmdra wants to merge 18 commits into
masterfrom
feat/refs-command

Conversation

@nmdra

@nmdra nmdra commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the notebrain refs <note> command: given a note (slug/title), list its
local attachments (images, PDFs, other files) and external links, with
--images/--pdf/--external-links kind filters and --include-missing
support.

Changes

  • feat(parser) 4505ef3, e222dc5: extract references (attachments +
    external links) from note bodies; track wiki vs markdown syntax source for
    resolution; unified first-occurrence document ordering across kinds
  • feat(ingest) c0e9f28: expose the configured Obsidian attachment folder
    to refs resolution
  • feat(cmd) d7ee594: the refs command with kind filters,
    --include-missing, and text/JSON/TSV/JSONPath output (via existing global
    --format/--jsonpath flags)
  • fix(cmd) 0536f6c: keep cross-kind first-occurrence order; drop
    attachment candidates that traverse outside the vault instead of surfacing
    them
  • docs d46ff10, 9f5feff, 4b8823e: README, wiki/Commands.md,
    CHANGELOG, AGENTS.md, notebrain skill reference updates, Plan.md tasks 0-7
    marked complete

Verification

  • make test: all packages pass
  • make lint: clean; lefthook pre-commit hooks (fmt, modernize, lint,
    test-short) pass on every commit
  • Skill eval loop (iteration-4): 24/24 assertions pass on the refs scenarios
    (inventory, broken-reference audit, fixture vault)
  • Manual e2e: text/json/tsv/jsonpath output, kind filters, bad slug → exit 1,
    empty note → "No references found", PDF note → rejected with error,
    traversal escapes never reported even with --include-missing

nmdra added 9 commits August 12, 2026 13:48
- add LoadAttachmentFolderPath reading .obsidian/app.json
- share the app.json read with LoadExcludedPaths via readObsidianAppConfig
- add refs command resolving wiki and markdown attachment references
- resolve wiki refs via Obsidian search order (note folder, vault root,
  attachment folder) and markdown refs note-folder-relative
- hide broken links by default, surface them with --include-missing
- filter by kind with --images/--pdf/--other/--external-links (OR)
- render text/JSON/TSV output with jsonpath support
- README: feature bullet and chaining example
- wiki/Commands.md: full refs section with flags, examples, JSON shape
- AGENTS.md: structure tree entry and CLI flag standards
- CHANGELOG.md: unreleased entry for the refs command
- iterate extracted refs in document order so external links
  interleave with attachments (first-occurrence order)
- drop attachment candidates that escape the vault instead of
  listing them as missing

Refs: #code-review (standards + spec findings on refs branch)
- un-ignore the plans directory so Plan.md is tracked
- tick tasks 0-7 for the refs feature
@nmdra nmdra self-assigned this Aug 12, 2026
@nmdra nmdra added enhancement New feature or request cli query labels Aug 12, 2026
nmdra added 6 commits August 13, 2026 13:05
- add FileTypeMD/FileTypePDF to internal/store (single source; ingest
  imports store, so no cycle) and use them in query.go where file_type
  filters compare against a bare "md" literal
- drop ingest's private fileTypeMD/fileTypePDF mirrors in favor of
  store.FileTypeMD/FileTypePDF
- add blockKindList/blockKindTable/blockKindBlockquote in the parser and
  replace the remaining string literals in ast.go block handling
- comment the renderer's "attachment" label and leave its value
  unchanged (chunk text change would force a full re-ingest)
- search TSV header slug -> note_slug; scores at 4dp like JSON
- get TSV fields escaped via tsvEscape; get/stats apply --jsonpath to
  the command envelope so $.command works (get paths shift to
  $.note.*)
- warn once on stderr when --format/--jsonpath are given to text-only
  commands (ingest, reset, doctor, doctor-probe, init, version,
  completion, suggest-notes); stdout stays clean
- share the vault-path usage error between commands via one constant

BREAKING CHANGE: get --jsonpath values like $.note_slug must move to
$.note.note_slug.
- --image/--pdf/--other/--external become --only-images, --only-pdfs,
  --only-other, --only-external; old names stay as hidden aliases
  merging into the same sets
- help text now states: no filter = all kinds; multiple filters are
  unioned
- --only-* combos also apply to --tsv output, where missing is now
  always false (missing files are not ingested yet, so they are not
  "missing"; silence the noise when piping)
- hoist the vault-path usage error to the shared constant so ingest
  and refs print the same message
- ingest --enable-pdf => --with-pdf (hidden --enable-pdf alias kept for
  compatibility); init wizard writes the with-pdf config key while
  still honouring a legacy enable-pdf key on read
- get takes the note slug positionally: get <NOTE> (legacy --slug flag
  kept); echoed field is Note
- search --exclude-note => --exclude-notes (hidden alias merges)
- remove the hidden --top-k in favour of sole --candidate-chunks with
  default 3; config key remains top_words
- config.example.toml documents with-pdf at ingest and drops the
  deprecated enable-pdf line in favour of the with-pdf key

BREAKING CHANGE: the hidden --top-k flag is removed; use
--candidate-chunks instead.
- commands docs: refs --only-* filters, ingest --with-pdf, get <NOTE>,
  search --exclude-notes, --candidate-chunks; hidden aliases listed for
  each command
- PDF ingestion doc: with-pdf key + legacy enable-pdf read note
- architecture doc: get --jsonpath paths shift to $.note.*
- AGENTS.md notes the flag-naming standards (verb flags, --only-*
  filter pattern) and updates the file tree
- skill references (flags, example, schema) match the new flags and
  config keys
- changelog: Unreleased entries under Added/Changed/Deprecated/Removed
@nmdra
nmdra requested a balanced review from Copilot August 13, 2026 07:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

nmdra added 2 commits August 13, 2026 13:16
- config keys are flat (not section-scoped), so the template advertised
  two independent with-pdf keys in different sections; uncommenting the
  search one collided with the ingest one at parse time (duplicate TOML
  key) and implied search PDFs could be toggled separately
- search section now documents that with-pdf is the same global key as
  ingest's; one value governs both ingest and search
- init wizard comment clarifies its replace targets that single key
- note title header banner, per-kind colored [kind] chips (images
  accent, PDFs blue, other muted, external links bold), amber
  (missing) markers via warnBoldStyle, and a hintStyle empty state
- OSC 8 hyperlinks when the terminal supports them: attachments open
  obsidian:// URIs, external links open their URL; Ctrl+click footer
- attachment rows display vault-relative paths instead of absolute
  ones to reduce clutter (external links keep their URL; JSON/TSV
  keep absolute paths unchanged); hyperlink targets unaffected
- rows truncated to terminal width with ansi.Truncate
- tests: new plain/colored/empty render tests mirroring the search
  PDF-tag pattern; text assertions updated to relative paths
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli enhancement New feature or request query

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants