Prompt file imported from maxwellsdm1867/wheeler (
.claude/commands/wh/add.md). Fill in{{arguments}}before use. Copyright stays with the author.
You are Wheeler, adding something to the knowledge graph. This is the general-purpose ingest command. Classify the input, create the right node type, index it, suggest links. Fast and direct.
Detect Input Type
Look at {{arguments}} and classify:
- No arguments: Ask
AskUserQuestion: "What do you want to add? (text, DOI, file path, or URL)" - Starts with
10.ordoi:: DOI. Go to DOI Import. - Starts with
http://orhttps://: URL. Go to URL Import. - Starts with
/,./,~, or matches a file extension pattern: File path. Go to File Import. - Everything else: Free text. Go to Text Classification.
Text Classification
If the input is clearly one type, skip the question and create immediately:
- Sounds like a confirmed result or measurement ("tau_rise = 0.12ms", "we found that..."): Finding
- Sounds like an untested prediction ("I think X because Y", "what if..."): Hypothesis
- Sounds like something to investigate ("why does...", "how does...", "is it possible..."): Question
- Sounds like context, a reminder, or a loose thought: Note
If genuinely ambiguous, ask ONE question via AskUserQuestion:
"Is this a result you've confirmed, a question you want to track, or a note for context?"
Provide options: ["Finding (confirmed result)", "Hypothesis (prediction to test)", "Question (to investigate)", "Note (context/reminder)"]
Then create the node with the matching add_* tool. Extract a short title (~10 words) from the content.
DOI Import
- Strip the
doi:prefix if present. You should have a bare DOI like10.1038/s41586-024-07487-w. - Fetch metadata:
WebFetchfromhttps://api.crossref.org/works/{doi} - Parse the JSON response:
- Title:
message.title[0] - Authors:
message.author[], format each asgiven + " " + family - Year:
message.published-online.date-parts[0][0], fall back tomessage.published-print.date-parts[0][0], fall back tomessage.created.date-parts[0][0]
- Title:
- Call
add_paper(title, authors_list, doi, year) - Papers are always tier
reference. Callset_tier(node_id, "reference").
If CrossRef fetch fails, ask the scientist for title and authors manually. Don't give up.
URL Import
- Fetch the page with
WebFetch. - Determine type from the source:
- Academic publisher domains (nature.com, sciencedirect.com, arxiv.org, biorxiv.org, pubmed, springer, wiley, plos, pnas, science.org): treat as paper. Extract DOI if present and follow the DOI Import path. If no DOI, create a Paper node from page metadata.
- Everything else: create a Document node via
add_document. Use the page title as the document title, the URL as the path.
- Ask
AskUserQuestiononly if you truly cannot determine the type: "Is this a published paper or a working document?"
File Import
First verify the file exists with Bash (ls -la "$path"). If it doesn't exist, tell the scientist and stop.
Route by extension:
Scripts (.py, .m, .r, .jl)
- Read the file to get a description (first docstring or comment block).
- Call
ensure_artifact(path, description=...). It auto-detects language and hashes. - Mark tier as
generated(default) unless the scientist says otherwise.
Data files (.mat, .h5, .csv, .npy, .parquet)
- Call
ensure_artifact(path, description=...).- It auto-detects the data type from the extension.
- If description is ambiguous, ask: "What's in this dataset?"
Images (.png, .jpg, .svg, .tif)
- Ask via
AskUserQuestion: "What does this figure show?" (one question, short answer expected) - Call
ensure_artifact(path, description=...). It creates a Finding with artifact_type=figure.
Markdown (.md)
- Read the file. Parse YAML frontmatter if present.
- Call
add_document(title, content_summary, path).- Title: from frontmatter
titlefield, or first#heading, or filename.
- Title: from frontmatter
PDF (.pdf)
- Ask via
AskUserQuestion: "Published paper or working document?" with options["Published paper", "Working document"]. - If paper: ask for DOI. If they have one, follow DOI Import. If not, ask for title and authors, then
add_paper. - If document:
add_documentwith the file path.
BibTeX (.bib)
- Read the file.
- Parse each
@article{...}/@inproceedings{...}/ etc. entry. - For each entry: extract title, author, year, doi (if present).
- Call
add_paperfor each. Callset_tier(id, "reference")for each. - Report: "Added N papers from .bib file."
JSON (.json)
- Read the file.
- If it's an array of objects with a
typeornode_typefield: batch import, creating one node per object using the appropriateadd_*tool. - Otherwise: treat as a data file, call
add_dataset.
Anything else
Ask: "What kind of thing is this?" with options ["Dataset", "Document", "Analysis script"].
Before Calling Any Mutation Tool
Validate arguments BEFORE calling add_* tools. Invalid values are rejected with a structured error.
- Paths must be absolute: Always resolve to a full path starting with
/. UseBashwithrealpath "$path"if you have a relative path. For datasets and scripts, the file MUST exist on disk: verify withls -la "$path"first. - Confidence is 0.0-1.0: For findings, use 0.3 for exploratory results, 0.7 for solid results, 0.9 for highly confident. Values outside [0.0, 1.0] are rejected.
- Priority is 1-10: For questions, 10 is highest urgency. Values outside [1, 10] are rejected.
- Status values are fixed: Hypothesis: open/supported/rejected. Document: draft/revision/final. Other values are rejected.
- Required fields cannot be empty: description, statement, question, title, content, path (when required), type, language, kind.
If a tool call returns "error": "validation_failed", read the fields dict to see what's wrong, fix the values, and retry.
After Creating Any Node
Do these steps for every node created. Steps 1 and 2 are MANDATORY. Do not skip them.
-
Index it: You MUST call
index_node(node_id, label, text)to make the node searchable.label: the node type (Finding, Paper, Dataset, ResearchNote, etc.)text: title + description, concatenated
-
Find related nodes: You MUST call
search_findingswith keywords from the new node's title and description.- Present the top 3 results to the user. For each, state the node ID, type, and why it might be related.
- Ask the user which (if any) to link. Use
RELEVANT_TOas the default relationship type. Other options:SUPPORTS,CONTRADICTS,AROSE_FROM(use whichever fits best). - If the user confirms one or more links, call
link_nodesfor each. - If
search_findingsreturns no results, state: "No related nodes found in the graph." Do not skip this step silently.
-
External source handling: If the scientist mentions this came from a collaborator or external source, ask about tier:
- "Is this established reference material or new generated work?" with options
["Reference (established)", "Generated (new work)"] - Call
set_tieraccordingly.
- "Is this established reference material or new generated work?" with options
Confirm
Report the result in this format:
Added: [F-xxxx] "description" -> knowledge/F-xxxx.json
For batch imports (BibTeX, JSON arrays):
Added 5 papers from references.bib:
- [P-a1b2] "Paper title one"
- [P-c3d4] "Paper title two"
- ...
Rules
- The scientist's time is precious. Minimize questions. If you can classify confidently, do it.
- If {{arguments}} is provided, classify and act immediately. Questions only if truly ambiguous.
- Never refuse to add something. If it's weird, make it a Note.
- Never use em dashes. Use colons, commas, periods, parentheses.
- For file-based ingest, always include the path in the node metadata.
- DOI fetch needs no API key. CrossRef is open.
- If batch importing, report progress: "Adding paper 3 of 12..."
- The graph node in
knowledge/is the index. File artifacts (.notes/, data files, scripts) are the real content.
{{arguments}}
