sense
Query a markdown tree with the sense CLI: filter notes by frontmatter, search prose, follow wikilinks and backlinks, trace link paths, find similar but unlinked notes, and inspect note outlines. Use when a task needs to query, filter, count, search, or report on a markdown directory; when a directory has sense.config.json; or when adding a saved sense query.
How do I install this agent skill?
npx skills add https://github.com/kmalakoff/sensemaking --skill senseIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill is functional for querying markdown files but introduces an indirect prompt injection surface as it processes untrusted user-controlled content. It also involves external downloads of CLI tools and database drivers via npm.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
sense
Use sense to locate evidence in a markdown tree before reading files. With the config default "build": true, CLI queries incrementally scan the configured tree for the capabilities they need; vector preparation is limited to the eligible scope. Config "build": false or a one-query --no-build reads the last completed indexed generation, checks requested readiness and does not scan live files. Explicit build and watch prepare it regardless of that default. Results contain paths, metadata, snippets, and line ranges. Read the returned files or ranges when the task needs their prose.
Setup, store selection, presets, and note design belong to the sense-setup skill. Translating an Obsidian Bases file belongs to sense-bases.
Use the shared Sense terminology when explaining results or output controls. Read it when distinguishing a snippet, section, section description, outline, chunk or link type; those names are not interchangeable.
Start with the tree
Run these when the tree or its configuration is unfamiliar:
sense status # config, store, cache, document count, preset coverage
sense map # fields, hubs, recent notes
sense --list # saved queries
If a command reports a missing config, run sense init only when the user wants the tree configured. A one-off query does not authorize changing the tree.
Choose the command
| Need | Command |
|---|---|
| Exact count, filter, grouping, or known-field report | sense sql or a saved SQL query |
| Notes about a subject | sense search |
| One note's frontmatter, outline, links, and backlinks | sense peek |
| Shortest link chain between two notes | sense path |
| Similar notes that a note does not link to | sense related |
| Tree shape and available fields | sense map |
Start with a bounded result. Raise --k, widen the preset, or broaden the words only when the first result does not answer the question.
sense search "pricing" --k 10
sense search "sourcing quotes" --preset raw
sense peek notes/pricing-model.md
sense path onboarding.md pricing-model.md
sense related notes/pricing-model.md --k 10
sense sql "SELECT path FROM frontmatter WHERE status = ? LIMIT 50" active
Read the store guide before composing syntax
The config's store key selects the SQL dialect and text-search grammar. An omitted key means sqlite. Bare words and quoted phrases work in sense search on every store. Advanced operators and raw text-index SQL differ.
Read the matching guide before writing raw SQL that uses engine functions, dates, JSON, text matching, or native types. Also read it before using advanced search operators.
The tables, ? placeholders, quoted identifiers, has(), basename(), and preset scope binding are shared. Portable SQL documents the schema and queries that work without depending on one engine.
Search and evidence
search combines the signals enabled by the selected preset:
| Signal | Evidence |
|---|---|
match | The note contains the search words. snippets shows the matching passages. |
link | A note that matched links to this note. |
vector | The embedding model placed this note near the query. The search words may be absent. |
Combinations such as match+link mean that more than one signal produced the row. score ranks rows within that result only. Do not compare it across searches. similarity ranks vector evidence within the current result and model. Do not carry a fixed similarity cutoff between trees.
The lines value gives a line range in the indexed note. It can identify a section around a word match or an embedding chunk. Read that range when it is present. A null range means the whole note is the reference. A vector-only row has no lexical snippet and is a lead, not proof that the note contains the query terms.
Read search evidence and troubleshooting when a search will support a factual claim, when absence matters, when results look noisy, or when tuning signal weights.
sense search --explain --format json adds the actual ranking contributions for returned notes. It does not change ranking or explain every missing result. The search guide describes how contributions differ from the via evidence label.
Scope and output
Bare commands use the default preset. --preset <name> chooses another. For search, map, peek, path, and related, --include, --exclude, and --no-exclude change the query scope for one invocation, but cannot reach files that no preset indexes. sense status shows actual coverage. Scope selects results; presets are not a security boundary.
peek rejects an exact path outside scope before trying a basename, resolves basenames within scope, and shows only scoped resolved links and backlinks; unresolved targets remain as written. path resolves its endpoints across the indexed tree and scopes intermediate notes. related resolves its seed across the indexed tree and scopes result candidates.
peek --section-count-limit n bounds section descriptions. --link-count-limit n independently bounds each group of outbound links, backlinks and unresolved links. Both default to 20 and require positive safe integers. Request more when the outline or links you need are truncated, or fewer for triage. Totals still describe the full selected groups; the limits do not widen scope. Section descriptions identify where to read; they do not return section prose.
--where filters search and graph commands against frontmatter alias f:
sense search "pricing" --where "f.status = 'active' AND has(f.tags, 'sales')"
sense sql is index-wide by default. With --preset, the command binds a temporary scope(path) table. The SQL must join it:
sense sql "SELECT f.path FROM frontmatter f JOIN scope ON scope.path = f.path" --preset default
Table output is for people. Use --format json when code or an agent will parse rows. Use --format csv when redirecting a large row set to a file. sql, search, related, and saved queries support all three formats. map, peek, status, and path support table and JSON.
Saved queries
Save a query in sense.config.json only when it will be reused:
{
"queries": {
"by-tag": { "sql": "SELECT path, title FROM frontmatter WHERE has(tags, ?) ORDER BY path" },
"hot": { "search": "pricing", "preset": "raw", "k": 20 }
}
}
Run these as sense by-tag urgent and sense hot. Invocation flags override a saved search's preset, k, or where value.
Running a saved entry validates it. Exit code 0 means it ran, 2 means the invocation needs different arguments, and 1 means the query or store failed. An empty result can be valid data, so interpret it from the query's purpose.
Tables
| Table | Holds |
|---|---|
frontmatter | One discovered column per frontmatter key, plus path, _mtime, _ctime, _size, _rank, and _parse_error |
content | path, title, summary, and authored text, plus store-owned search columns |
links | src, written target, resolved dst, and embed |
tags | Merged and deduplicated frontmatter and inline tags |
sections | Heading, level, line range, and token estimate |
preset_files | Paths covered by each preset |
Features can add tables. sense map and sense status show which features are active.
A non-null _parse_error means the file has no recovered frontmatter values. To distinguish a missing field from invalid frontmatter, include _parse_error IS NULL in the filter. Fixes appear on the next command because reconciliation runs first.
Reading discipline
Select only the columns needed for the answer. Use LIMIT for row-returning exploration. Prefer path, title, summary, and bounded snippets over content.text. Aggregates such as COUNT and GROUP BY are already bounded by their result shape.
When a result identifies a large note, use peek and then read the relevant line range. Small files are often cheaper to read whole.
Worked command traces are in EXAMPLES.md.
Upkeep
- Install a missing CLI with
npm install -g sensemaking. sense statusprints the cache path and watcher state.- Use
sense build --forceto recreate a derived index whose state is in doubt; source files, configuration, and the watcher ownership claim remain in place. - Use
sense watchwhen another process should keep all configured capabilities prepared during frequent edits. A default query scans the configured tree for its needed capabilities and limits vector preparation to eligible paths;--no-buildreads the completed generation only.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/kmalakoff/sensemaking/sense">View sense on skillZs</a>