diff --git a/resources/handoff-prompt-ai-agent.md b/resources/handoff-prompt-ai-agent.md
new file mode 100644
index 0000000..d1b6e1a
--- /dev/null
+++ b/resources/handoff-prompt-ai-agent.md
@@ -0,0 +1,178 @@
+# Agent Handoff: Obsidian CRBasic Syntax Highlighting Plugin
+
+## Objective
+
+Create an Obsidian plugin ("CodeBlock CRBasic") that provides syntax highlighting for CRBasic code in markdown fenced code blocks (` ```crbasic `). CRBasic is the programming language for Campbell Scientific dataloggers.
+
+## Reference Material
+
+The token lists (keywords, built-in functions, operators, constants, preprocessor directives) were ported from the **VSCode CRBasic extension** by Campbell Scientific:
+
+- Marketplace: https://marketplace.visualstudio.com/items?itemName=daiwalkr.cr-basic-ms-vscode
+- The extension's VSIX can be downloaded and extracted to get `syntaxes/cr-basic.tmLanguage.json` — a TextMate grammar file containing all token patterns.
+- The extension's repo is private GitLab: `https://gitlab.com/cs-global/research-and-development/product-testing-and-compliance/ptg-software/vscode-crbasic-plugin`
+
+## Architecture
+
+The plugin needs **two separate highlighting engines** because Obsidian uses different renderers for its two view modes:
+
+| View Mode | Engine | Approach |
+|---|---|---|
+| **Edit / Live Preview** | CodeMirror 6 (via HyperMD) | CM6 `ViewPlugin` with `Decoration.mark()` |
+| **Reading View** | PrismJS | `registerMarkdownCodeBlockProcessor()` |
+
+### File Structure
+
+```
+markdown-codeblock-crbasic/
+├── manifest.json # Obsidian plugin manifest (id: "codeblock-crbasic")
+├── package.json # npm config + build scripts
+├── tsconfig.json # TypeScript config
+├── esbuild.config.mjs # Bundles src/ → main.js (CJS, externals for obsidian/CM6)
+├── styles.css # Empty (uses Obsidian's built-in theme tokens)
+├── src/
+│ ├── main.ts # Plugin entry — registers CM6 extension + code block processor
+│ ├── crbasic-tokens.ts # Shared keyword/function/operator/constant lists
+│ ├── tokenizer.ts # Line-level tokenizer shared by both engines
+│ └── cm6-crbasic.ts # CM6 ViewPlugin implementation
+```
+
+### Shared Tokenizer (`tokenizer.ts`)
+
+A single line-level tokenizer is shared by both the CM6 ViewPlugin and the Reading View processor. It takes a line of text + an offset, and returns an array of `{from, to, type}` tokens. Token types: `keyword`, `builtin`, `operator`, `atom`, `number`, `string`, `comment`, `meta`.
+
+CRBasic is **case-insensitive** — all keyword matching uses lowercased lookup sets.
+
+### Token Lists (`crbasic-tokens.ts`)
+
+All token lists are extracted from the TextMate grammar into a single module. Both engines import from here. Categories:
+
+- **Keywords** (`keyword.control`): `BeginProg`, `EndProg`, `If`, `Else`, `Scan`, `Sub`, `Public`, `Dim`, `Const`, etc.
+- **Preprocessor** (`keyword.control.preprocessor`): `#If`, `#Else`, `#EndIf`, etc. (matched WITH the `#` prefix)
+- **Logical operators** (`keyword.operator.logical`): `AND`, `OR`, `NOT`, `MOD`, `XOR`, `IMP`, `INTDV`
+- **Constants** (`constant.character` + `constant.language`): `True`, `False`, `As`, `LoggerType`, etc.
+- **Built-in functions** (`entity.name.function.*`): ~300 functions across CDM, DataTable, Measurements, Math, FileIO, Internet, PakBus, SDM, Serial, String categories — deduplicated into a flat array.
+
+## Critical Lessons Learned
+
+### 1. Obsidian's CM6 uses HyperMD — NOT standard CM6 markdown nodes
+
+**The problem**: Standard CM6 markdown uses syntax tree nodes named `FencedCode`, `CodeInfo`, `CodeText`. Obsidian's HyperMD fork uses completely different names: `HyperMD-codeblock-begin`, `HyperMD-codeblock-bg`, `hmd-codeblock`, `HyperMD-codeblock-end`, etc.
+
+**The solution**: Don't use `syntaxTree()` to find code blocks. Instead, scan the document text line-by-line looking for ` ```crbasic ` opening fences and ` ``` ` closing fences. Collect the content lines between them and tokenize. This is robust regardless of Obsidian's internal CM6 node naming.
+
+```typescript
+// Correct approach — text scanning:
+for (let i = 1; i <= doc.lines; i++) {
+ const line = doc.line(i);
+ if (/^```crbasic\s*$/i.test(line.text.trim())) {
+ inCrbasicBlock = true; ...
+ }
+}
+```
+
+### 2. `StreamLanguage.define()` does NOT work for code block highlighting
+
+**The problem**: `StreamLanguage.define()` creates a full CM6 language. Registering it via `registerEditorExtension(lang.extension)` would try to make it the **top-level** editor language, replacing markdown. There is no public Obsidian API to register a new nested code-block language with CM6's markdown parser.
+
+**The solution**: Use a `ViewPlugin` that applies `Decoration.mark()` with `cm-*` CSS classes (e.g., `cm-keyword`, `cm-string`, `cm-builtin`). Obsidian themes already style these classes, so no custom CSS is needed.
+
+### 3. `window.hljs` is NOT available at plugin load time
+
+**The problem**: Obsidian does not expose `window.hljs` when plugins load. Attempting `window.hljs.registerLanguage()` in `onload()` silently fails.
+
+**The solution**: Don't use hljs at all. Use `registerMarkdownCodeBlockProcessor("crbasic", callback)` instead. This takes over the rendering of ` ```crbasic ` blocks entirely — you create your own `
` DOM structure with highlighted `` elements.
+
+### 4. Obsidian Reading View uses PrismJS, not highlight.js
+
+**The problem**: Internet sources (and initial assumptions) suggested Obsidian uses highlight.js. It actually uses **PrismJS** for Reading View rendering.
+
+**The solution**: Since we use `registerMarkdownCodeBlockProcessor` (which bypasses PrismJS entirely), we just need our `` elements to use PrismJS-compatible CSS classes so Obsidian themes style them correctly:
+
+```typescript
+// PrismJS class format: TWO separate classes, "token" + type
+// Obsidian's createEl cls parameter takes an ARRAY:
+code.createEl("span", {
+ cls: ["token", "keyword"], // ✓ correct
+ text: "BeginProg",
+});
+
+// NOT a single string (won't be split into two classes):
+code.createEl("span", {
+ cls: "token keyword", // ✗ wrong — single class
+ text: "BeginProg",
+});
+```
+
+Token type mapping for PrismJS:
+| Our type | PrismJS classes |
+|---|---|
+| `keyword` | `["token", "keyword"]` |
+| `builtin` | `["token", "function"]` |
+| `operator` | `["token", "operator"]` |
+| `atom` | `["token", "boolean"]` |
+| `number` | `["token", "number"]` |
+| `string` | `["token", "string"]` |
+| `comment` | `["token", "comment"]` |
+| `meta` | `["token", "keyword"]` |
+
+### 5. Reading View DOM structure matters
+
+The `
` and `` elements need specific classes for Obsidian themes to style the code block background and font correctly:
+
+```typescript
+const pre = el.createEl("pre", { cls: ["language-crbasic"] });
+const code = pre.createEl("code", { cls: ["language-crbasic", "is-loaded"] });
+```
+
+The `is-loaded` class on `` is important — Obsidian uses it to determine that code highlighting has been applied.
+
+### 6. CM6 token class names
+
+For Edit mode, use standard CodeMirror CSS classes via `Decoration.mark({ class: "cm-keyword" })`. Obsidian themes already provide colors for: `cm-keyword`, `cm-builtin`, `cm-string`, `cm-comment`, `cm-number`, `cm-operator`, `cm-atom`, `cm-meta`.
+
+### 7. Build configuration
+
+All `@codemirror/*`, `@lezer/*`, `obsidian`, and `electron` packages must be listed as **externals** in esbuild. Obsidian provides these at runtime. Bundling them causes conflicts.
+
+Use `--legacy-peer-deps` when running `npm install` because the `obsidian` npm package has peer dependency conflicts with `@codemirror/state` versions.
+
+### 8. Debug technique
+
+To debug CM6 syntax tree issues, add a command that dumps node names:
+
+```typescript
+this.addCommand({
+ id: "dump-syntax-tree",
+ name: "Dump CM6 syntax tree (debug)",
+ callback: () => {
+ const view = this.app.workspace.getActiveViewOfType(MarkdownView);
+ const cm = (view.editor as any).cm;
+ const tree = syntaxTree(cm.state);
+ const names = new Set();
+ tree.iterate({ enter: (node) => { names.add(node.name); } });
+ console.log("Node names:", [...names].sort());
+ },
+});
+```
+
+Open Obsidian DevTools with `Ctrl+Shift+I`, run the command from the command palette (`Ctrl+P`).
+
+## Build & Deploy
+
+```bash
+cd markdown-codeblock-crbasic
+npm install --legacy-peer-deps
+npm run build
+# Copy main.js, manifest.json, styles.css to:
+# /.obsidian/plugins/codeblock-crbasic/
+```
+
+Reload Obsidian with `Ctrl+R` (with DevTools open) or restart the app.
+
+## What's NOT In Scope
+
+- Autocomplete, snippets, diagnostics, formatting (IDE features from the VSCode extension)
+- Semantic highlighting (requires a full parser)
+- File associations (Obsidian doesn't open `.cr1x` files directly)
+- Only one language alias is registered: `crbasic`
diff --git a/resources/readme-initial-codeblock-crbasic.html b/resources/readme-initial-codeblock-crbasic.html
new file mode 100644
index 0000000..56be185
--- /dev/null
+++ b/resources/readme-initial-codeblock-crbasic.html
@@ -0,0 +1,588 @@
+
+
+
+
+
+CodeBlock CRBasic — Installation Guide
+
+
+
+
+
+
CodeBlock CRBasic
+
Syntax highlighting for CRBasic code blocks in Obsidian. A simple guide to install and use the plugin.
+
+
+
+
+
+
+
+
+ 1
+
What You Need
+
+
The plugin is made up of 3 small files. That's it — no installer, no app store, just 3 files:
+
+
+
+ 📄
+ main.js
+ The plugin code (~16 KB)
+
+
+ 📄
+ manifest.json
+ Tells Obsidian the plugin's name and version
+
These files should have been provided to you alongside this guide. If you're missing any of them, ask the person who shared the plugin with you.
+
+
+
+
+
+
+
+ 2
+
Find Your Obsidian Vault Folder
+
+
Your vault is the folder on your computer where Obsidian stores all your notes. You chose this folder when you first set up Obsidian.
+
+
Not sure where it is? Open Obsidian, then:
+
+
Click the Settings gear icon (bottom-left corner)
+
Look at the very bottom of the left sidebar — it shows your vault name
+
Click Files & Links in the sidebar
+
The path shown at the top is your vault folder
+
+
+
Or simply: open File Explorer (Windows) or Finder (Mac) and navigate to wherever your notes live.
+
+
+
Tip
+
Inside your vault folder, there's a hidden folder called .obsidian. On Windows, you may need to turn on "Show hidden items" in File Explorer's View menu to see it.
Copy main.js, manifest.json, and styles.css into the codeblock-crbasic folder you just created.
+
+
When you're done, the folder should look like this:
+
+
+
+ 📁
+ codeblock-crbasic/
+
+
+
+ 📄
+ main.js
+
+
+
+ 📄
+ manifest.json
+
+
+
+ 📄
+ styles.css
+
+
+
+
+
That's all the files. Nothing else to download or install.
+
+
+
+
+
+
+
+ 5
+
Enable the Plugin in Obsidian
+
+
+
Restart Obsidian (close it completely and re-open it)
+
Open Settings (gear icon, bottom-left)
+
Click Community plugins in the left sidebar
+
If you see a message about Restricted Mode, click "Turn on community plugins"
+
You should see "CodeBlock CRBasic" in the list of installed plugins
+
Toggle the switch next to it so it turns on (blue/purple)
+
+
+
+
Don't see it?
+
Double-check that all 3 files are in the correct folder, and that the folder is named exactly codeblock-crbasic (no typos, no extra spaces). Then restart Obsidian again.
+
+
+
+
+
+
+
+
+
+
+ 6
+
How to Use It
+
+
In any Obsidian note, create a code block by typing three backticks followed by crbasic, then your code, then three backticks to close:
■Built-in functions — PanelTemp, Battery, DataTable, DataInterval, VoltDiff, Average, etc.
+
■Numbers — 1, 15000, 3.14
+
■Strings — "M!", "Hello"
+
■Comments — anything after an apostrophe: 'this is a comment
+
■Constants — True, False
+
+
+
+
Both views work
+
Syntax highlighting works in both Edit mode (where you type) and Reading mode (the clean preview). Toggle between them with the book/pencil icon in the top-right corner of a note.
+
+
+
+
+
+
+
+
+
+
+ 7
+
Quick Test
+
+
Want to make sure everything is working? Follow this 30-second test:
+
+
+
Open Obsidian
+
Create a new note (click the "New note" icon or press Ctrl+N)
+
Click the Copy button on the example code above
+
Paste it into the note (Ctrl+V)
+
You should immediately see colored keywords in the code block
+
Switch to Reading mode (click the book icon top-right) — the colors should appear there too
+
+
+
If you see colors — you're all set!
+
+
+
+
+
+
+
+
+
+ ?
+
Troubleshooting
+
+
+
No colors showing up at all?
+
+
Make sure the code block starts with exactly ```crbasic (three backticks, then the word crbasic, no space between them)
+
Make sure the plugin is enabled in Settings → Community plugins
+
Try restarting Obsidian completely (close and re-open)
+
+
+
Plugin doesn't appear in the plugin list?
+
+
The folder must be named exactly codeblock-crbasic
+
All 3 files (main.js, manifest.json, styles.css) must be directly inside that folder — not in a sub-folder
+
Make sure Community Plugins / Restricted Mode is turned off
+
+
+
Can't find the .obsidian folder?
+
+
Windows: In File Explorer, click View in the top menu, then check "Hidden items"
+
Mac: In Finder, press Cmd + Shift + . (period) to show hidden files