Skip to content
🚧 Early alpha — building the foundation. See the roadmap →

Development setup

Created Updated
  • Bun — primary package manager and runtime
  • Node.js 18+ (used by some sub-tools like Playwright)
  • Obsidian — for plugin testing
  • Git

Optional for sharing your local dev server with others:

git clone https://github.com/cybersader/crosswalker.git
cd crosswalker
bun install

That installs the plugin’s dependencies. The docs site has its own separate node_modules in docs/ that gets installed automatically on first use of the orchestrator.

The local dev orchestrator — bun run serve

Section titled “The local dev orchestrator — bun run serve”

From the repo root, bun run serve is an interactive menu wrapping every local workflow. It’s the recommended entry point for development — it handles cross-OS node_modules contamination automatically (e.g. rollup native binary mismatches when bouncing between WSL and Windows), auto-installs docs/node_modules on first run, and cleans up all spawned children on Ctrl+C.

bun run serve
━━━ Crosswalker local serve ━━━

  1) Docs dev server          http://localhost:4321   HMR, for KB editing
  2) Docs preview (built)     http://localhost:4321   built site
  3) Docs build only          → docs/dist
  4) Plugin dev (watch)       → test-vault
  5) Docs + plugin dev        both in parallel
  6) Share docs (Tailscale)   tailnet only
  7) Share docs (Cloudflare)  public URL
  8) Docs e2e tests           playwright test:local

  Choose [1-8]:
bun run serve:docs       # Option 1 — docs dev server
bun run serve:plugin     # Option 4 — plugin watch
bun run serve:both       # Option 5 — docs + plugin in parallel
bun run serve:share      # Option 6 — docs + Tailscale

Two .bat files at the repo root, for when you’d rather double-click than open a terminal:

FileRunsUse
serve.batbun run serveInteractive menu (docs / plugin / both / tunnel / tests)
serve-docs.batbun run serve:docsDocs dev server only → http://localhost:4321/crosswalker/

Both cd to the repo root first, so they work from anywhere, and pause on exit so the window stays open if something errors.

# Watch mode — rebuilds plugin on file changes, outputs to test-vault
bun run serve:plugin
# or the raw command:
bun run dev

Then:

  1. Open test-vault/ in Obsidian (File → Open vault → select test-vault)
  2. Enable Crosswalker in Settings → Community plugins
  3. Trigger the plugin via command palette: Crosswalker: Import structured data
  4. Edits to src/ auto-rebuild. Reload the plugin in Obsidian (toggle in settings or Ctrl+R in the dev console) to pick up changes
  5. Install the Hot Reload community plugin in test-vault/ for automatic plugin reloads on rebuild
bun run serve:docs

Opens the Astro dev server at http://localhost:4321/crosswalker/. HMR is active — edits to .mdx files hot-reload in the browser (with the exception of inline <style> blocks in MDX files, which sometimes require a full page refresh).

Do not open docs/ as an Obsidian vault — content files are .mdx, not .md. Use VS Code with the MDX extension for rich editing.

Common when working on a feature that touches both plugin code and docs:

bun run serve:both

Starts the docs dev server and plugin watch build in the same terminal. Single Ctrl+C kills both cleanly.

These all work standalone if you prefer not to use the orchestrator:

CommandDescription
Plugin
bun run devPlugin watch mode, outputs to test-vault
bun run buildPlugin production build (type-check + bundle)
bun run testPlugin Jest unit tests
bun run test:watchPlugin unit tests in watch mode
bun run lintESLint with obsidian-plugin rules (required for community plugin submission)
bun run lint:fixAuto-fix lint issues
bun run e2ePlugin E2E tests (WebdriverIO, requires Obsidian)
Orchestrator (interactive menu wraps the workflows below)
bun run serveInteractive 8-mode menu — docs dev, plugin watch, parallel both, tunnel sharing, tests, MDX check
bun run serve:docsShortcut: docs Astro dev server (mode 1)
bun run serve:pluginShortcut: plugin watch build (mode 4)
bun run serve:bothShortcut: docs dev + plugin watch in parallel (mode 5)
bun run serve:shareShortcut: docs dev + Tailscale tunnel (mode 6)
Fixtures + spec
bun run fixturesRegenerate Tier 1 test fixtures into test-vault/Frameworks/NIST-mini/ from tools/fixtures/synthetic/nist-mini.csv
Docs
cd docs && bun run devDocs Astro dev server
cd docs && bun run buildDocs production build → docs/dist
cd docs && bun run previewServe the built dist locally
cd docs && bun run test:localDocs Playwright E2E tests
bun run check:mdxLightweight MDX syntax pre-check (catches bare braces, unclosed tags, frontmatter YAML errors) — fast (~1–2s)
Release
bun run versionBumps version in manifest.json + versions.json; stages git changes for commit

See the testing page for details on each test surface.

crosswalker/
├── src/                      # Plugin source (TypeScript)
│   ├── main.ts               # Plugin entry point
│   ├── settings/             # Settings management
│   ├── import/               # Import wizard + parsers
│   ├── generation/           # Generation engine
│   ├── config/               # Config manager + browser
│   ├── types/                # TypeScript interfaces
│   └── utils/                # Debug logging, etc.
├── tests/                    # Plugin Jest unit tests
├── test-vault/               # Embedded Obsidian vault
│   └── .obsidian/plugins/crosswalker/    # Build output lives here
├── spec/                     # Machine-readable contracts (load-bearing)
│   ├── tier1.schema.json     # Canonical Tier 1 vault shape — what producers emit
│   ├── recipe.schema.json    # Recipe DSL — Ch 22 closed grammar
│   ├── primitives/           # (Stub) one schema per transformation primitive
│   └── README.md
├── tools/                    # Dev / test infrastructure (not shipped)
│   ├── generate-fixtures.ts  # CSV → Tier 1 markdown fixture generator
│   ├── fixtures/synthetic/   # Hand-authored sample CSVs (committed)
│   └── README.md
├── docs/                     # Astro Starlight docs site
│   ├── src/
│   │   ├── content/docs/     # .mdx content files
│   │   ├── components/       # Starlight component overrides (PageTitle, MobileMenuFooter)
│   │   └── styles/           # brand.css, global.css
│   ├── tests/                # Playwright E2E specs
│   ├── astro.config.mjs      # Starlight config
│   ├── playwright.config.ts  # Playwright config
│   ├── package.json          # Docs dependencies
│   └── tags.yml              # Controlled tag vocabulary
├── scripts/
│   └── serve.mjs             # The bun run serve orchestrator
├── frameworks_to_obsidian.py # Python CLI (external producer example)
├── .claude/                  # AI agent historical context (CLAUDE.md, numbered knowledge base)
├── .github/workflows/        # CI/CD — docs deploy, plugin release
├── CLAUDE.md                 # Root-level agent instructions
├── CONTRIBUTING.md           # Contributing quick-start (also see docs/development/contributing/)
├── README.md                 # Repo landing page
└── ROADMAP.md                # Plain-markdown mirror of the docs roadmap

After cloning and bun install, verify the setup works:

# Plugin builds cleanly
bun run build

# Plugin tests pass
bun run test

# Plugin lints cleanly
bun run lint

# Docs dev server starts
bun run serve:docs
# Open http://localhost:4321/crosswalker/ and check the homepage loads

If the plugin build or docs dev server fails with a rollup native-binary error (e.g. Cannot find module @rollup/rollup-<platform>), just re-run bun run serve — the orchestrator auto-detects the contamination and reinstalls docs/node_modules with the correct platform binaries.