Qmd
breferrari/obsidian-mind
Search the vault using QMD semantic search. An agent skill from breferrari/obsidian-mind.
Service architecture patterns for the Obsidian plugin. An agent skill from aidenlx/zotlit.
$ npx skills add aidenlx/zotlit --skill obsidian-services -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install aidenlx/zotlit obsidian-services --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/aidenlx/zotlit.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/obsidian-services .claude/skills/obsidian-services && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "obsidian-services" agent skill from https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-services into .claude/skills/obsidian-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "obsidian-services", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-servicesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add aidenlx/zotlit --skill obsidian-services -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install aidenlx/zotlit obsidian-services --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aidenlx/zotlit.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/obsidian-services .agents/skills/obsidian-services && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "obsidian-services" agent skill from https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-services into .agents/skills/obsidian-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "obsidian-services", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add aidenlx/zotlit --skill obsidian-services -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install aidenlx/zotlit obsidian-services --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aidenlx/zotlit.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/obsidian-services .cursor/skills/obsidian-services && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "obsidian-services" agent skill from https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-services into .cursor/skills/obsidian-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "obsidian-services", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/aidenlx/zotlit.git --path .agents/skills/obsidian-services--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add aidenlx/zotlit --skill obsidian-services -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install aidenlx/zotlit obsidian-services --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aidenlx/zotlit.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/obsidian-services .gemini/skills/obsidian-services && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "obsidian-services" agent skill from https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-services into .gemini/skills/obsidian-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "obsidian-services", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install aidenlx/zotlit obsidian-servicesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add aidenlx/zotlit --skill obsidian-services -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/aidenlx/zotlit.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/obsidian-services .github/skills/obsidian-services && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "obsidian-services" agent skill from https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-services into .github/skills/obsidian-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "obsidian-services", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add aidenlx/zotlit --skill obsidian-services -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install aidenlx/zotlit obsidian-services --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/aidenlx/zotlit.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/obsidian-services .opencode/skills/obsidian-services && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "obsidian-services" agent skill from https://github.com/aidenlx/zotlit/tree/main/.agents/skills/obsidian-services into .opencode/skills/obsidian-services/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "obsidian-services", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
obsidian-servicesService architecture patterns for the Obsidian plugin. An agent skill from aidenlx/zotlit.
Obsidian Services is an agent skill from aidenlx/zotlit. Service architecture patterns for the Obsidian plugin. Use when creating, modifying, or wiring services in apps/obsidian/src/services/ or editing zt-main.ts lifecycle code.
Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Software architecture. It works with Obsidian. The repository describes itself as: Bring your Zotero library into Obsidian. Create literature notes, insert citations, and annotate PDFs without leaving your vault. The licence is AGPL-3.0.
8 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 27f5752. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Obsidian Services loads about 2.2k tokens when it runs. Until then it costs about 48 tokens; SKILL.md has 932 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from aidenlx/zotlit at commit 27f5752, republished under its AGPL-3.0 licence (© aidenlx). 932 words, ~2,194 tokens.
.claude/skills/obsidian-services/SKILL.md (or your agent's skills folder).Use the source as the canonical reference. Do not copy service/container/plugin-shell snippets out of this skill; read the current implementation before editing so examples cannot drift from real code.
apps/obsidian/src/services/service-base.ts: Service (abstract base class), ServiceContainer, and other utils.apps/obsidian/src/services/build.ts: buildServices wiring.apps/obsidian/src/zt-main.ts: plugin lifecycle ownership, await using, stack.move(), cleanup, and debug service access.apps/obsidian/src/lib/disposables.ts: Disposable helpers for stack.use(...).apps/obsidian/src/services/service-base.ts first for Service/ServiceContainer/ServiceInitError definitions and JSDoc. Open apps/obsidian/src/services/build.ts to see how buildServices wires services through container.use(...). Treat both as authoritative.apps/obsidian/src/zt-main.ts before changing plugin load/unload behavior. Keep it a thin lifecycle shell.apps/obsidian/src/services/<service-name>/service.ts.import type for upstream services.buildServices with one keyed .use(...) entry. Let the accumulated service type come from the container chain.plugin, plugin.app, upstream services, and optional deps explicitly through deps objects as needed. Avoid module-global service lookups.apps/obsidian/src/lib/disposables.ts helpers when adapting Obsidian or DOM registrations into Disposable values for stack.use(...).extend Service from services/service-base.ts. The base class owns [Symbol.asyncDispose] and the await ready → disposeAsync ordering; subclasses must not override [Symbol.asyncDispose].Service is generic in the ready resolve type. Use plain extends Service for startup-only services whose ready resolves to void; use extends Service<State> when #load() returns loaded resources/state.Component subclass, a DI library, or any other runtime dependency for service wiring.super(), store deps, and start startup by assigning ready (typically this.ready = this.#load()). They must not synchronously acquire resources or throw after startup begins.await using stack = new AsyncDisposableStack(), then handed to the base via this.commit(stack.move()) on the success path. commit() should be the last meaningful side effect before returning the ready state; avoid fallible work after commit. commit() throws on double-commit or commit-after-dispose; in those guard-failure paths it also fires off disposeAsync() on the passed stack so resources don't leak through the throw (disposal errors there are intentionally swallowed).ready is startup-only and must always settle. Do not await long-lived/post-load signals such as workspace.onLayoutReady inside ready — disposal awaits ready, so a non-settling ready hangs cleanup.ready promises. There is no global readiness gate or scheduler.ready and the base class disposer.Service and initialize ready = Promise.resolve(). They do not call commit() and do not need a constructor unless they have deps.ready dependency.ServiceContainer.use() accepts exactly one service entry and rejects duplicate keys.instanceof Service; a non-Service return is a typed error at registration time.ServiceInitError (original error preserved as cause) and reported per service. The wrapped rejection — not the original — is what cascades to dependent services that await this service's ready.buildServices(plugin, stack) wires services only; lifecycle ownership remains with the caller's stack in zt-main.ts.zt-main.ts focused on lifecycle wiring, action/menu/view registration, and cleanup.await using plus stack.move() pattern already implemented there for rollback-safe startup.services getter as normal dependency access. It is an escape hatch/debug surface; services should receive deps through buildServices.registerView factory.Pass layout or UI readiness signals as deps when needed, but schedule post-load work instead of making ready wait on those signals. Disposal waits for ready, so a non-settling ready can hang cleanup.
The shape below shows the required surface of a Service subclass. It is a structural template, not a snippet to copy verbatim — always read existing services in apps/obsidian/src/services/ before authoring a new one, since real services carry their own dep types and resource patterns.
Async service with deps and acquired resources:
import { Service } from "../service-base";
import type { SettingsService } from "../settings/service";
interface DatabaseState {
conn: Connection;
}
interface DatabaseServiceDeps {
plugin: ZotLitPlugin;
settings: SettingsService;
}
export class DatabaseService extends Service<DatabaseState> {
readonly #plugin;
readonly #settings;
ready: Promise<DatabaseState>;
constructor(deps: DatabaseServiceDeps) {
super();
this.#plugin = deps.plugin;
this.#settings = deps.settings;
this.ready = this.#load();
}
async #load(): Promise<DatabaseState> {
await this.#settings.ready;
await using stack = new AsyncDisposableStack();
const conn = stack.adopt(
await openDatabase(),
async (conn) => await conn.close(),
);
await this.#runMigrations(conn);
this.commit(stack.move());
return { conn };
}
async query(sql: string): Promise<Result> {
const { conn } = await this.ready;
return conn.query(sql);
}
}Sync-only service (no deps, no acquired resources):
export class TimeService extends Service {
ready = Promise.resolve();
now(): number {
return Date.now();
}
}Sync-only service with deps:
interface ClockServiceDeps {
plugin: ZotLitPlugin;
}
export class ClockService extends Service {
readonly #plugin;
ready = Promise.resolve();
constructor(deps: ClockServiceDeps) {
super();
this.#plugin = deps.plugin;
}
}Notes the shape encodes:
extends Service, never implements Service (no interface) and never a custom base.super() first in any explicit constructor.readonly private (#) fields; no public dep fields, no reach-through. Omit the type annotation on the field — let TypeScript infer it from the constructor assignment (readonly #app; not readonly #app: App;).ready is a mutable instance field. Declare it as ready: Promise<State> and assign in the constructor when load is async and returns state; use ready: Promise<void> for async startup with no state; initialize as ready = Promise.resolve() when load is sync. Do not mark it readonly — the container reassigns it to attach ServiceInitError wrapping.#load() under a local await using stack, handed off with this.commit(stack.move()) only on the success path. Treat commit() as the last meaningful side effect before returning the ready state.#load() as the ready resolve value; accessors do const { ... } = await this.ready; instead of storing nullable resource fields.[Symbol.asyncDispose] in the subclass — the base owns it.© aidenlx, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/obsidian-services of aidenlx/zotlit.
Open the folder on GitHubat commit 27f5752
Obsidian Services next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Obsidian Services this skillaidenlx/zotlit | 1k | — | ~2.2k | Automated safety check: Pass | AGPL-3.0 | |
| Qmdbreferrari/obsidian-mind | 5k | — | ~1.7k | Automated safety check: Pass | MIT | |
| Archify Diagramstt-a1i/archify | 81k | — | ~2.9k | Automated safety check: Pass | MIT | |
| JSON Canvasheyitsnoah/claudesidian | 2.6k | 18 repos | ~3.5k | Automated safety check: Pass | MIT | |
| Electron Multi-Process ArchitectureiOfficeAI/AionUi | 33k | 1 repos | ~1.8k | Automated safety check: Pass | Apache-2.0 | |
| Backend Code Reviewlanggenius/dify | 158k | — | ~676 | Automated safety check: Pass | Custom licence |
breferrari/obsidian-mind
Search the vault using QMD semantic search. An agent skill from breferrari/obsidian-mind.
tt-a1i/archify
Creates interactive architecture, workflow, sequence, data-flow and lifecycle diagrams as standalone HTML with inline SVG, themes and image or video export.
heyitsnoah/claudesidian
Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections.
iOfficeAI/AionUi
Tells the agent where new code belongs in an Electron multi-process project and which APIs each process may use, with rules for new bridges, services, agents and workers.
langgenius/dify
Reviews backend code under api/ for concrete, reproducible defects, routes to rule packs for architecture, schema, repositories and SQLAlchemy, and ranks findings from P0 to P3.
Cocoon-AI/architecture-diagram-generator
Creates dark-themed system, cloud, security and network architecture diagrams as self-contained HTML files with inline SVG and CSS.
aidenlx/zotlit
Obsidian house style for the wording of user-facing UI strings — command names, setting labels, button text, notices, modal copy.
aidenlx/zotlit
Style Obsidian plugin UI with Tailwind + native components. An agent skill from aidenlx/zotlit.
aidenlx/zotlit
Typed regex authoring with arkregex in this repo. An agent skill from aidenlx/zotlit.
aidenlx/zotlit
Write a user-facing changelog entry under apps/docs/content/changelog/.
aidenlx/zotlit
Draft a Discord announcement from a changelog entry. An agent skill from aidenlx/zotlit.
aidenlx/zotlit
Define ZotLit UI messages in the Inlang Message Format and consume them through the generated JSON Language Pack facade.
Works with
Categories
Service architecture patterns for the Obsidian plugin. An agent skill from aidenlx/zotlit. Obsidian Services is an agent skill from aidenlx/zotlit. Service architecture patterns for the Obsidian plugin.
Obsidian Services fits situations like: wiring services in apps/obsidian/src/services/; editing zt-main.ts lifecycle code.
Run `npx skills add aidenlx/zotlit --skill obsidian-services -a claude-code`. Or copy the skill folder (.agents/skills/obsidian-services in aidenlx/zotlit) into .claude/skills/obsidian-services in your project. Claude Code loads it when a task matches its description.
Run `npx skills add aidenlx/zotlit --skill obsidian-services -a codex`. Or copy the skill folder (.agents/skills/obsidian-services in aidenlx/zotlit) into .agents/skills/obsidian-services in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add aidenlx/zotlit --skill obsidian-services -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/obsidian-services, .gemini/skills/obsidian-services, .github/skills/obsidian-services and .opencode/skills/obsidian-services in your project.
SKILL.md names no scripts, command-line tools or credentials: Obsidian Services is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Obsidian Services is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.2k tokens (SKILL.md is roughly 8.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Obsidian Services: Qmd (breferrari/obsidian-mind, 5k stars), Archify Diagrams (tt-a1i/archify, 81k stars), JSON Canvas (heyitsnoah/claudesidian, 2.6k stars) and Electron Multi-Process Architecture (iOfficeAI/AionUi, 33k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
aidenlx (a GitHub user) maintains it in aidenlx/zotlit, which has 1,028 GitHub stars. The repository holds 16 skills in this directory. The repository was last updated on October 9, 2026.
Source: aidenlx/zotlit on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.