Skip to content

ctx.* Services Reference

Call these exact signatures — do not guess method names.

Services (declare in inject)

  • vault: getMarkdownPaths() → string[] (vault-relative paths; alias listMarkdown); read(path) → string; write(path, content); create(path, content); createFolder(path) (creates nested); delete(path); rename(old, new); on(ev, cb) (vault/modify|create|delete|rename)
  • views: registerView(type, (leaf) => view); open(type)
  • commands: addCommand({ id, name, callback })
  • ribbon: addRibbonIcon(icon, title, callback){ remove }
  • statusbar: addStatusBarItem(){ el, remove }
  • notice: notice(message, timeoutMs?)
  • workspace: getActiveFile() → string | null; onFileOpen(cb)
  • editor: getSelection() / insertText(text) / replaceSelection(text) (null when no active editor)
  • toolsCompat: register({ name, description, input, execute }) (execute returns JSON-serializable)
  • settings: get(key, fallback) / set(key, value); registerSettingTab(tab)
  • sandbox / approval / sessionLog / llmCaller / dshI18n: see the respective chapters

Events (ctx.on)

dsh/session/event, vault/modify|create|delete|rename, workspace/file-open, dsh/waiting-approval.

Panel plugin

js
const { ItemView } = require('obsidian')
class MyView extends ItemView {
  getViewType() { return 'my-view' }
  getDisplayText() { return 'My Panel' }
  onOpen() { this.contentEl.createEl('h3', { text: 'Hello' }) }
}
module.exports = {
  name: 'my-plugin',
  inject: ['views', 'commands'],
  apply(ctx) {
    ctx.effect(() => [
      ctx.views.registerView('my-view', (leaf) => new MyView(leaf)),
      ctx.commands.addCommand({ id: 'open', name: 'Open panel', callback: () => ctx.views.open('my-view') }),
    ])
  },
}