Claude Code Plugins

Community-maintained marketplace

Feedback
21
0

Use when creating, linking, searching, or exporting notes—use `wiki` CLI for automatic notebook discovery, or `zk` directly when you need explicit control

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name storage-zk
description Use when creating, linking, searching, or exporting notes—use `wiki` CLI for automatic notebook discovery, or `zk` directly when you need explicit control

Personal Wiki: Using the wiki CLI

[!Note]

Preferred approach: Use the wiki CLI wrapper for automatic notebook discovery. Fallback to direct zk commands only when you need explicit control over notebook paths.

Quick Start: wiki CLI

The wiki CLI intelligently discovers your notebook path. No -W flag needed:

# Discover notebook for current project
wiki project discover

# Get project ID and metadata
wiki project id

# Use discovered notebook (auto-discovers path internally)
wiki new --title "My Note"
wiki list --match="pattern"
wiki list --format=json > export.json

If you need the notebook path explicitly for direct zk commands:

NOTEBOOK=$(wiki project discover)
zk list -W "$NOTEBOOK" --match="search"

Discovery Process

The wiki script uses this priority order:

  1. Environment variable NOTEBOOK_PATH (if set, use it directly)
  2. Ancestor directory search (finds .zk/config.toml in parent directories)
  3. Context matching (scans ~/Notes/ for matching project contexts)
  4. Global fallback (uses ~/.config/zk/config.toml if it defines notebook.dir)

This means in most cases, you just run wiki commands without specifying paths.

Overview

Personal Wiki is a lightweight zettelkasten system using ZK (a markdown-based CLI tool). Core principle: all data is markdown files; CLI just organizes, searches, and exports them. Avoid assuming commands exist (no export or link commands); instead use flags and manual editing.

Common Workflows with wiki CLI

Single Note: Create → Link → Search → Export

# 1. Create new note (auto-discovers notebook)
NOTE_PATH=$(wiki new --title "Research Topic" --print-path)

# 2. Edit file and add links (manual)
echo -e "\n\nRelated: [[existing-note-id]]" >> "$NOTE_PATH"

# 3. Search for related notes
wiki list --match="Research" --format=long

# 4. Export results
wiki list --match="Research" --format=json > related-notes.json

Get Project Info & Notebook Path

# Get project ID for the current directory
wiki project id

# Get the actual notebook path
NOTEBOOK_PATH=$(wiki project discover)
echo "Using notebook at: $NOTEBOOK_PATH"

# Register current project with notebook (for context matching)
wiki project add

Export All Notes from Project

# Get notebook, then export
NOTEBOOK=$(wiki project discover)
wiki list --format=json > all-notes.json

# Validate export
jq . < all-notes.json > /dev/null && echo "Valid JSON"

When to Use

Symptoms:

  • Creating notes but unsure about notebook path
  • Need to export notes in various formats
  • Want automatic project-to-notebook mapping
  • Working with multiple projects and notebooks

When NOT to use:

  • Editing notebook configuration (see zk documentation for config.toml)
  • Advanced templating (templates are Handlebars, see zk docs)
  • LSP setup (language server integration, separate config)

wiki vs. Direct zk Commands

Scenario Use Example
Notebook path unknown wiki CLI wiki new --title "Note" (auto-discovers)
Known notebook path Direct zk zk list -W /path --match="x" (explicit control)
Get notebook path first wiki project discover NOTEBOOK=$(wiki project discover)
Get project ID wiki project id Returns JSON: projectId, repo, remote
Register project context wiki project add Helps future discovery for this project

Quick Reference: wiki CLI Commands

Task Command Notes
Create note wiki new --title "Title" --print-path Auto-discovers notebook; returns path
List all notes wiki list Defaults to table format
Search pattern wiki list --match="pattern" Regex or plain text
Export JSON wiki list --format=json > file.json Use redirection for output
Export CSV wiki list --format=csv > file.csv RFC 4180 compliant; use CSV parser
Export oneline wiki list --format=oneline > file.txt Minimal format, easy to parse
Find backlinks wiki list --linked-by=<note-id> Shows notes linking to target
Show note details wiki list --match=<note-id> --format=long Includes metadata and preview

Quick Reference: Direct zk Commands (When You Need Explicit Control)

Task Command Notes
Create note zk new -W <dir> --title "Title" --print-path Explicit notebook path required
List all notes zk list -W <dir> Always include -W flag
Search pattern zk list -W <dir> --match="pattern" Regex or plain text
Export JSON zk list -W <dir> --format=json > file.json Use redirection for output
Export CSV zk list -W <dir> --format=csv > file.csv RFC 4180 compliant; use CSV parser
Find backlinks zk list -W <dir> --linked-by=<note-id> Shows notes linking to target

Filtering Options

Filter Syntax Example Note
Title/body --match="pattern" zk list -W /nb --match="daily" Regex or plain text search
Linked-by --linked-by=<id> zk list -W /nb --linked-by=abc123 Show notes linking to abc123
Other filters Check zk list --help zk list --help | grep -i filter ZK may have additional filters not listed

Important: For any filtering not shown here, always verify with zk list --help before assuming syntax. ZK may add new filters in newer versions.

Understanding Notebook Discovery

The wiki CLI automatically handles notebook discovery using a smart search algorithm. No need to manually specify -W flags.

How wiki Discovers Your Notebook

When you run any wiki command, it searches in this order:

  1. Environment variable NOTEBOOK_PATH (if explicitly set)
  2. Ancestor directories for .zk/config.toml (finds project-local notebooks)
  3. Context registry in ~/Notes/ (matches your project path to a registered notebook)
  4. Global fallback ~/.config/zk/config.toml (if it defines a notebook.dir)

Advantage: You don't need to worry about getting the path wrong. Just run wiki commands.

Direct zk Commands: Explicit -W Flag Required

If you bypass wiki and use zk directly, you must always include -W:

# ❌ DON'T - unsafe, ambiguous which notebook is used
zk list --match="search"

# ✅ DO - explicit notebook path
zk list -W /path/to/notebook --match="search"

Why? Without -W, ZK searches UP the directory tree until it finds the first .zk folder. With nested notebooks, this can pick the wrong one:

~/projects/
  .zk/                 # master notebook
  project-a/
    .zk/               # project-a notebook ← you want this
    notes/

If you're in ~/projects/project-a/notes/ and run zk list without -W, it might find ~/projects/.zk instead.

Troubleshooting: Verify Which Notebook Is Active

# Using wiki (recommended)
wiki project discover
# Returns: /path/to/notebook

# Using direct zk with explicit path
zk info -W /path/to/notebook
# Shows: notebook path, config, note count

Link Creation Patterns

ZK does not have a zk link command. Links are created by editing markdown files directly:

Wiki-style Links (Most Common)

This note connects to [[other-note-id]] and [[another-one]].

ZK automatically resolves these to matching note IDs. The ID can be filename without extension or explicit ID field in note frontmatter.

Markdown Links (Also Valid)

See [related note](/path/to/note.md) for details.

ZK understands both formats. Wiki-style [[]] is preferred for cross-referencing.

Backlink Discovery

Find all notes linking to a specific note:

zk list -W /notebook --linked-by=target-note-id

Export Workflows

Pattern: Use zk list with --format flag + output redirection

Before Any Bulk Export: Safety Checklist

Bulk exports (100+ notes) can be dangerous if not validated:

  • Do you have a backup of the notebook? (cp -r /notebook /notebook.backup)
  • Are you exporting to test data first? (Start with --match="test" to validate format)
  • Do you understand what you're exporting? (Links as refs? Full body? Metadata?)
  • Is the output format valid? (Test with head -5 export.json | jq .)

Example: Safe bulk export

# 1. Validate on one note
zk list -W /notebook --match="note-id" --format=json | jq .

# 2. Check structure is what you expect
# (inspect the JSON output)

# 3. Export to temp file first
zk list -W /notebook --format=json > /tmp/export.json

# 4. Validate output is valid JSON
jq . < /tmp/export.json > /dev/null && echo "Valid JSON"

# 5. Move to final location
mv /tmp/export.json ~/exports/notes.json

JSON Export (Programmatic)

zk list -W /notebook --match="tag:project" --format=json > export.json

Output includes: id, title, path, body, tags, relationships

CSV Export (Spreadsheet Import)

zk list -W /notebook --format=csv > notes.csv

Output columns: title, path, modified date. Parse with CSV reader, not awk.

Oneline Export (Grep-able)

zk list -W /notebook --format=oneline > index.txt

Output: id - title - path on single line per note

Common Mistakes

Mistake Problem Fix
Using zk without -W flag Ambiguous which notebook is used Use wiki CLI (auto-discovers) or explicit -W /path
zk export No export command exists Use wiki list --format=X > file (or zk list -W <dir>...)
zk link note1 note2 No link command Edit markdown files, add [[note-id]] manually
wiki list --match="x" fails Notebook not discovered Run wiki project discover to verify path
--format json (no redirection) Output prints to stdout, not file Use > file.json to capture output
[[filepath]] instead of [[id]] Wiki-links use ID, not path Use note ID or filename without extension
Assuming links created CLI-side Links are manually edited Always add links by editing note files directly
Hardcoding notebook paths in scripts Breaks when project moves Use wiki CLI or wiki project discover instead

Reference: Output Formats

Table (Default)

id | title | path

Long (Includes Metadata)

id: xxx
title: My Note
path: /notebook/notes/xxx.md
tags: [tag1, tag2]
links: [[id1]], [[id2]]

JSON (Programmatic Parsing)

[{"id":"xxx","title":"My Note","tags":["tag1"],"path":"/notebook/notes/xxx.md"}]

CSV (Spreadsheet Import) — RFC 4180 Compliant

Format: Quoted fields, comma-separated, includes header row

title,path,modified
"My Note",/notebook/notes/xxx.md,2025-01-15
"Note with, comma",/notebook/notes/yyy.md,2025-01-14

Important: Parse CSV with a proper CSV parser, not awk -F',', because titles can contain commas. Example with Python:

import csv
with open('notes.csv') as f:
    for row in csv.DictReader(f):
        print(row['title'], row['path'])

Oneline (Grep-able)

xxx - My Note - /notebook/notes/xxx.md

Workflow Examples

Single Note: Create → Link → Search → Export (Using wiki CLI)

# 1. Create new note (notebook auto-discovered)
NOTE_PATH=$(wiki new --title "Research Topic" --print-path)

# 2. Edit file and add links (manual)
echo -e "\n\nRelated: [[existing-note-id]]" >> "$NOTE_PATH"

# 3. Search for related notes
wiki list --match="Research" --format=long

# 4. Export results
wiki list --match="Research" --linked-by="research-topic-id" --format=json > related-notes.json

Advantage: No need to discover notebook path manually. wiki handles it.

Single Note: Using Direct zk (When You Need Explicit Control)

# 1. Create new note with explicit notebook path
NOTEBOOK="/path/to/notebook"
NOTE_PATH=$(zk new -W "$NOTEBOOK" --title "Research Topic" --print-path)

# 2. Edit file and add links (manual)
echo -e "\n\nRelated: [[existing-note-id]]" >> "$NOTE_PATH"

# 3. Search for related notes
zk list -W "$NOTEBOOK" --match="Research" --format=long

# 4. Export results
zk list -W "$NOTEBOOK" --match="Research" --linked-by="research-topic-id" --format=json > related-notes.json

Note: Step 2 requires manual file editing. No CLI command creates links; you add them to markdown content.

Bulk: Create Multiple Notes & Link to Master (Using wiki)

For creating 10+ notes that all link to a master note:

#!/bin/bash
MASTER_ID="master-index"

# Create notes in a loop (notebook auto-discovered)
for i in {1..10}; do
  NOTE_PATH=$(wiki new \
    --title "Topic $i" \
    --print-path)
  
  # Add link to master note
  echo "" >> "$NOTE_PATH"
  echo "See master: [[${MASTER_ID}]]" >> "$NOTE_PATH"
done

# Verify all notes link to master
wiki list --linked-by="$MASTER_ID" --format=long

Advantage: No need to discover or pass notebook path. wiki handles it automatically.

Bulk: Using Direct zk (Explicit Notebook Path)

For explicit control over notebook:

#!/bin/bash
NOTEBOOK="/path/to/notebook"
MASTER_ID="master-index"

# Create notes in a loop
for i in {1..10}; do
  NOTE_PATH=$(zk new -W "$NOTEBOOK" \
    --title "Topic $i" \
    --print-path)
  
  # Add link to master note
  echo "" >> "$NOTE_PATH"
  echo "See master: [[${MASTER_ID}]]" >> "$NOTE_PATH"
done

# Verify all notes link to master
zk list -W "$NOTEBOOK" --linked-by="$MASTER_ID" --format=long

Constraint: ZK doesn't have a bulk-link command. Manual editing via script is the standard approach.

Export Large Notebook Safely (Using wiki)

#!/bin/bash
EXPORT_DIR="$HOME/exports"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Create export directory with timestamp
mkdir -p "$EXPORT_DIR"

# Test export format on small sample (notebook auto-discovered)
echo "=== Testing format on 1 note ==="
wiki list -l 1 --format=json | jq . > /dev/null
if [ $? -ne 0 ]; then
  echo "ERROR: JSON validation failed"
  exit 1
fi

# Full export
echo "=== Exporting all notes ==="
wiki list --format=json > "$EXPORT_DIR/export_${TIMESTAMP}.json"

# Validate output
jq . < "$EXPORT_DIR/export_${TIMESTAMP}.json" > /dev/null
if [ $? -eq 0 ]; then
  echo "✓ Export successful: $EXPORT_DIR/export_${TIMESTAMP}.json"
else
  echo "✗ Export failed: JSON is invalid"
  exit 1
fi

Advantage: No manual path discovery needed.

Export Large Notebook Safely (Direct zk with Explicit Path)

#!/bin/bash
NOTEBOOK="/path/to/notebook"
EXPORT_DIR="$HOME/exports"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Create export directory with timestamp
mkdir -p "$EXPORT_DIR"

# Test export format on small sample
echo "=== Testing format on 1 note ==="
zk list -W "$NOTEBOOK" -l 1 --format=json | jq . > /dev/null
if [ $? -ne 0 ]; then
  echo "ERROR: JSON validation failed"
  exit 1
fi

# Full export
echo "=== Exporting all notes ==="
zk list -W "$NOTEBOOK" --format=json > "$EXPORT_DIR/export_${TIMESTAMP}.json"

# Validate output
jq . < "$EXPORT_DIR/export_${TIMESTAMP}.json" > /dev/null
if [ $? -eq 0 ]; then
  echo "✓ Export successful: $EXPORT_DIR/export_${TIMESTAMP}.json"
else
  echo "✗ Export failed: JSON is invalid"
  exit 1
fi

Real-World Impact

Without this skill: Agents waste time guessing at nonexistent commands (zk export, zk link), get confused by -W flag, and struggle with format options.

With this skill: Agents know exactly which commands exist, understand working directory behavior, master export patterns, and avoid wasted attempts at missing commands.