Cross-plugin APIs
Plugins communicate through a loaded plugin's api object,
available under app.plugins.plugins["<plugin-id>"]. They do not
import one another's generated main.js files. Consumers should
feature-detect both the provider and the method or namespace they need; an
unloaded plugin is not a usable dependency.
API objects are additive compatibility surfaces. Check a namespace's own
version when it has one instead of assuming every namespace
changes with the root version. Guard cross-plugin calls and handle failure
results.
Block ID Prompt¶
block-id-prompt.api.pomodoroLinkPicker is namespace version 1.
pick(request) resolves to a selected open Pomodoro
({ kind: "existing", entryLine, entryText, title }), a new
destination ({ kind: "new", name }), or null when
cancelled, unavailable, or unable to resolve today's Pomodoros. The promise
does not reject. A new choice made from Recent may include the additive
preserveSpelling: true field so the caller keeps the catalog's display name.
Navigation Hotkeys uses this picker for successor offers.
Bob Ledger Tools¶
The root bob-ledger-tools.api is version 3. It shares live
planning data and presentation helpers: caps,
planBudget, todayKeys, isToday,
todayRank, nextBudget, pendingBudget,
dashboardLaneBudget, renderDashboardLaneBadge,
readyBudget, renderReadyBadge, and
renderReviewChip. With content supplied,
planBudget({ path?, content? }) measures post-write content
synchronously; without it, the API reads the target note asynchronously.
isToday uses the task path and Tasks block link; it returns false when
either identity field is missing or the Today ledger cache is not ready.
todayRank(task) returns that task's zero-based index in the cached Today
ledger, or Number.MAX_SAFE_INTEGER when the task has no rank.
| Namespace | Version | Purpose |
|---|---|---|
stats |
2 | Append validated review events; host, fetch, and bobPath support Stats and consumers. |
themes |
1 | Share the Pomodoro theme catalog; hueFor, componentsOf, historyRows, and similarTo are synchronous, fetch and snapshot serve the cached bob themes list report, hide/unhide/color/rename spawn bob with --via, and onChange subscribes to updates. |
workBadges |
2 | Return count-to-limit badge tones through tone and todayTone. |
freshness |
12 | Read or update freshness, refresh intervals, keep counts, review queue, and unblocked metadata. |
noteReady |
1 | Read per-note Ready-lane counts and render the crowded-note chip. |
dashboardCollections |
1 | Snapshot or render PROJECTS and REFERENCES badges. |
priorityMarks |
1 | Model and render priority marks. |
dateMarks |
1 | Model and render canonical date marks. |
progressMarks |
1 | Refresh the display-only In Progress Task Link mark. |
unblockedGlyph |
1 | Refresh the display-only unblocked hand-off glyph. |
relationIndex |
1 | Read the live, source-authoritative task relation index and label suggestions. |
relationLabels |
1 | Read the relation-label catalog and delegate hide, unhide, and previewed rename writes to bob. |
relationIndex.ready() reports whether the chunked initial scan is complete;
generation increases whenever a complete pair of forward and reverse maps
is published. outgoing(path, blockIdOrLine) accepts a block ID, a 1-based
task line number, or the source task's line text, and returns its relation
rows, including unresolved targets. incoming(path, blockId) returns
only rows whose target path and block ID resolve. Each row contains source
and target task records (path, blockId, line, text, and status),
the optional label, relation line number and raw text, plus resolved,
archived, embedded, and struck flags. labelSuggestions(prefix?) returns
case-insensitively deduplicated { label, count } rows ordered by count, then
Unicode code point. onChange(callback) subscribes to atomic map publications
and returns an unsubscribe function. Task text and status prefer the Tasks
cache and fall back to indexed note text, including read-only done/ notes.
The index scans relation-bearing Markdown files in idle chunks, including
done/, and updates from metadata changes, vault create/delete/rename events,
and the active editor's unsaved text. Relation targets are resolved with
Obsidian's link resolver and cached block IDs. Consumers render from this live
index; they do not read the generated LINKED FROM mirror as source data.
relationLabels.rows(query?, { hidden }) and hiddenCount() expose the
catalog and folded hidden preferences. hide(name), unhide(name), and
rename(from, to, { dryRun?, merge?, via? }) resolve { ok, code?, message?,
report? } without rejecting. Writes spawn bob with --via and refresh the
read-only journal fold; rename previews return the dry-run report without
writing.
- Register
vaultcreate/modifylisteners insideworkspace.onLayoutReady, because Obsidian replayscreatefor every vault file (PDFs included) during load. - Never
read/cachedReadnon-Markdown files from a vault event.
The read-only readyBudget() returns
{ count, cap, over }; unavailable Tasks data or an unready cache
returns a null count. dashboardLaneBudget(lane) returns
{ section, lane, cap, over, today } with null section/lane when
unavailable. Here pending selects Tasks status IN_PROGRESS and next
selects status symbol *. The section count excludes Today; badges use it
for color and turn over only when section > cap. Whole-lane pressure remains
in the tooltip. The no-argument pendingBudget() and nextBudget() keep
whole-lane counts for existing callers. Render helpers accept a host and
optional source-path/component context so mounted views can refresh with their
lifecycle.
The freshness namespace advertises
trackerReview, checklistTiers, and
recurringTier. Its methods include config,
stampLine, setRefreshLine,
keepLine, markUnblockedLine,
state, returnedBy, bucket,
reviewModel, isDue, tier,
rank, intervalFor, intervalForLine,
queue, counts, lints, and
reviewEntryView. These calls are synchronous and do not throw;
keepLine is the sole helper that increments the keep streak.
Generic freshness stampers clear that count. A counted keep saturates at 999
and increments only when the line has a valid [fresh::] date before today;
missing, malformed, or same-day freshness does not add to the streak.
Navigation Hotkeys exposes freshnessDecayCard.version >= 2 as a capability
for the approved decay decision card. Ledger Tools shows the decision-card
leaf and Alt+F to decide hint only when that capability is present and decay
is enabled. Without either condition, freshness marks use counting-only
wording.
Navigation Hotkeys, Task Status Cycler, and Block ID Prompt delegate freshness
placement to Ledger Tools with
api?.freshness?.stampLine?.(line, dateText) ?? line when the Ledger Tools
root API is version 3 or later. They do not place [fresh::] themselves.
noteReady provides snapshot(now?),
forNote(path), counted(task),
inCrowdedNote(task), groupLabel(task), and
renderCrowdedChip(host, options?). It reads the area/project
note's Ready lane against the shared cap and is synchronous.
themes shares the Pomodoro theme catalog (namespace version 1). Every
picker uses it; no plugin keeps its own hidden list or history scanner.
available() is false on mobile, where pickers stay today-only but colors
(hash, area, and journal pins from the vault .bob/themes/ fold) still
render. fetch() resolves { report, stale, error } with stale-while-
revalidate single flight over bob themes list -a -f json;
snapshot() returns the last report without spawning. hueFor(key, name)
returns { hue, hue_source } (null hue for exempt themes) and never throws.
componentsOf(name) returns { raw, key } rows, historyRows({ query,
limit, exclusions }) ranks visible catalog themes per PT7 group B then D,
and similarTo(name) returns up to 2 near-duplicate names. hide,
unhide, color, and rename spawn bob with --via bob-ledger-tools,
then refresh; they resolve { ok, code?, message? } and never reject —
an older bob without the writers resolves code: "unsupported".
onChange(callback) subscribes to catalog changes and returns an
unsubscribe function. The --bob-hue-* tokens in the ledger stylesheet are
the single source for theme color; later picker surfaces reuse them. The JS
mirrors of the hue rule, the journal fold, and the PT7 ranking are pinned by
scripts/fixtures/pomodoro_themes/vectors.json, copied byte-for-byte from
bob-cli. See the Pomodoro themes contract
for the shared catalog, hue, and menu rules.
dashboardCollections provides snapshot() and
renderChip(host, options?) for live PROJECTS/REFERENCES badges.
priorityMarks exposes model(value) and
render(host, value, { decorative?, inheritColor? }).
dateMarks exposes model(field, dateText) and
render(host, field, dateText, { decorative?, inheritColor? });
its fields are created, scheduled,
completion, and cancelled. These glyphs are
display-only. progressMarks exposes expect(entries),
refresh(), and isEnabled(); the
unblockedGlyph namespace exposes refresh() and
isEnabled().
Bob Navigation Hotkeys¶
The root bob-navigation-hotkeys.api is version 3:
| Namespace or method | Version | Purpose |
|---|---|---|
reviewWalk |
1 | Capture a review landing with capture(editor), then continue it after a gesture with continue(origin, outcome). |
inboxRoute |
1 | Test an inbox path and prompt or commit a route. |
quickRoll |
1 | Preview the Alt+P roll for a review row. |
taskLinkLane |
1 | Match a Pomodoro Task Link and toggle its Next/In Progress lane. |
notice |
1 | Show the Unblocked card. |
successors |
1 | Ask which offered successor links to add. |
blocks |
1 | Open the reverse Blocks stage or remove a dependent. |
relations |
0 | Remove a LINKS edge (removeLink). openStage opens the Links direction; the reverse direction settles { ok: false } until both stage directions ship. |
openReferencePdf(path) |
Additive member | Open a vault-relative PDF in Highlights; resolves { ok, reason? }. |
openDependencyStage(ref) |
Root method | Open the task's dependency stage. |
removeDependency(parentRef, target) |
Root method | Remove the requested prerequisite. |
claimReviewWalkCompletion(editor) |
Root method | Claim completion handoff for a landed review row. |
inboxRoute has isInboxNote(path),
prompt(request), and commit(request).
quickRoll has keyLabel (Alt+P) and
preview({ content | lines, line, tier }). preview is synchronous
and never throws: it plans the same recommendation Alt+P would use
and returns the frozen { ok, kind, line, compact, detail } preview,
or { ok: false, reason } for PRE/POST rows and lines with no
recommendation. With a null plugin (after unload) it returns
{ ok: false, reason: "unavailable" }; the root api version stays 3.
taskLinkLane.matches({ content, line, path }) is synchronous;
toggle(args) performs the Next/In Progress change and resolves
to a result object. successors.pick(model) resolves to a result
with a picks array or null when no choice is made.
blocks.openStage(ref) and
blocks.removeDependent(ownerRef, target) resolve to result
objects. relations.removeLink(sourceRef, targetRef) removes the
authored LINKS edge from the source and best-effort-updates the
target's LINKED FROM mirror; relations.openStage({path, line,
direction}) opens the owner's Links stage for direction: "to" (or an
absent direction) and settles { ok: false, reason: "unavailable" }
otherwise. Callers
feature-detect api.relations?.version >= 1 before showing chip
controls. notice.showUnblocked(model) presents the Unblocked card.
Async navigation methods settle to result objects or null rather
than rejecting. taskLinkLane.matches is synchronous and
toggle settles its result. reviewWalk.capture returns
null when there is no current landing;
reviewWalk.continue resolves its advance result.
Task Status Cycler¶
task-status-cycler.api is version 2:
recoverBlockedDependents(identities, context?)runs the same dependent recovery as task completion without retiring references. It resolves to{ reopened, failures }; tasks with a strictly futurescheduleddate remain Blocked. Each identity haspathand at least one ofblockIdortaskId. The method never throws; failures are returned in the result.completeTaskAtCursor(editor)completes the cursor task through Tasks'set-status-symbol-to-xcommand so recurrence can run; it never writes[x]directly. It returns{ ok: true, lineDelta, successorNotice }or{ ok: false, reason }and does not stamp the task.
Related¶
- Block ID Prompt
- Bob Ledger Tools
- Bob Navigation Hotkeys
- Task Status Cycler
- Plugin architecture — generated sources and module boundaries.