From onebrain
Import local files (PDF, Word, PowerPoint, Excel, images, video, scripts) from a staging inbox folder or explicit path into structured markdown notes in the resources folder (default 04-resources/, resolved from vault.yml). Invoke when user runs /import, /import [path], or /import --attach.
npx claudepluginhub kengio/onebrain --plugin onebrainThis skill uses the workspace's default tool permissions.
Process local files into permanent vault notes in `[resources]/` (resolved from vault.yml; default: `04-resources/`).
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Performs token-optimized structural code search using tree-sitter AST parsing to discover symbols, outline files, and unfold code without reading full files.
Process local files into permanent vault notes in [resources]/ (resolved from vault.yml; default: 04-resources/).
Usage:
/import : scan default import staging inbox ([inbox]/imports/, resolved from vault.yml)/import /path/to/file : import a single explicit file/import --attach : scan inbox and copy supported files into vault for inline Obsidian preview/import /path/to/file --attach : single file with attachResolve folders from vault.yml (read the file if it exists at the vault root):
vault.yml does not exist: use all defaults below.vault.yml exists but cannot be parsed: report the error and stop : do not proceed with unknown folder paths.folders.inbox → default: 00-inbox (vault inbox; used to derive import staging path)folders.import_inbox → default: [inbox]/imports (import staging folder; substituting the resolved [inbox] value)folders.resources → default: 04-resources (output folder for notes)folders.attachments → default: attachments (for --attach copies)Use these resolved values throughout. Store as [inbox], [resources], [attachments].
Parse arguments:
--attach flag if present (remove from path consideration)/import: this is single-file modeSingle-file mode:
[filename]is not a supported file type. Supported: PDF, Word, Excel, PowerPoint, images, video, Python/Shell/SQL scripts. Then stop.
Batch mode:
[inbox] resolved in Step 1 above (default: [inbox]/imports from vault.yml).Import inbox not found at
[inbox path]. Run/onboardingto set up your vault, or use/import /path/to/fileto import a specific file. Then stop.
Inbox is empty (
[inbox path]). Add files there and run/importagain, or run/import /path/to/file. Then stop.
Group files by type. Show a confirmation table:
Found N files to import:
report.pdf PDF document
budget.xlsx Excel spreadsheet
hero-image.png Image
cleanup.sh Shell script
deck.pptx PowerPoint
unknown.xyz ⚠ Unsupported : will be skipped
Proceed with all? Or type filenames to skip (comma-separated, or "all"):
(Inbox files will be removed after successful import)
Unsupported file types are listed with a warning but not processed.
Wait for user response:
Note: In batch mode, subagents auto-select subfolders without user confirmation. Users can move notes to different subfolders after import.
For each file in the confirmed set, dispatch one subagent in parallel. Each subagent receives:
--attach flag is setEach subagent runs the appropriate handler section from this skill (see below).
After all subagents complete, show a summary:
Import complete : 4 notes created:
[resources]/research/report.md (from report.pdf)
[resources]/finance/budget-summary.md (from budget.xlsx)
[resources]/media/hero-image.md (from hero-image.png)
[resources]/scripts/cleanup.md (from cleanup.sh)
4 files removed from inbox.
If any subagent failed:
⚠ 1 file failed:
deck.pptx : markitdown not installed. File left in inbox. Install with: pipx install markitdown
If any files were skipped due to unsupported type:
⏭ 2 files skipped (unsupported : left in inbox):
unknown.xyz
notes.txt
If a note was created but the inbox delete failed (partial success):
⚠ 1 partial success:
report.pdf : note created at [resources]/research/report.md, but inbox file could not be deleted. Delete manually.
| Extension | Type | Handler section |
|---|---|---|
.pdf | PDF Handler | |
.docx | Word | Word Handler |
.xlsx, .xls | Excel | Excel Handler |
.pptx, .ppt | PowerPoint | PowerPoint Handler |
.png, .jpg, .jpeg, .gif, .webp | Image | Image / GIF / SVG Handler |
.svg | SVG | Image / GIF / SVG Handler |
.mp4, .mov, .webm, .mkv | Video | Video Handler |
.py | Python | Script Handler |
.sh, .bash, .zsh | Shell | Script Handler |
.sql | SQL | Script Handler |
These rules apply to all handlers. No exceptions.
1. Cleanup is conditional on note creation success. Delete an inbox file ONLY after the Write tool confirms the note was created. If note creation fails for any reason: return an error, leave the inbox file untouched, stop.
2. Stub notes do NOT trigger cleanup. When a stub note is created (extraction tool unavailable, extraction failed, empty document): do NOT delete the inbox file. The user needs it to retry after fixing the issue.
3. Read/extraction failures stop processing. If the Read tool, markitdown, or any extraction step returns an error or empty output: do NOT create a note. Return an error. Do NOT delete the inbox file.
4. File validation before processing.
Check file size with ls -la "[filepath]". If 0 bytes: create a stub note ("File is empty : no content to extract."), do NOT delete inbox file, return.
5. --attach directory creation.
Before every cp, run mkdir -p for the target directory. If cp fails: skip the embed, report the failure, do NOT delete inbox file, stop.
6. Filename collision.
Before writing a note, check if the target path already exists. If it does: append (Imported YYYY-MM-DD) to the filename and note the rename in the summary.
Used by the Word, PowerPoint, and Excel handlers. Each handler references this section for detection, OS check, Python check, and install : instead of duplicating the logic.
command -v markitdown
Exit 0 → markitdown is installed. Proceed with the handler. Non-zero or command not found → run OS detection below before attempting install.
Run uname:
Darwin → proceed to Python checkLinux AND uname -r contains microsoft or WSL (WSL) → treat as Linux, proceed to Python checkLinux AND uname -r does NOT contain microsoft or WSL (native Linux) → proceed to Python check$OS equals Windows_NT AND uname fails or returns MINGW/CYGWIN →
create stub note:
⚠ Windows detected (non-WSL). /import requires WSL. Run this in a WSL terminal and retry. Stop. Do NOT delete the inbox file.
uname not found: proceed to Python check (assume POSIX-compatible environment).python3 --version
Not found → create stub note:
⚠ Python 3 is not installed. Install Python first:
- macOS:
brew install python3- Linux/WSL:
sudo apt install python3Then run:
pipx install markitdownand re-import this file.
Stop. Do NOT delete the inbox file.
Try in order:
pipx install markitdown # preferred (isolated environment)
If pipx is not found:
pip3 install markitdown # macOS/Linux/WSL
pip install markitdown # fallback if pip3 not in PATH
Install succeeded → retry the handler from the beginning (markitdown is now available).
Install failed → create stub note:
⚠ markitdown could not be installed automatically. Install manually:
pipx install markitdown, then re-import this file.
Stop. Do NOT delete the inbox file.
Executed by a subagent. Inputs: file path, vault root, --attach flag, inbox flag.
Read the PDF file using the Read tool. Claude can read PDFs natively up to 20 pages per request. For large PDFs, read in page ranges.
Extract:
Choose output subfolder:
[resources]/*/ (resolved from vault.yml)research, finance, legal)[resources]/[suggested]/. OK?"Create note at [resources]/[subfolder]/[Title].md using the Note Template below.
file_type: pdfIf --attach flag is set:
mkdir -p "[vault-root]/[attachments]/pdf/"cp "[filepath]" "[vault-root]/[attachments]/pdf/[filename]"cp fails: skip embed, report failure, do NOT delete inbox file, stop![[filename]] embed to the note body (above the Summary section)Cleanup : only if step 4 (note creation) succeeded:
rm "[filepath]"Return: note path, or error with reason
Executed by a subagent. Inputs: file path, vault root, --attach flag, inbox flag.
Requires
markitdown(install:pipx install markitdown). Falls back to stub note if unavailable.
Check markitdown is available : follow the markitdown Dependency section above. If the dependency flow could not install markitdown, skip to step 5 (stub note).
Extract markdown:
markitdown "[filepath]"
From the extracted markdown, identify:
# heading, or derive from filenameChoose output subfolder (same rule as PDF Handler : including single-file confirmation). Create note using Note Template:
file_type: docxStub note fallback (if markitdown unavailable or failed): Create a minimal note with the appropriate message:
markitdown is not installed or could not be installed automatically. Install with: pipx install markitdown, then re-import this file."--attach is NOT supported for Word files (no Obsidian preview value).
Cleanup : only if a full note was created (markitdown succeeded in step 2). If a stub note was created, do NOT delete the inbox file.
Return: note path, or error with reason.
Executed by a subagent. Inputs: file path, vault root, inbox flag. (--attach flag not supported for this type)
Requires
markitdown(install:pipx install markitdown). Falls back to stub note if unavailable.
Check markitdown is available : follow the markitdown Dependency section above. If the dependency flow could not install markitdown, skip to step 5 (stub note).
Extract tables:
markitdown "[filepath]"
Generate AI summary: From the extracted markdown, write 2-3 sentences describing:
Choose output subfolder (same rule as PDF Handler : including single-file confirmation). Create note using Note Template:
file_type: xlsx (use for both .xlsx and .xls files)## Summary
[AI-generated description from step 3]
## [Sheet Name]
[markdown table from markitdown output for this sheet]
## [Sheet 2 Name] ← repeat for each additional sheet
Stub note fallback (if markitdown unavailable or failed): Create a minimal note with the appropriate message:
markitdown is not installed or could not be installed automatically. Install with: pipx install markitdown, then re-import this file.".xls file: "⚠ Content could not be extracted : legacy .xls format may not be fully supported. Convert to .xlsx and re-import, or open the file manually."## Summary section left blank for manual entry.
Do NOT delete the inbox file when a stub note is created.--attach is NOT supported for Excel files.
Cleanup : only if a full note was created (markitdown succeeded in step 2). If a stub note was created, do NOT delete the inbox file. If delete fails, report as partial success.
Return: note path, or error with reason.
Executed by a subagent. Inputs: file path, vault root, inbox flag. (--attach flag not supported for this type)
Requires
markitdown(install:pipx install markitdown). Falls back to stub note if unavailable.
Check markitdown is available : follow the markitdown Dependency section above. If the dependency flow could not install markitdown, skip to step 5 (stub note).
Extract markdown:
markitdown "[filepath]"
From the extracted markdown, create a slide outline:
## headings : use these as the slide structure## Slide Outline section is populated from these headings and their contentChoose output subfolder (same rule as PDF Handler : including single-file confirmation). Create note using Note Template:
file_type: pptx## Slide Outline (slide titles as headings + key points per slide)Stub note fallback (if markitdown unavailable or failed):
markitdown is not installed or could not be installed automatically. Install with: pipx install markitdown, then re-import this file."--attach is NOT supported for PowerPoint files.
Cleanup : only if a full note was created (markitdown succeeded in step 2). If a stub note was created, do NOT delete the inbox file.
Return: note path, or error with reason.
Executed by a subagent. Inputs: file path, vault root, --attach flag, inbox flag.
For PNG, JPG, JPEG, GIF, WebP (visual images):
Read the image using the Read tool. Claude is multimodal and can describe images visually.
Generate a description covering:
Choose output subfolder (suggest media, images, or topic-based; confirm with user in single-file mode, auto-select in batch mode). Create note using Note Template:
file_type: imageFor SVG (vector graphics : treated as structured XML, not visual):
Read the SVG file as text using the Read tool.
Describe:
Create note same as above (same subfolder selection rule : confirm in single-file mode, auto-select in batch mode), but with file_type: svg.
--attach behavior (PNG, JPG, JPEG, GIF, WebP, SVG):
mkdir -p "[vault-root]/[attachments]/images/"cp "[filepath]" "[vault-root]/[attachments]/images/[filename]"cp fails: skip embed, report failure, do NOT delete inbox file, stop![[filename]] embed above the Summary section in the noteCleanup : only after note creation succeeded AND (if --attach was set) cp succeeded. If cp failed, the handler already stopped; do not reach this step. If the file was inside the inbox folder: rm "[filepath]". If delete fails, report as partial success.
Return: Note path, or error with reason.
Executed by a subagent. Inputs: file path, vault root, --attach flag, inbox flag.
Collect metadata:
ls -lh "[filepath]" via Bash : if the command fails, record size as "unknown"Choose output subfolder (suggest media or video; confirm with user in single-file mode, auto-select in batch mode). Create note using Note Template:
file_type: video--attach behavior:
mkdir -p "[vault-root]/[attachments]/video/"cp "[filepath]" "[vault-root]/[attachments]/video/[filename]"cp fails: skip embed, report failure, do NOT delete inbox file, stop![[filename]] embed above the Summary sectionCleanup : only after note creation succeeded AND (if --attach was set) cp succeeded. If cp failed, the handler already stopped; do not reach this step. If the file was inside the inbox folder: rm "[filepath]". If delete fails, report as partial success.
Return: note path.
Executed by a subagent. Inputs: file path, vault root, inbox flag.
Handles: .py, .sh, .bash, .zsh, .sql
Read the file content verbatim using the Read tool.
Analyze the script:
Choose output subfolder (suggest scripts, or topic-based like data-processing; confirm with user in single-file mode, auto-select in batch mode). Create note using Note Template:
file_type: script## Code section after Key Points with the full file content in a fenced code block using the correct language tag:
.py → python.sh, .bash, .zsh → bash.sql → sql--attach is NOT supported for scripts (content is already in the note as a code block).
Cleanup : only if step 1 (Read) succeeded and the note was created. If the file was inside the inbox folder: rm "[filepath]". If delete fails, report as partial success.
Return: note path.
All handlers use this base template. Type-specific sections are added by each handler.
The note structure:
If file came from an explicit path (not inbox) : file is kept in place:
---
tags: [import, <type-tag>]
created: YYYY-MM-DD
source: /import
file_type: <pdf|docx|xlsx|pptx|image|svg|video|script>
file_path: /absolute/path/to/original
---
# [Filename or derived title]
> **Original file:** [Open](file:///absolute/path/to/original)
> **Imported:** YYYY-MM-DD
[If --attach flag was used and file type supports it, add: ![[filename]] ]
## Summary
[2-3 sentence distillation, AI description, or plain-language explanation]
## Key Points / Contents
[Extracted structure : key sections, data highlights, slide outline, script analysis, etc.]
## Related
[[linked vault notes]]
If file came from the inbox : file is deleted after import:
---
tags: [import, <type-tag>]
created: YYYY-MM-DD
source: /import
file_type: <pdf|docx|xlsx|pptx|image|svg|video|script>
---
# [Filename or derived title]
> **Imported from inbox:** YYYY-MM-DD : staging copy removed after import
[If --attach flag was used and file type supports it, add: ![[filename]] ]
## Summary
[2-3 sentence distillation, AI description, or plain-language explanation]
## Key Points / Contents
[Extracted structure : key sections, data highlights, slide outline, script analysis, etc.]
## Related
[[linked vault notes]]
Type-specific section additions (after Key Points):
## Code : full file content in a fenced code block## Slide Outline : slide titles as headings + key points per slide## Key Points / Contents : use ## Summary (AI-generated) + ## [Sheet Name] (markdown table per sheet)## Summary : left blank for manual entryScan for related notes: After creating the note, grep [resources]/**/*.md and 03-knowledge/**/*.md for titles or tags related to the file's topic. Suggest up to 2 wikilinks if found. If no related notes are found, leave the ## Related section with: _No related notes found : add links manually._
Note on
file_path:file_pathis only included for files imported from an explicit path (kept in place after import). For inbox-staged files,file_pathis omitted : the staging copy is deleted and the note is the permanent artifact.