Curio CLI

Working with the Curio CLI

Need to install or connect the CLI?

See Installation and Integrations for installation, updates, settings, AI Agent Skills, MCP, and AI-client setup.

This guide covers using the Curio CLI to inspect and modify Curio projects, organize content, import and export files, navigate the Curio app, and work with command output and errors.

Quick Start

Check whether Curio is running:

curio status

Query the running app using Curio’s full query language:

curio query "#active due soon sort:priority" --fields id,title,priority,due_date

Query the current selection:

curio query --selected figure --fields plain_text,priority

Read a specific figure:

curio get --id 12345678-1234-1234-1234-123456789ABC --fields raw_text,due_date,tags,asset_file,sync_file

Get the selected idea space:

curio get --selected ideaspace --fields title,note,tags

List all available tags in the current project:

curio tags
curio tags --project ~/Documents/MyProject.curio

Inspect the project’s section hierarchy:

curio sections --project ~/Documents/MyProject.curio

List assets under a section or Organizer parent:

curio assets --project ~/Documents/MyProject.curio --section 12345678-1234-1234-1234-123456789ABC --recursive --organizer_order
curio assets --project ~/Documents/MyProject.curio --parent 87654321-4321-4321-4321-CBA987654321 --recursive --organizer_order

Create Organizer structure in the running app:

curio create section --title "Research"
curio create folder --section 12345678-1234-1234-1234-123456789ABC --title "Exhibits"
curio create ideaspace --section 12345678-1234-1234-1234-123456789ABC --title "001 - Complaint"
curio create ideaspace --selected ideaspace --position next_sibling --title "002 - Exhibit A"

Move a figure on the canvas or move an idea space in the Organizer:

curio move --selected figure --position 100,100
curio move --id 12345678-1234-1234-1234-123456789ABC --relative-to 87654321-4321-4321-4321-CBA987654321 --position next_sibling
curio move --id 12345678-1234-1234-1234-123456789ABC --parent 87654321-4321-4321-4321-CBA987654321 --position first_child

Update the selected figure:

curio set --selected figure --priority 4 --due-date 2026-04-01
curio set --selected figure --field priority=3 --values '{"note":"Reviewed"}'
curio set --selected figure --field size.width=360
curio set --selected figure --field fill_color=#ffcc66 --field pen_color=#112233

Send text through standard input:

echo "hello from Terminal" | curio set --selected figure --raw-text --stdin

Set an asset figure caption:

curio set --selected figure --caption "Sprint planning whiteboard"

Update the selected idea space:

curio set --selected ideaspace --title "Roadmap" --tags "GTD/Active,Planning"
curio set --selected ideaspace --field dimension.width=1600 --field dimension.height=1000 --field fill_color=#f0f7ff

Export the currently selected figures as PDF:

curio export --selected figures --format pdf --filename ~/Desktop/Selection

Import a file into the current idea space:

curio import ~/Photos/diagram.png

Import content as a structured figure:

curio import ~/outline.md --as list

Spread a multi-page PDF into one idea space per page:

curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --title-template "{page:03}"
curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --layout layout.json

Querying

The query command uses the same query language as Curio’s Search shelf and Quick Find, so the same query expressions, scopes, grouping, and sorting rules apply. See Curio’s query language documentation for a deeper discussion of query syntax.

When Curio is running, context scopes such as scope:section and scope:ideaspace use the current Organizer section or active idea space. Direct --project mode is offline and returns InvalidRequest for context-dependent scopes that require live UI state.

Unless the query text includes an explicit group: command, the CLI returns a flat items array and reports groupBy as null. If the query text includes group:, the response switches to a groups array with label and items for each group.

Examples:

curio query "ipad"
curio query "(ipad or iphone) @SteveJ #event #2010" --fields id,title
curio query "#active due soon sort:priority" --fields id,title,priority,due_date
curio query "#active group:priority" --fields id,title,priority
curio query --project ~/Documents/MyProject.curio "#active" --fields id,title

You can optionally truncate long text fields in the response:

curio query "#meeting" --fields id,title,plain_text --max-chars 500

Use --fields all with query to return every field that applies to each result item’s type.

Selected Targets

Instead of a query string, you can ask for specific live UI targets using --selected <kind>. These selected targets only work when Curio is running.

--selected value Returns
figure The single selected figure
figures All selected figures
section The current section containing the active organizer item
sections All selected sections
organizer_item / ideaspace The active Organizer item or idea space
organizer_items / ideaspaces The selected Organizer items or idea spaces

Examples:

curio query --selected figure --fields plain_text,priority
curio query --selected figures --fields id,title,priority
curio query --selected section --fields id,title,kind
curio query --selected sections --fields id,title,kind
curio query --selected ideaspace --fields id,title
curio query --selected ideaspaces --fields id,title,kind

Important

Selected targets are based on Curio’s current UI state, so they are not available with --project.

Figure Fields

These are the fields available when the target is a figure. You can use them with query, get, and figure-targeted set.

Use --id <uuid-or-identifier> to target a specific figure. UUID lookup is tried first; identifiers must be unique or Curio returns InvalidRequest. Use --selected figure to target the single selected figure.

get supports both the running app and --project. Use --fields all with get to return the full field set for the selected target type. set requires the running app.

Examples:

curio get --selected figure --fields raw_text,due_date,tags
curio get --id 12345678-1234-1234-1234-123456789ABC --fields id,title,kind,link
curio get --project ~/Documents/MyProject.curio --id 12345678-1234-1234-1234-123456789ABC --fields title,plain_text
curio get --id 12345678-1234-1234-1234-123456789ABC --fields link,asset_id,asset_file_kind,display_page
curio set --selected figure --priority 4
curio set --selected figure --rating 5 --progress 75
curio set --selected figure --start-date 2026-03-20 --due-date 2026-03-27
curio set --selected figure --done-date 2026-03-27T14:30
curio set --selected figure --caption "Sprint planning whiteboard"
curio set --selected figure --note "Reviewed with team"
curio set --selected figure --field priority=3 --field rating=4
curio set --selected figure --field size.width=360 --field origin.x=72 --field origin.y=96
curio set --selected figure --field text_font_size=18 --field text_color=#123456 --field text_bold=true
curio set --selected figure --field fill_color=#ffcc66 --field pen_color=#112233 --field pen_width=2
curio set --selected figure --field displaying_as=preview --field display_page=2
curio set --selected figure --field icon_size=64 --field caption_within_shape_border=false
curio set --selected figure --field freeform_sizing=false --field min_height=120
curio set --selected figure --values '{"bounds":{"x":72,"y":96,"width":360,"height":240}}'
curio set --selected figure --values '{"text_alignment":"center","text_vertical_alignment":"middle"}'
curio set --selected figure --values '{"fill_style":"solid","shape":"RoundedRect","opacity":0.75}'
curio set --selected figure --values '{"note":"Reviewed with team","priority":3}'
curio set --selected figure --values-file updates.json
cat notes.md | curio set --selected figure --raw-text --stdin

For common fields, use the named flags such as --priority or --due-date. For script-generated updates, --field key=value handles quick scalar assignments, while --values and --values-file accept a JSON object of writable field values. Set size.width to let Curio recompute a natural height for figures that support it, such as text figures, image previews, and collections. Text styling fields use the text_ prefix, including text_font_size, text_color, text_bold, and alignment fields. Figure styling fields include fill_color, pen_color, pen_width, opacity, corner_radius, fill_style, shape, and dashed_pattern. Asset presentation fields include displaying_as, display_page, caption placement, icon size, automatic sizing, freeform sizing, and minimum height. All set forms merge into the same update request, so don’t provide the same field more than once in a single command.

Field Settable Description
id no Figure or Organizer item UUID (stable, used for addressing)
identifier no User-visible figure identifier set via Curio’s Info panel
kind no Figure or Organizer item kind used by query kind filters
title no Processed plain text title (writable when targeting an Organizer item)
link no curio:// deep link URL that opens the project and navigates to the target item
section_path no Section hierarchy containing the figure or Organizer item
organizer_path no Organizer path to the figure’s idea space or to the Organizer item
raw_text yes Raw text content (may contain markdown, MathJax, Mermaid source)
caption yes Asset figure caption text (empty string clears it)
displaying_as yes Asset figure display mode: icon, preview, text, or live_preview when supported
display_page yes 1-based displayed page number for PDF asset figures
caption_within_shape_border yes Whether the asset figure caption is drawn within the shape border
icon_size yes Asset figure icon size in points, from 16 to 512; sets square icon width and height
auto_sizing yes Whether the asset figure automatically sizes itself to its content
freeform_sizing yes Whether the asset figure uses freeform sizing instead of automatic sizing or minimum-height fitting
min_height yes Asset figure minimum height in points; 0 clears it
plain_text no Processed searchable text
rendered_text no Fully processed plain text
rendered_markdown no Figure content converted to Markdown
url no Associated URL for URL figures
asset_file no File path to the underlying asset file (PDF, image, doc, etc.)
asset_id no Underlying asset UUID for an asset-backed figure
asset_file_kind no Underlying asset display/file kind
sync_file no Sync file URL, if sync is configured
sync_file_direction no Sync direction: bidirectional, export, or import
start_date yes Start date (YYYY-MM-DD or YYYY-MM-DDTHH:MM)
due_date yes Due date (YYYY-MM-DD or YYYY-MM-DDTHH:MM)
done_date yes Done date (YYYY-MM-DD or YYYY-MM-DDTHH:MM)
added_date no Date the figure or Organizer item was added (YYYY-MM-DD or YYYY-MM-DDTHH:MM, read-only)
modified_date no Date the figure or Organizer item was last modified (YYYY-MM-DD or YYYY-MM-DDTHH:MM, read-only)
tags yes Array of tag names; matching ignores case, spaces, and emoji when setting, for example vacation,gtd/onhold
resources no Array of resource names
references no Outgoing references grouped by reference type name; each value is an array of target curio:// links
priority yes Priority level (0=none, 1=very low, 2=low, 3=medium, 4=high, 5=urgent)
rating yes Rating (0-5)
progress yes Percent complete (0-100)
text_font_family yes Text font family name
text_font_face yes Text font face name within the selected family, such as Regular, Bold, or Italic; PostScript font names are also accepted
text_font_size yes Text font size in points
text_color yes Text foreground color as #rgb, #rgba, #rrggbb, or #rrggbbaa
text_background_color yes Text background color as #rgb, #rgba, #rrggbb, or #rrggbbaa; transparent clears the background
text_bold yes Whether text is bold
text_italic yes Whether text is italic
text_underline yes Whether text is underlined
text_strikethrough yes Whether text has strikethrough
text_alignment yes Text horizontal alignment: left, center, right, justified, or natural
text_vertical_alignment yes Text vertical alignment: top, middle, or bottom
origin.x yes Figure bounds origin x coordinate
origin.y yes Figure bounds origin y coordinate
size.width yes Figure width; recomputes natural height when supported
size.height yes Figure height
bounds yes Rectangle object with x, y, width, and height
rotation yes Figure rotation angle in degrees
fill_color yes Figure fill color as #rgb, #rgba, #rrggbb, or #rrggbbaa; setting a figure fill color enables solid fill unless fill_style is also set to none
pen_color yes Figure pen color as #rgb, #rgba, #rrggbb, or #rrggbbaa; setting a pen color ensures a visible pen width unless pen_width is also set to 0
pen_width yes Figure pen width in points; 0 hides the stroke
opacity yes Figure opacity from 0.0 transparent through 1.0 opaque
corner_radius yes Figure corner radius in points, from 0 to 30, when the figure or collection layout supports corner radius changes
fill_style yes Figure fill style: none or solid
shape yes Figure shape name, such as Rectangle, RoundedRect, Capsule, Circle, Diamond, or Cloud
dashed_pattern yes Figure dash pattern as pixelsOn{,pixelsOff,pixelsOn,pixelsOff}{;phase}; use 0 for a solid line
note yes Meta note text

Asset Presentation Fields

Asset figures support display, caption, and sizing controls through generic writable fields. Curio rejects display modes that the target figure cannot support, such as text for a plain image asset or live_preview for a non-URL asset. For PDFs, display_page is 1-based and out-of-range errors include the valid page range when Curio can read it.

freeform_sizing and min_height are mutually exclusive in Curio’s figure model: enabling freeform sizing clears min_height and disables auto_sizing; setting min_height above 0 turns freeform sizing off.

Organizer Item Fields

These are the fields available when the target is an Organizer item or idea space. You can use them with query, get, and set.

Use --id <uuid-or-identifier> to target a specific Organizer item or idea space. UUID lookup is tried first; identifiers must be unique or Curio returns InvalidRequest. Use --selected ideaspace to target the active organizer item / idea space. organizer_item is still accepted as an alias.

get supports both the running app and --project. Use --fields all with get to return the full field set for the selected target type. set requires the running app.

Examples:

curio get --id 87654321-4321-4321-4321-CBA987654321 --fields title,note,tags
curio get --selected ideaspace --fields title,note,tags
curio set --selected ideaspace --title "Deep Link"
curio set --selected ideaspace --tags "GTD/Active,Planning"
curio set --selected ideaspace --note "Reviewed with team"
curio set --selected ideaspace --field dimension.width=1600 --field dimension.height=1000
curio set --selected ideaspace --values '{"dimension":{"width":1600,"height":1000},"fill_color":"#f0f7ff"}'

Idea space and Organizer item IDs support direct title, note, and tags reads and writes. Idea spaces also support dimension.width, dimension.height, and fill_color; these change the canvas size and background fill, not figure bounds or figure fill.

Field Settable Description
id no Idea space or Organizer item UUID (stable, used for addressing, identical to the underlying asset UUID)
identifier no User-visible idea space identifier set via Curio’s Info panel
kind no Figure or Organizer item kind used by query kind filters
asset_file_kind no Underlying asset display/file kind
title yes Processed plain text title (writable when targeting an Organizer item)
link no curio:// deep link URL that opens the project and navigates to the target item
section_path no Section hierarchy containing the figure or Organizer item
organizer_path no Organizer path to the figure’s idea space or to the Organizer item
dimension.width yes Idea-space canvas width in points
dimension.height yes Idea-space canvas height in points
fill_color yes Idea-space background fill color as #rgb, #rgba, #rrggbb, or #rrggbbaa
added_date no Date the figure or Organizer item was added (YYYY-MM-DD or YYYY-MM-DDTHH:MM, read-only)
modified_date no Date the figure or Organizer item was last modified (YYYY-MM-DD or YYYY-MM-DDTHH:MM, read-only)
tags yes Array of tag names; matching ignores case, spaces, and emoji when setting, for example vacation,gtd/onhold
references no Outgoing references grouped by reference type name; each value is an array of target curio:// links
note yes Meta note text

Creating Organizer Structure

Use create to add sections, folders, and idea spaces through the running Curio app. Creation is app-only so Curio’s Organizer model, validation, selection handling, and undo behavior stay in charge; it is not available with --project.

Examples:

curio create section --title "Correspondence" --note "Reviewed" --tags "Discovery/Verified"
curio create section --parent 12345678-1234-1234-1234-123456789ABC --title "Authorities"
curio create folder --section 12345678-1234-1234-1234-123456789ABC --title "Discovery"
curio create ideaspace --section 12345678-1234-1234-1234-123456789ABC --title "001 - Notice of Motion"
curio create ideaspace --selected ideaspace --position next_sibling --title "002 - Exhibit A"

create section can target the Organizer root or a parent section. create folder and create ideaspace can target a section or another Organizer item. Every successful create response returns the new item’s stable id, kind, title, parent_id, resolved index, and any create-time note or tags so scripts can chain later operations.

Moving Figures And Idea Spaces

Use move through the running Curio app to reposition a figure on the current idea-space canvas or to reparent/reorder an Organizer item such as an idea space. move is app-only and is not available with --project.

Figure moves use an absolute idea-space coordinate:

curio move --id 12345678-1234-1234-1234-123456789ABC --position 100,100
curio move --selected figure --position 240,160

Organizer moves use the same placement vocabulary as create:

curio move --id 12345678-1234-1234-1234-123456789ABC --relative-to 87654321-4321-4321-4321-CBA987654321 --position previous_sibling
curio move --id 12345678-1234-1234-1234-123456789ABC --section 87654321-4321-4321-4321-CBA987654321 --position last_child
curio move --selected ideaspace --parent 87654321-4321-4321-4321-CBA987654321 --position first_child

Options:

  • --id <uuid> targets a figure or Organizer item.
  • --selected figure|ideaspace|organizer_item uses Curio’s current UI selection.
  • --position x,y moves a figure to an absolute canvas coordinate.
  • --position first_child|last_child|first_sibling|previous_sibling|next_sibling|last_sibling moves an Organizer item.
  • --parent <uuid> , --section <uuid> , and --relative-to <uuid> choose the Organizer destination context.
  • --index <n> provides an explicit child index for Organizer moves and cannot be combined with --position .

Successful move responses include mode (figure or organizer) plus the moved item’s id. Figure responses include final geometry fields such as origin.x, origin.y, and bounds; Organizer responses include final parent_id and index.

Command Batch Files

Use curio batch to run a UTF-8 text file containing one Curio command per line. Lines can omit the leading curio prefix, blank lines are ignored, and # starts a comment outside quotes.

# filing.curio-batch
discovery = create section --title "Discovery"
emails = create ideaspace --title "Emails" --parent $discovery.id
import "~/Documents/emails.pdf" --as spread-pdf --parent $discovery.id --layout layout.json
curio batch filing.curio-batch

A line can store its structured result with name = command .... Later lines can refer to top-level result fields such as $discovery.id, $emails.link, or $spread.asset_id. Batch output is JSONL: one JSON object per executed line, including the source line number, ref (null for unassigned lines), exit code, and either result or error. Execution stops on the first failure unless you pass --continue-on-error.

Batch files do not support child commands that read from stdin, such as import --stdin or set --stdin, because the batch file itself owns the input stream. Use file-backed imports or pass values directly in the batch line.

Placement options:

Position Meaning
first_child Insert as the first child of the target parent.
last_child Insert as the last child of the target parent. This is the default.
first_sibling Insert at the beginning of the reference item’s sibling list.
previous_sibling Insert immediately before the reference item.
next_sibling Insert immediately after the reference item.
last_sibling Insert at the end of the reference item’s sibling list.

Target options:

  • --parent <uuid> targets a parent section or Organizer item.
  • --section <uuid> targets a section for folder or idea-space creation.
  • --relative-to <uuid> targets an existing section or Organizer item for sibling placement.
  • --selected section|ideaspace|organizer_item uses Curio’s current UI selection.
  • --index <n> provides an explicit child index and cannot be combined with --position .

Sections

Use sections to return the Organizer’s section hierarchy. This command returns a recursive tree by default using children, so child sections are nested under their parent sections automatically.

Examples:

curio sections
curio sections --project ~/Documents/MyProject.curio

Top-level special sections such as Archive, Trash, and Journal are included when present.

Assets

Use assets to list assets in the project or within a specific section.

Examples:

curio assets
curio assets --project ~/Documents/MyProject.curio
curio assets --project ~/Documents/MyProject.curio --section 12345678-1234-1234-1234-123456789ABC
curio assets --project ~/Documents/MyProject.curio --parent 87654321-4321-4321-4321-CBA987654321
curio assets --project ~/Documents/MyProject.curio --section 12345678-1234-1234-1234-123456789ABC --recursive --organizer_order
curio assets --project ~/Documents/MyProject.curio --parent 87654321-4321-4321-4321-CBA987654321 --recursive --organizer_order

assets --section <uuid> restricts results to a section. assets --parent <uuid> restricts results to an Organizer parent such as a folder, idea space, or section. Both are non-recursive by default. Add --recursive to include child items as well.

The returned asset list includes figure assets that are contained within idea spaces, like PDF images.

Organizer contents

Technically Organizer items are assets so you can use curio assets to get your Organizer tree as well.

  • Use --organizer_order to return only organizer-visible items in the exact Organizer UI order for that section or parent, with folder contents nested under children .
  • --organizer_order requires --section or --parent and can be combined with --recursive .
  • When --organizer_order is specified, results include parent_id , parent_title , depth , index , and container_kind so callers can reconstruct the Organizer tree. Flat asset listings do not include these hierarchy fields.
  • This mode is Organizer-facing, so it does not include figure assets that are contained within idea spaces, like PDF images.

Example Organizer tree:

Case 25
├── Deep Link
└── Deep Folder
    └── Item in Folder

The UUID for each returned asset can be used as the idea space / Organizer item UUID in calls such as set and get.

Each asset includes both a machine-readable kind and a human-readable asset_file_kind:

  • kind is the stable Curio asset kind for scripting and matches the query language’s kind=... filter, with values such as organizerfolder , organizersection , organizerideaspace , organizerspecialsection , or image .
  • asset_file_kind is the asset’s display/file kind, such as Organizer Folder or PDF document .

This split lets scripts filter by Curio structure using kind while still inspecting file-specific details using asset_file_kind and asset_file.

Exporting

The export command exports content from the running app to a file or the clipboard. You can export a single figure by UUID or identifier, all selected figures, or selected idea spaces in the Organizer.

Supported export formats are png, jpg, pdf, text, markdown, and rtf.

Examples:

curio export --id 12345678-1234-1234-1234-123456789ABC --format png --filename ~/Desktop/Figure
curio export --id 87654321-4321-4321-4321-CBA987654321 --format pdf --filename ~/Desktop/IdeaSpace
curio export --selected figures --format png --filename ~/Desktop/Selection
curio export --selected figures --format pdf --clipboard
curio export --selected figures --format markdown --filename ~/Desktop/Notes --include-assets
curio export --selected ideaspaces --format pdf --filename ~/Desktop/IdeaSpaces
curio export --selected ideaspace --format pdf --clipboard
curio export --selected figures --format png --filename ~/Desktop/Selection --overwrite

If --filename points to an existing folder then Curio will automatically name the export using the selected content’s title.

If --id names a figure, Curio navigates to that figure and exports the resulting single selection. If --id names an idea space, Curio exports that idea space directly.

Note

--clipboard is supported for figure exports, and for --selected ideaspace only when exactly one idea space is selected and the format is png, jpg, or pdf. For file exports, --selected ideaspace supports png and jpg only when exactly one idea space is selected. Multi-idea-space file exports are supported for pdf, text, markdown, and rich text.

Note

Rich text exports are requested with --format rtf, but the actual output may be .rtf or .rtfd depending on whether attachments are present. Markdown exports with --include-assets use a sibling Assets/ folder, and repeated exports merge into that folder instead of replacing it. Exported markdown asset references are written to match the resulting asset folder layout.

Importing

The import command creates a new figure on the current idea space from a file or from standard input. It can also spread a multi-page PDF into one idea space per page. It requires the running Curio app and does not support --project.

Important

The Mac App Store edition of Curio runs in a sandbox that limits which file paths it can access. File import (--as file), Spread PDF import (--as spread-pdf), and file sync (--sync) work only when the source file is in an accessible folder — the app’s temporary directory, Downloads, your Curio projects folder, or any folder you have previously authorized in Curio. Run curio status to see the list of accessible folders for your installation. Content import (--as text, list, mindmap, stack, table) without --sync works with both editions regardless of file location, because the CLI reads the file and sends the content directly.

Tip

If you are scripting file imports against the Mac App Store edition, use the accessible folders list from curio status to find a staging location. The app’s temporary directory is always available and can be written to by any process running as the same user. Note that the sandboxed temporary directory is inside the app container (e.g. ~/Library/Containers/com.zengobi.curio/Data/tmp/), not the system /tmp. The website (direct download) edition is not sandboxed and can access any file path.

Importing a file as an asset figure

By default, import copies the file into the project as an asset figure (image, PDF, document, etc.):

curio import ~/Photos/diagram.png
curio import ~/Documents/report.pdf --transfer move
curio import /Volumes/Ext/video.mp4 --transfer alias

The --transfer flag controls how the file is handled:

Value Description
copy Copy into the project (default)
move Move into the project
alias Reference the file externally without copying

Spreading a PDF across idea spaces

Use --as spread-pdf to import a multi-page PDF as one stored PDF asset and one or more idea spaces. By default, Curio creates one idea space per requested page. Each created idea space contains a distinct PDF figure instance, so each page has its own figure UUID and curio:// link while all figures share the same asset_id and asset_file.

When PDFs are imported into Curio, Curio automatically uses Apple Vision to perform an OCR scan in the background. The OCR text is stored with the PDF asset, can be viewed in the Curio UI via the Info inspector panel, and is automatically included when Curio searches text through the query system in either the Curio UI or the CLI.

curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --title-template "{page:03}"
curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --pages 1-10,15
curio import ~/Documents/affidavit.pdf --as spread-pdf --selected ideaspace --position next_sibling
curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --page-titles titles.json
curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --layout layout.json
curio import ~/Documents/affidavit.pdf --as spread-pdf --section <sectionUUID> --dry-run

Spread PDF placement uses the same target and position model as curio create:

Option Description
--section <uuid> Create page idea spaces under a section
--parent <uuid> Create page idea spaces under a section or Organizer item
--selected ideaspace Use the selected or active Organizer item as the placement reference
--selected organizer_item Alias for --selected ideaspace
--relative-to <uuid> Use an Organizer item UUID as the placement reference
--position <pos> first_child, last_child, first_sibling, previous_sibling, next_sibling, or last_sibling
--index <n> Numeric child index; cannot be combined with --position

By default, --pages all creates one idea space for every PDF page. Use a comma-separated page/range list such as 1-10,15 to import a subset. Duplicate pages are rejected.

Use --title-template for generated idea space titles. Supported tokens are {page}, {page:03}, {page_start}, {page_end}, {page_count}, and {filename}. Use --page-titles when titles need to come from a manifest:

[
  { "page": 1, "title": "2026-05-01 - Letter from Smith" },
  { "page": 2, "title": "p2" }
]

Use --layout when each idea space should contain a grid of PDF pages instead of a single page. The number of pages per idea space is columns * rows. The optional figure frame defines the first page figure, and x_gap / y_gap determine the offsets for the remaining columns and rows:

{
  "columns": 2,
  "rows": 2,
  "x_gap": 50,
  "y_gap": 50,
  "figure": { "x": 72, "y": 72, "width": 420, "height": 540 },
  "title_template": "Pages {page_start}-{page_end}"
}

A layout file can also include pages. Explicit command-line options such as --pages and --title-template override values in the layout file.

--transfer copy and --transfer move are supported. --transfer alias is rejected for Spread PDF import because the operation creates a stored project asset that is shared by the created page figures.

The response includes asset_id, asset_file, and an items array with every created ideaspace_id, title, page range, and page figure. For layout imports, each item includes a figures array with each figure’s figure_id, display_page, frame, and link.

Importing content as a structured figure

Use --as to choose a specific import mode instead of the default asset-figure import:

curio import ~/notes.md --as text
curio import ~/outline.md --as list
curio import ~/outline.md --as mindmap
curio import ~/outline.md --as stack
curio import ~/data.csv --as table
--as value Description
file Store the file as an asset figure (default when --as is omitted)
spread-pdf Store one PDF asset and create one idea space per requested page
text Create a text figure from the file content
list Parse hierarchical text into a list collection
mindmap Parse into a mind map collection
stack Parse into a stack collection
table Parse tabular text (CSV/TSV/markdown table) into a table collection

The content format is auto-detected from the file extension:

Extension Format
.md, .markdown Markdown
.taskpaper TaskPaper
.opml OPML
.csv CSV
.tsv TSV
.txt, other Plain text

Reading content from standard input

Use --stdin to read content from standard input instead of a file. This only works with content types (--as text, list, mindmap, stack, or table).

echo "- Item 1\n- Item 2" | curio import --stdin --as list
pbpaste | curio import --stdin --as text
cat data.tsv | curio import --stdin --as table --content-format tsv

Since stdin has no file extension, the content format defaults to Markdown (or CSV when --as table). Use --content-format to override this default:

curio import --stdin --as list --content-format taskpaper
curio import --stdin --as table --content-format tsv
curio import --stdin --as mindmap --content-format opml

Supported --content-format values: markdown, taskpaper, opml, csv, tsv, plain.

Setting up a sync file

Use --sync to create a content figure that stays synchronized with the source file. This requires a file path (not --stdin) and a content type (--as text, list, mindmap, stack, or table).

curio import ~/todo.md --as list --sync bidirectional
curio import ~/brainstorm.md --as mindmap --sync import
curio import ~/notes.md --as text --sync export
--sync value Description
bidirectional Changes flow both ways between the figure and the file
export Figure changes export to the file
import File changes import into the figure

Import response

The response includes the created figure’s UUID so you can immediately use get or set on it:

{
  "api_version": 1,
  "app_version": "26.1",
  "response_ok": true,
  "result": {
    "figure_id": "12345678-1234-1234-1234-123456789ABC",
    "figure_kind": "list",
    "title": "todo"
  }
}

When --sync is used, the response also includes sync_file and sync_direction.

Use navigate to jump to a Curio location:

curio navigate "curio://project/MyProject.curio?figure=abc-123"
curio navigate ~/Documents/MyProject.curio
curio navigate 12345678-1234-1234-1234-123456789ABC

If Curio is not already running, navigate can still open curio:// URLs and .curio project paths. Navigating by UUID requires the running app.

Status

The status command reports whether Curio is running, which projects are open, and whether the app is sandboxed:

curio status

When Curio is running as the Mac App Store edition, the response includes app_sandboxed: true and an accessible_folders array listing the folders the sandboxed app can read from:

{
  "api_version": 1,
  "app_version": "26.1",
  "response_ok": true,
  "result": {
    "accessible_folders": [
      "/Users/you/Library/Containers/com.zengobi.curio/Data/tmp/",
      "/Users/you/Library/Containers/com.zengobi.curio/Data/Downloads",
      "/Users/you/Documents/Curio",
      "/Users/you/Desktop"
    ],
    "app_open_projects": [
      { "path": "/Users/you/Documents/Curio/MyProject.curio", "title": "MyProject" }
    ],
    "app_running": true,
    "app_sandboxed": true
  }
}

The accessible folders typically include:

  • The app’s temporary directory (inside the sandbox container, not system /tmp )
  • The app’s Downloads directory (also inside the container)
  • Your Curio projects folder (set in Preferences)
  • Any authorized folders you have previously granted Curio access to

When the website (direct download) edition is running, app_sandboxed is false and accessible_folders is not included — the app can access any file path.

When Curio is not running, status returns a local response with app_running: false.

Command Summary

Command Purpose
curio query ... Query figures using Curio’s query language
curio get ... Read fields from one figure or one Organizer item
curio sections ... Return the Organizer section hierarchy
curio assets ... List project assets or assets within a section
curio create ... Create Organizer sections, folders, and idea spaces
curio move ... Move a figure on the canvas or move an Organizer item
curio batch ... Run a command batch file with pseudo-variable references
curio set ... Update writable fields on one figure or one Organizer item
curio export ... Export a figure, selected figures, or selected idea spaces
curio import ... Import a file/content or Spread PDF pages
curio navigate ... Open a deep link, project, or UUID target
curio status Report whether Curio is running, open projects, and sandbox info
curio skills Manage AI platform skill installations
curio claude Install, package, or diagnose the Claude Desktop connector
curio mcp-server Run the stdio MCP server for host-launched AI integrations
curio fields List all available fields
curio fields <name> Show details for one field
curio tags List all available tags in the current project
curio update Check for the latest CLI release
curio --help Show built-in command help
curio --version Show the installed CLI version

Available Fields

Field names are always written in snake_case and are passed as a comma-separated list to --fields.

For example:

curio query "#active" --fields id,title,priority,due_date

The exact field list for your installed version is available via curio fields. For convenience, the full reference is split above into:

curio fields shows the combined catalog across both target types, and curio fields <name> shows the type and description for one field.

Available Tags

Use curio tags to list all visible tags in the current project.

Examples:

curio tags
curio tags --project ~/Documents/MyProject.curio

curio tags returns:

  • items : array of tag name strings
  • count : number of returned tags

Tag names are formatted exactly as Curio expects them in tag-oriented CLI operations:

  • Named tag sets use TagSet/Tag Name , such as GTD/Active or Context/Next Action .
  • Project-local keyword tags use just Tag Name .
  • Global keyword tags use /Tag Name .

When you set tags, Curio matches tag names case-insensitively and ignores spaces and emoji, so inputs such as vacation,gtd/onhold still resolve to the corresponding visible tags.

Sections and Assets Output

sections and assets return structured JSON results directly and do not use --fields.

Sections Result

curio sections returns:

  • items : array of top-level section objects
  • count : number of top-level section objects

Each section object includes the same general metadata style as other CLI output, and parent sections include a children array when they contain child sections.

Assets Result

curio assets returns:

  • items : array of asset objects
  • count : number of returned assets

In normal mode, items is a flat array. Use --section <uuid> to start from a section or --parent <uuid> to start from any Organizer parent. With --organizer_order, items follows the Organizer order and organizer folders include nested children. Combine --recursive with --organizer_order to include descendants in Organizer order. This Organizer-order mode only returns items that appear in the Organizer UI for that parent.

The hierarchy fields parent_id, parent_title, depth, index, and container_kind are included only when --organizer_order is specified.

Each asset object may include:

Field Type Description
id string Asset UUID
type string Asset object type
kind string Stable Curio asset kind for scripting, such as organizerfolder, organizersection, or image
asset_file_kind string Human-readable asset display/file kind, if applicable
title string Asset title
tags [string] Asset tags
note string Asset note text, if present
asset_file string Underlying file path, if the asset has one
section_path string Section hierarchy containing the asset
organizer_path string Organizer path under the containing section, if applicable
parent_id string UUID of the containing Organizer parent; only present with --organizer_order
parent_title string Title of the containing Organizer parent; only present with --organizer_order
depth number Hierarchy depth relative to the requested section or parent; only present with --organizer_order
index number Zero-based position within the containing Organizer parent; only present with --organizer_order
container_kind string Kind of Organizer parent containing the asset, such as section, folder, or ideaspace; only present with --organizer_order
added_date string Added date in YYYY-MM-DD or YYYY-MM-DDTHH:MM format
modified_date string Modified date in YYYY-MM-DD or YYYY-MM-DDTHH:MM format

JSON Output and Exit Codes

All commands print JSON responses. On success the response contains response_ok: true; on failure it contains response_ok: false plus an error dictionary.

A typical success response looks like this:

{
  "api_version": 1,
  "app_version": "25.1",
  "response_ok": true,
  "result": {
    "items": [
      {
        "id": "fig-abc",
        "title": "Write docs",
        "priority": 4
      }
    ]
  }
}

Exit codes are:

  • 0 for success
  • 1 for an API or runtime error
  • 2 for invalid command line usage

Common Errors

Error Meaning
NoSelection Nothing is selected
MultipleSelection More than one figure is selected when a single figure is required
SelectionNotTextCapable The selected figure does not support text for the requested operation
FigureNotFound The requested UUID or identifier could not be found
ReadOnlyField You tried to write a read-only field
ReadOnlyTransport You tried to write through a read-only transport
NotActivated Curio needs to be launched to refresh CLI activation
InvalidRequest The command or supplied values were not valid, or an identifier matched multiple targets
InternalError An unexpected internal failure occurred

Tip

If you are scripting against the CLI, check the response_ok field in the JSON response and the process exit code.

Troubleshooting

If a command says it cannot connect, Curio is not running and the command requires the live app. Launch Curio and try again.

If --project mode returns NotActivated, launch Curio once so it can refresh the CLI activation token.

If a selection-based command fails, confirm that the correct project window is frontmost and that the expected figures or Organizer items are selected.