Introduction

Scimax VS Code includes a command-line interface (CLI) that provides access to many features without needing to open VS Code. This is useful for:

  • Batch operations (exporting multiple files)

  • Integration with other tools and scripts

  • Quick lookups from the terminal

  • CI/CD pipelines for documentation

The CLI reads from the same SQLite database that the VS Code extension builds, so you get consistent results between the editor and command line.

Installation

From the Extension

If you have the extension installed, the CLI is included. After building the extension:

# From the extension directory
npm run compile

# Run directly
node out/cli/index.js --help

# Or use npx (if in the extension directory)
npx scimax --help

Global Installation

To use scimax from anywhere:

# From the extension directory
npm link

# Now available globally
scimax --help

To unlink later:

npm unlink scimax-vscode

✅ Configuration

The CLI automatically uses the same database as the VS Code extension. It looks in VS Code's global storage location:

PlatformDatabase Path
macOS~/Library/Application Support/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite
Linux~/.config/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite
Windows%APPDATA%/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite

The database is created and maintained by VS Code when you open a folder with org files. The CLI reads from and writes to this same database.

Override Database Path

You can override the database path with the --db flag:

scimax db stats --db /path/to/custom.db
scimax search "query" --db /path/to/custom.db

Custom Configuration (Advanced)

For advanced setups, you can create .scimax/config.json in your project directory to specify a custom database path:

{
  "dbPath": "/custom/path/to/scimax.db"
}

The CLI checks for this file only if the VS Code global storage database is not found.

Commands

Help

scimax --help        # or: scimax help

--help (or -h) always prints the global help, even after a command name, so scimax db --help shows the same text as scimax --help. Some commands print their own usage when given help or no subcommand:

scimax db help
scimax cite
scimax task help
scimax skill

Agenda

View scheduled items, deadlines, and TODO items.

# Today's agenda
scimax agenda today

# Week view
scimax agenda week

# All TODO items
scimax agenda todos

# Filter by state
scimax agenda todos --state NEXT

# Overdue items
scimax agenda overdue

# Cap the number of TODO items (default 500)
scimax agenda todos --limit 50

# JSON output (any view)
scimax agenda week --json

Output Example

=== Today's Agenda ===

  TODO     Today    Review paper draft
           docs/paper.org:42
  NEXT     Today    Submit grant proposal
           projects/grant.org:15

Custom Agenda Commands

The CLI runs the custom agenda commands defined in scimax.agenda.customCommands in your VS Code settings.json (see Custom Agenda Commands).

# List your custom commands and their keys
scimax agenda custom

# Print the view for key "d"
scimax agenda custom d

# Structured output
scimax agenda custom d --json

# Write every command's "export" files (.txt, .org, .html, .ics, .json)
scimax agenda store

scimax agenda store from cron keeps HTML or iCalendar copies of your views current, like org-store-agenda-views in Emacs.

Export

Export org files to HTML, LaTeX, or PDF.

# Export to HTML
scimax export paper.org --format html

# Export to LaTeX
scimax export paper.org --format latex

# Export to PDF (requires pdflatex/latexmk)
scimax export paper.org --format pdf

# Export to PDF, printing the LaTeX log tail if compilation fails
scimax export paper.org --format pdf --show-log

# Export to Beamer slides (.tex)
scimax export slides.org --format beamer

# Compile Beamer slides to PDF
scimax export slides.org --format beamer-pdf

# Specify output file
scimax export paper.org --format html --output build/paper.html

# With bibliography
scimax export paper.org --format html --bib references.bib

# With specific CSL style
scimax export paper.org --format html --bib refs.bib --csl ieee

# Use a custom exporter
scimax export memo.org --exporter cmu-memo

# List installed custom exporters (and any manifest problems)
scimax export --list-exporters

# JSON result (success, input file, output path, or error)
scimax export paper.org --format pdf --json

The export command automatically looks for bibliography files in the same directory (refs.bib, references.bib, or <filename>.bib).

When a PDF compile fails, the CLI prints the first LaTeX error and its .tex line, points to the full .log, and deletes the incomplete PDF so a broken build is not mistaken for a good one. Use --show-log (or --verbose / -v) to also print the tail of the log. See Export for details.

For --format latex and --format pdf, a document that names a custom exporter with #+EXPORTER:, or whose #+LATEX_CLASS is mapped in scimax.export.latexClassExporters, is routed to that exporter, as in the editor.

✅ Tangle

Extract source blocks to their :tangle target files (org-babel tangling). Each block with a :tangle <filename> header argument is written to that file, with multiple blocks targeting the same file concatenated in document order. Blocks with :tangle no (or no :tangle header) are skipped. Noweb references (<<name>>) are expanded by default for blocks marked :noweb yes or :noweb tangle.

# Tangle all blocks in a file to their :tangle targets
scimax tangle setup.org

# Only tangle specific named blocks (matches #+NAME: of the block)
scimax tangle setup.org --only init,config

# Disable noweb reference expansion
scimax tangle setup.org --no-noweb

# Structured JSON output (files written, block/line counts, errors)
scimax tangle setup.org --json

Relative :tangle paths are resolved against the directory of the source file, and parent directories are created as needed. Note that --only filters named blocks; unnamed blocks with a :tangle target are always tangled.

Table Align

Align the org-mode and Markdown tables in files, in place. It is the same alignment as pressing TAB in a table in VS Code (scimax.table.align), so a file aligned from the terminal matches one aligned in the editor. Files ending in .md, .markdown or .qmd get Markdown (GFM) tables; everything else is treated as org.

# Align every table in a file
scimax table align notes.org

# Several files at once
scimax table align docs/*.org

# Only the table containing line 42 (leaves the other tables alone)
scimax table align README.md --line 42

# Check without writing: exits 1 if any table is not aligned (for CI)
scimax table align docs/*.org --check

# Print the result instead of writing the file
scimax table align notes.org --stdout

# Structured JSON output (tables found and changed per file)
scimax table align notes.org --json

Links are measured as the editor shows them with scimax.org.descriptiveLinks on: [[url][desc]] counts as desc. Pass --raw-links to measure links as written, which is how Emacs org-table-align lines them up. Tables inside blocks (#+begin_src ... #+end_src, Markdown code fences) are not touched.

Marp Slides

Build a Marp deck into one self-contained HTML file with the presenter tools (pen, laser, spotlight, sticky notes, talk timer, saving with ink, live Python cells). It is the same build as exporting HTML (h) from the Marp menu in VS Code, using the scripts that ship with the extension, so nothing else needs to be installed except Marp CLI (marp on the PATH, or npx, which downloads it the first time).

# deck.md -> deck.html with presenter tools
scimax marp build talk.md

# Build and open it in the browser
scimax marp build talk.md --open

# Choose the output file
scimax marp build talk.md -o build/talk.html

# Also write a PDF (plain Marp output)
scimax marp build talk.md --pdf

# Plain Marp HTML, without the presenter tools
scimax marp build talk.md --plain

# Anything after -- goes to Marp CLI, for example a custom theme
scimax marp build talk.md -- --theme-set theme/custom.css

# JSON result (output, inlined counts, missing files, web references, offline issues)
scimax marp build talk.md --json

From the CLI every deck gets the presenter tools unless its front matter says presenter: false. presenter: offline embeds Python and the packages the cells import, so they run without a network, and timer: 20 adds a 20-minute talk timer. Marp runs from the deck's folder, so relative paths and a .marprc apply. Local images, iframes, scripts, stylesheets and KaTeX fonts are inlined; the build lists files it could not find and anything still loaded from the web.

KaTeX fonts and offline Python files are downloaded once and cached in the extension's global storage, which the extension's own exports share.

See Presenter Tools and Live Python for the keys while presenting.

Citations

Citation-related operations. extract, check, and list accept --json (or --format json) for structured output.

Extract Citations

List all citation keys used in a document:

scimax cite extract paper.org

# JSON output
scimax cite extract paper.org --format json

Output:

Found 12 citation(s) with 8 unique key(s):

  doe-2020
  jones-2021
  smith-2019
  ...

Check Citations

Validate citations against a bibliography file:

scimax cite check paper.org --bib references.bib

Output:

Citation Check: paper.org

  Citations found: 12
  Bibliography entries: 15

MISSING (2 cited but not in .bib):
  - nonexistent-2020
  - typo-key

UNUSED (5 in .bib but not cited):
  - old-reference-2010
  - unused-entry
  ...

This is useful in CI pipelines to catch citation errors before publishing.

Convert Citation Syntax

Convert between org-ref v2, v3, and org-cite syntax:

# Convert v2 to v3
scimax cite convert paper.org --from v2 --to v3

# Convert to org-cite
scimax cite convert paper.org --from v3 --to org-cite

# Modify file in place
scimax cite convert paper.org --from v2 --to v3 --inplace

# Output to new file
scimax cite convert paper.org --from v2 --to v3 --output paper-v3.org

List Bibliography

List entries in a BibTeX file:

scimax cite list references.bib

# JSON output
scimax cite list references.bib --format json

Journal

Open or create journal entries from the terminal.

# Open today's journal (creates if needed)
scimax journal

# Open a specific date
scimax journal tomorrow
scimax journal yesterday
scimax journal friday
scimax journal --date "next monday"
scimax journal --date 2026-03-15
scimax journal --date +2d
scimax journal --date -1w

# JSON output (for scripting)
scimax journal --json

# Look up a past entry without opening VS Code or creating it
scimax journal --date -1d --no-create --no-open --json
scimax journal --date=-1d --no-open
FlagEffect
--dateDate expression; negative offsets work (--date -1d, --date-1d=)
--no-openPrint the entry path without opening VS Code
--no-createNever create a missing entry; reports exists: false
--jsonJSON output with date, weekday, path, exists

The journal directory is configured via scimax.journal.directory in VS Code settings. New entries use the default template (customizable via scimax.journal.customTemplate setting).

Supported date expressions: today, tomorrow, yesterday, day names (monday, fri), next/this day (next friday, this monday), relative (+2d, -1w, +3m), month+day (jan 15), ISO dates (2026-03-15).

Project

Fuzzy-select and open a known project in VS Code.

# Interactive fuzzy selection (uses fzf if available)
scimax project

# Pre-filter with a query
scimax project scimax

# List all known projects
scimax project --list

# Add a new project (creates directory if needed, opens in VS Code)
scimax project --add ~/projects/new-project

# JSON output
scimax project --json

# Remove projects whose directories no longer exist
scimax project --cleanup

# Remove one project by path
scimax project --remove /old/path

# Find and register git/projectile projects under a directory (default: cwd)
scimax project --scan ~/projects

Projects are pulled fresh from the scimax database each time. The extension registers projects automatically when you open folders in VS Code.

When fzf is installed, the interactive selection uses fuzzy matching. Otherwise, a numbered list is displayed.

Tasks

Project management over org task graphs. Answers "what should I work on next", who is overloaded, what is blocked, and what the long pole is.

Note that scimax task and scimax project are unrelated despite the similar-sounding names: scimax project opens VS Code workspaces, while scimax task reads task metadata inside org files.

# What to work on now, ranked and explained
scimax task next

# Open tasks, filtered
scimax task list --ready
scimax task list --blocked
scimax task list --assignee priya

# Workload by assignee
scimax task who

# One task: what blocks it, what it unblocks
scimax task show synth

# Critical path through the remaining work
scimax task path

# Mark done (refuses if blocked) and set an assignee
scimax task done synth
scimax task assign xrd priya

# Which files contain tasks
scimax task files

Task Model

A task is a heading carrying an :ID: property. The relevant properties are:

PropertyMeaningExample
:ID:Task identifier (required)synth
:ASSIGNEE:Who owns itliam
:EFFORT:Estimated work, Nd or Nh5d
:DEPENDS:Explicit blockers, space-separatedid:design id:xrd
:ORDERED:On a parent: children run in ordert

Both blocking sources are honored, so --ready and --blocked match what the editor enforces. scimax task done refuses a blocked task unless --force is passed, and reports which tasks the completion unblocked.

File Selection

File selection is global by default. The database spans every indexed file, so scimax task next gives the same answer from any directory: it picks the file with the most task metadata anywhere.

FlagEffect
(none)The file with the most tasks, anywhere
--localOnly files under the current directory
--file <path>That file

Run scimax task files to see the candidates with their task counts.

Options

OptionDescription
--file <path>Project file to operate on
--localConfine discovery to the current directory
--jsonStructured output
--forceAllow done on a blocked task

Limitations

  • done does not write a CLOSED: timestamp, and does not regenerate project-table dynamic blocks; refresh those in the editor.

  • :ORDERED: sequences direct children only, not deeper descendants.

  • Task ids resolve within one file, so cross-file :DEPENDS: is not followed.

  • Effort totals count only Nd and Nh; anything else is reported as unestimated.

Database

Database maintenance operations.

Statistics

Show database statistics:

scimax db stats

Output:

=== Database Statistics ===

  Database: /home/user/.config/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite
  Root: /home/user/project

  Files indexed: 42
  Headings: 1234
  Source blocks: 317
  Has embeddings: No
  Org files: 40
  Markdown files: 2

Add --json for structured output.

Optimize

Remove entries for missing files and VACUUM:

scimax db optimize

Close VS Code first: VACUUM needs the database to itself. It rewrites the file, so it needs free disk space about the size of the database. The output reports the size before and after:

Database optimized: 47.0 GB -> 1.9 GB

The same as Scimax: Optimize Database in VS Code. See Database Search.

Check Integrity

Check for missing or stale files:

scimax db check

Output:

Checking database integrity...

MISSING: old-file.org
MISSING: deleted-folder/notes.org

Total files in database: 42
Missing files: 2

Open VS Code to rebuild the index.

When nothing is missing, the last line is Database looks good. Running scimax db sync also removes the missing entries.

Sync

Bring the database into agreement with the configured scan roots and the filesystem in one pass: pick up new files, refresh changed files (mtime-based), refresh in-scope files that are stale, and prune entries for files that no longer exist.

Scan roots are unioned from:

  1. scimax.db.include (VS Code settings)

  2. scimax.journal.directory

  3. scimax.agenda.include

  4. NotebookManager projects (every project you have opened in VS Code, persisted in notebooks.json)

Files in the database that do not fall under any current root are still refreshed if they exist and their mtime has advanced; otherwise they are left alone.

# Default daily driver
scimax db sync

# Preview what sync would do without changing the DB
scimax db sync --dry-run

# Show a line per file (in addition to the summary)
scimax db sync --verbose

# Index without generating embeddings
scimax db sync --no-embeddings

Output:

Database: ~/Library/Application Support/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite

Scan roots (3):
  ~/Dropbox/org
  ~/Dropbox/journal
  ~/Dropbox/projects/scimax_vscode

sync complete in 1.4s
  +12 new
  ~5 updated
  -2 removed
  1834 unchanged

The summary uses these markers:

MarkerMeaning
+New file added to the database
~Existing file re-indexed (mtime newer)
*Out-of-scope file refreshed because mtime advanced
-File removed from the database (no longer on disk)
=Unchanged (--verbose only)
.Out-of-scope file, unchanged (--verbose only)

✅ Embeddings During Sync

Sync uses scimax.db.embeddingProvider, scimax.db.ollamaUrl, and scimax.db.ollamaModel from your VS Code settings.json. When the provider is ollama, sync:

  1. Tests the connection by embedding a short string and checking the vector has the size expected for the model. If the test fails, sync prints FAILED (embeddings will be skipped) and indexes without embeddings.

  2. Queues embeddings for every file it indexes.

  3. After the summary, also queues every indexed file that has no embeddings yet (for example, files indexed before a provider was configured), so you do not need clear to add embeddings to an existing database.

  4. Waits for the queue to finish before exiting, then reports Embeddings complete or Embeddings failed for N file(s). Last error: ....

Testing embedding service connection... OK
  Provider: ollama, Model: nomic-embed-text

sync complete in 3.2s
  +12 new
  ~5 updated
  -0 removed
  1834 unchanged
Generating embeddings (14 file(s) remaining)...
  Embeddings complete

--no-embeddings skips all of this. The provider defaults to none, as in VS Code, and --embeddings does not enable embeddings when the provider is none; set scimax.db.embeddingProvider to ollama instead. Embeddings are not generated in --dry-run mode. Embedding a large collection for the first time can take a long time; scimax db scan accepts the same embedding flags.

✅ Clear

Wipe the database. Use this before a full re-sync, after a schema change, or when troubleshooting suspected corruption. Requires confirmation.

# Interactive confirmation
scimax db clear

# Skip the prompt
scimax db clear --yes

# Typical reset workflow
scimax db clear --yes && scimax db sync

Output:

Database: ~/Library/Application Support/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite
This will delete 1853 file(s), 12044 heading(s), 3201 source block(s).
Continue? [y/N] y
Database cleared.
Run "scimax db sync" to repopulate.

✅ Remove and Ignore Files

Remove files from the database by path or glob. Relative paths are resolved against the current directory.

# Remove one file
scimax db remove notes/scratch.org

# Remove everything matching a glob
scimax db remove "~/Dropbox/archive/**"

# Remove from the database AND add to scimax.db.exclude in settings.json
scimax db ignore "~/Dropbox/archive/**"

remove only deletes database entries, so a later sync adds the files back if they are under a scan root. ignore also appends the pattern (or the absolute path) to scimax.db.exclude in your VS Code settings.json, so sync skips it from then on. Both accept --json.

Prune Excluded Files

Remove database entries that the current exclude rules would reject.

scimax db sync deliberately keeps an entry whose file still exists on disk, even when that file is outside the configured scan roots — otherwise files added by other means would vanish on every sync. The consequence is that tightening scimax.db.exclude, or upgrading to a version that adds a new built-in exclusion, leaves the old rows in place. prune is what clears them.

# See what would go, grouped by the pattern that caught it
scimax db prune --dry-run

# Remove them
scimax db prune

# Machine-readable
scimax db prune --json

Output:

Database: ~/Library/Application Support/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite
Exclude patterns: 22
Indexed files: 58713
Matching exclude rules: 26570
Mode: dry-run (no changes will be written)

    23872  **/node_modules/**
     2574  **/Code/User/History/**
      120  **/build/**
        4  **/Code/User/globalStorage/**

Would remove 26570 file(s). Re-run without --dry-run to apply.

Always run --dry-run first and read the per-pattern breakdown. A pattern that catches far more than you expected is usually a pattern that is too broad.

✅ Scan Directory

Scan a specific directory and add its files to the database. This is a simplified command that takes the directory as a direct argument, making it ideal for cron jobs and scripts.

# Scan a specific directory
scimax db scan /path/to/org-files

# Scan multiple directories (run sequentially)
scimax db scan ~/work/org-files
scimax db scan ~/personal/notes

Output:

Scanning directory: /path/to/org-files
Database path: /home/user/.config/Code/User/globalStorage/jkitchin.scimax-vscode/scimax-db.sqlite

Found 15 org file(s) to index.

  Indexing: meeting-notes.org... OK
  Indexing: project/tasks.org... OK
  Indexing: archive/2024.org... OK
  ...

Indexed: 15 file(s)

Scheduling Automatic Syncs

Prefer db sync over db scan for scheduled runs: it covers every configured scan root at once, refreshes changed files, and prunes entries whose files are gone. db scan only adds one directory.

macOS (launchd)

On a laptop, use launchd rather than cron. If the machine is asleep at the scheduled time, launchd runs the job at the next wake; cron simply misses it.

A wrapper script keeps the log timestamped, bounded, and free of overlapping runs. Save it as ~/.local/bin/scimax-db-sync.sh and chmod +x it:

#!/bin/bash
set -uo pipefail

# launchd starts jobs with a bare environment, so spell out the PATH.
export PATH="/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin"

LOG_DIR="$HOME/Library/Logs/scimax"
LOG="$LOG_DIR/db-sync.log"
LOCK="$LOG_DIR/db-sync.lock"
MAX_LOG_BYTES=$((5 * 1024 * 1024))

mkdir -p "$LOG_DIR"

if [ -f "$LOG" ] && [ "$(stat -f%z "$LOG")" -gt "$MAX_LOG_BYTES" ]; then
    mv -f "$LOG" "$LOG.1"
fi

# mkdir is atomic: a run that overlaps the previous one backs off rather than
# competing for the database write lock.
if ! mkdir "$LOCK" 2>/dev/null; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] skipped: a sync is already running" >> "$LOG"
    exit 0
fi
trap 'rmdir "$LOCK" 2>/dev/null' EXIT

{
    echo "=== $(date '+%Y-%m-%d %H:%M:%S %Z') — scimax db sync ==="
    START=$(date +%s)
    scimax db sync
    STATUS=$?
    echo "--- exit $STATUS after $(( $(date +%s) - START ))s"
    echo
} >> "$LOG" 2>&1

Then ~/Library/LaunchAgents/com.USER.scimax-db-sync.plist, here scheduled for 06:00 and 17:00:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.USER.scimax-db-sync</string>

  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>/Users/USER/.local/bin/scimax-db-sync.sh</string>
  </array>

  <key>StartCalendarInterval</key>
  <array>
    <dict><key>Hour</key><integer>6</integer><key>Minute</key><integer>0</integer></dict>
    <dict><key>Hour</key><integer>17</integer><key>Minute</key><integer>0</integer></dict>
  </array>

  <key>StandardOutPath</key>
  <string>/Users/USER/Library/Logs/scimax/launchd.out</string>
  <key>StandardErrorPath</key>
  <string>/Users/USER/Library/Logs/scimax/launchd.err</string>

  <key>RunAtLoad</key>
  <false/>

  <key>ProcessType</key>
  <string>Background</string>
</dict>
</plist>

Load it, then prove it works instead of waiting until tomorrow:

plutil -lint ~/Library/LaunchAgents/com.USER.scimax-db-sync.plist
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.USER.scimax-db-sync.plist

launchctl kickstart -p gui/$UID/com.USER.scimax-db-sync   # run it now
launchctl print gui/$UID/com.USER.scimax-db-sync | grep -E 'state|runs|last exit'
tail -f ~/Library/Logs/scimax/db-sync.log

To change the schedule, edit the plist, then launchctl bootout and bootstrap again — launchd caches the loaded copy.

launchctl bootout gui/$UID/com.USER.scimax-db-sync
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.USER.scimax-db-sync.plist
Linux (cron)
crontab -e

# 6am and 5pm daily
0 6,17 * * * /usr/local/bin/scimax db sync >> ~/.local/state/scimax/db-sync.log 2>&1

Use an absolute path to the binary: cron's PATH is minimal and will not find a scimax installed via npm link.

Command Comparison

CommandUse Case
scimax db syncDaily driver: discover, refresh, and prune in one pass
scimax db clearWipe the database (followed by sync for a full rebuild)
scimax db scan <dir>Ad-hoc scan of a single directory
scimax db checkRead-only integrity report (no changes)
scimax db pruneDrop entries the exclude rules now reject
scimax db removeDrop specific files or globs from the database
scimax db ignoreDrop files and add them to scimax.db.exclude
scimax db optimizeShrink the database file (VS Code closed)
  • Use sync for routine maintenance, including the morning's first pass.

  • Use scan for one-off directories outside the configured scan roots.

  • Use clear + sync only when you genuinely need to start over.

  • Use prune after changing scimax.db.exclude, or after an upgrade that adds a built-in exclusion.

The rebuild and reindex subcommands have been removed. Use sync (or clear + sync) instead.

✅ Publish

Publish org projects to HTML, using the same configuration as the editor's publishing commands (_config.yml or .org-publish.json in the current directory). See Publishing for the configuration format.

# Publish all projects
scimax publish

# Publish one project
scimax publish docs

# Republish every file, even if up to date
scimax publish docs --force

# Show what would be published without writing files
scimax publish docs --dry-run

# List configured projects
scimax publish --list

# Structured output (works with --list and publishing)
scimax publish --json

Put the project name before any flags. Flags take the following word as their value, so scimax publish --force docs treats docs as the value of --force and publishes all projects.

If a theme other than default is configured (for example theme: book in _config.yml), projects are published with that theme.

Initializing a Configuration

--init writes a starter configuration to the current directory. It refuses to overwrite an existing _config.yml or .org-publish.json unless --force is given.

# .org-publish.json with defaults
scimax publish --init

# _config.yml instead
scimax publish --init --yaml

# Custom names and directories
scimax publish --init --name docs --base ./docs --output ./_build/html
OptionDefaultDescription
--name <name>mainProject name
--base <dir>./Source directory
--output <dir>./_build/htmlOutput directory
--yamloffWrite _config.yml instead of JSON
--no-githubGitHub onDisable GitHub Pages support (.nojekyll)
--no-sitemapsitemap onDisable automatic sitemap generation
--forceoffOverwrite an existing configuration

If the source directory has no _toc.yml, --init prints an example one.

Skill

Scimax ships four agent skills that let an AI coding agent use the CLI and answer questions about your notes, agenda, projects, org syntax and slides:

SkillWhat it covers
scimaxSearch, agenda, TODOs, journal, export, citations, database
scimax-orgOrg-mode syntax, links, source blocks, tables, citations
scimax-projectsscimax task, :DEPENDS:/:ORDERED:, Gantt charts, assignees
scimax-presentationsBeamer and Marp decks built with scimax marp build

They live in skills/<name>/SKILL.md in the repository and follow the Agent Skills specification, so they work with Claude Code, VS Code (GitHub Copilot), Codex, Cursor, OpenCode and Gemini CLI.

Installing

Any of these gives the same result:

scimax skill install                          # bundled with the extension, no Python needed
uvx knowhow add jkitchin/scimax_vscode -g -y  # from GitHub with knowhow
npx skills add jkitchin/scimax_vscode -g -y   # from GitHub with npx skills

In VS Code, run Scimax: Install AI Agent Skills (cmd:scimax.skills.install) and choose all projects or this workspace.

Each skill is copied to ~/.agents/skills/<name>, which VS Code, Codex, Cursor, OpenCode and Gemini CLI read, and ~/.claude/skills/<name> is a symlink to it for Claude Code. The install is recorded in ~/.agents/.skill-lock.json, so knowhow check, knowhow upgrade and npx skills update can keep it current.

Commands

scimax skill install [name...]    # Install skills (default: all four)
scimax skill update [name...]     # Reinstall the bundled version
scimax skill uninstall [name...]  # Remove skills installed from scimax
scimax skill list                 # Bundled skills and whether they are installed
scimax skill show [name]          # Print a bundled SKILL.md (default: scimax)
scimax skill path                 # Print the installation directory
OptionDescription
--projectInstall into the current directory (.agents/skills, .claude/skills, skills-lock.json)
--forceReplace skill folders that were not installed from scimax

install and update stop rather than replace a skill folder of the same name that was installed by something else, unless you pass --force. uninstall only removes skills whose lock entry says they came from jkitchin/scimax_vscode.

Learnings

When you correct the agent, it appends the correction to ~/.config/scimax/learnings.md ($XDG_CONFIG_HOME/scimax/learnings.md if set), and all four skills read that file before answering. It lives outside the skill folders, so updates and uninstalls never touch it.

Before 0.14 the skill was a single folder at ~/.claude/skills/scimax with its own learnings.md. The first scimax skill install or update moves those entries to the new file and replaces the old folder.

Scripting Examples

Export All Org Files to HTML

#!/bin/bash
for f in docs/*.org; do
    scimax export "$f" --format html --output "build/$(basename "$f" .org).html"
done

Check Citations in CI

# .github/workflows/check-citations.yml
name: Check Citations
on: [push, pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm run compile
      - run: node out/cli/index.js cite check paper.org --bib refs.bib

Daily Agenda Email

#!/bin/bash
# Send daily agenda via email
scimax agenda today | mail -s "Today's Agenda" user@example.com

Find Files with Specific Tags

# Using search (if tag is in heading)
scimax search ":research:" --limit 50

Limitations

The CLI has some limitations compared to the VS Code extension:

  1. Semantic Search: Requires embeddings, which need an Ollama embedding provider configured in your VS Code settings (see Embeddings During Sync).

  2. Live Updates: The CLI reads a snapshot of the database. Changes made to org files won't be reflected until you run scimax db sync or VS Code re-indexes them.

  3. Interactive Features: No support for interactive features like completion or live preview.