Capture
architect-capture: one quick-add parser, the composer, a capture window on a system-wide shortcut, the vault inbox and processing it, capture targets extensions add, CAPTURE_* and INBOX_*.
What it is and when to use it#
Every app needs to capture things, so capture is architect’s (#352), ported
from Task. A line goes in from the composer, the capture window, ⌘K, a menu,
the menu-bar item or an agent (CAPTURE_ADD). The quick-add parser reads
it: [[Project]], #tag, @context, !high, today / tomorrow / a
weekday / next fri / YYYY-MM-DD, and every week / every 3 days /
every weekday become properties, and the rest becomes the title. It lands
in the vault’s inbox as a note. Each capture comes back once, in the
inbox deck or through INBOX_*, and leaves in one of four ways:
- made into a target’s thing (a task, …);
- filed as a plain note;
- put off until a later day;
- discarded.
Extensions add what a capture can become with [[capture_targets]]. The
Tasks extension’s task is the first
(Extensions: capture targets).
A capture’s note keeps Task’s inbox frontmatter, so a vault Task wrote reads
the same. The demo vault’s convention (type: capture, captured,
processed: false) is read too:
---
type: inbox-item
status: open
source: window
created: 2026-11-05T23:00:21-08:00
due: 2026-11-06
priority: high
projects: ["[[Lab]]"]
tags: [design]
---
The lines typed after the first.
A minimal example#
use architect_capture::actions::{self, Config};
// The list already has the vault's VAULT_* (and, with extensions, EXT_CAPTURE_TARGETS).
let capturer = actions::register(&list, Config::default(), None)?;
list.run_json_async("CAPTURE_ADD", br#"{"text":"Call the venue tomorrow !high"}"#).await?;
With a window, architect_capture::ui::use_capture(&list, Config::default())
registers the same actions, with CAPTURE_OPEN and INBOX_OPEN opening the
composer and the deck. Mount CaptureLayer { capture } once over the window.
Code tour#
features/capture/src/parse.rsholds the parser.parse/parse_withreturn aDraft: the title, tags, contexts, projects, priority, due date,Repeatand extensions’extra.Draft::propertiesgivesTaskNotes’ keys (keys).mergelays hand-set chips over the parsed properties (a chip set by hand beats the text, and a hand-setnullremoves one).TokenRuleis an extension’s word, like Keyflow’skey:D.features/capture/src/inbox.rscovers inbox notes.note_forbuilds a capture’s note (the first line parsed, the rest the body).Item::from_notereads aVAULT_READanswer back.Item::is_duehandlesresurface_on.carrieddrops the inbox’s own keys when a capture leaves.suggests_taskis Task’skind_from_text.features/capture/src/target.rs:Target(the app’snote, then the registry’s), andCapture, what a target’s action is given.features/capture/src/actions.rs(featureactions) hasCapturer, the one path behind the actions, the composer and the deck. It writes only throughVAULT_*and runs each as the caller.registeris the entry point, withidsandOpener.features/capture/src/vocabulary.rs:Vocabulary, what the composer offers to pick from (people, projects, the vault’s tags as labels, contexts), read byCapturer::vocabularyfrom whichever ofTAGS_LIST,PROJECTS_LIST,TASKS_LISTandVAULT_LISTis on the list.features/capture/src/ui/mod.rs(featureui) hasuse_capture/CaptureUi(process_now,process) andCaptureLayer. The capture window is anarchitect_workspace::Popout::page, falling back to a card where there is no OS window.- The composer is Task’s, ported (#445), its look and behaviour kept:
features/capture/src/ui/composer.rsComposer(a full-screen sheet on a phone whose properties ride the keyboard as one scrolling bar, a card with its chips in a row on a desk;@people and contexts,#labels,[[Project]], dates, repeats and!priorityread live as chips, a chip set by hand winning; a More menu for labels, a due date, a repeat, sub-tasks and a link; the kind at the top a menu of the targets; “Create more”, ⌘↩),Hand,kind_from_text,resolved_kind; its chipsfeatures/capture/src/ui/chips.rs(StatusChip,PriorityChip,AssigneeChip,ProjectChip,LabelsChip) and their pickerfeatures/capture/src/ui/picker.rsPropertyPicker; quick add’s barfeatures/capture/src/ui/quick_add.rsQuickAdd; Task’s Tailwind as architect’s theme tokensfeatures/capture/src/ui/style.rsLook. - Processing is Task’s too:
features/capture/src/ui/process.rsProcessCard, one capture’s decision in twoModes, remembered on the device (capture-modeinARCHITECT_CONFIG_DIR). Fast is Task’s card: do it now (a task in progress through thetasktarget, its clock throughTIME_START), add to a project (TaskShape, the capture parsed into an editable title, project, contexts, due date and estimate), write a note in your own words under a parent, snooze (Soon, Maybe, Someday: 1, 7 and 30 days), keep as reference, a project (PROJECTS_CREATE), already done (Capturer::done), delete. Clarify asks first: is it actionable? Then the next step (do it now, a task, waiting on someone, a project) or keep it (a note, someday, delete).ProcessDeck(INBOX_OPEN) deals the inbox one card at a time;ProcessNowSheetis “Process now” from the composer.Origin,OriginTileandagoare for an inbox list’s rows (the navigator’s Inbox view, #443). features/capture/src/shortcut.rs(featurenative, desk only) hasuse_global_shortcut(global-hotkey, registered on the event loop’s thread as macOS requires) anduse_float_window(the window over every app, a third of the way down the screen).apps/ui/src/capture.rswires it into the Architect app:use_app_capture, ⌃⌥N by default (ARCHITECT_CAPTURE_SHORTCUTnames another), andWINDOW_COMMANDfor the menu-bar item.apps/ui/src/lib.rsputs ⇧⌘N (LAB_CAPTURE), the feather and File › Process inbox on it.
| action | what it does |
|---|---|
CAPTURE_OPEN {text?, target?, window?} | opens the composer, or with window the capture window |
CAPTURE_ADD {text, properties?, target?, source?} | captures into the inbox, or straight into a target |
CAPTURE_PARSE {text} | the title, properties and suggested target, writing nothing |
CAPTURE_TARGETS | the app’s note, then every [[capture_targets]] |
CAPTURE_CLOSE | puts the composer and the deck away (a tour’s setup between chapters) |
INBOX_OPEN | opens the deck |
INBOX_LIST {all?} | the captures waiting, oldest first |
INBOX_PROCESS {path, target, title?, properties?} | makes it target’s thing; it leaves the inbox |
INBOX_FILE {path, folder?} | files it as a plain note |
INBOX_DEFER {path, until?} | puts it off (a date or a quick-add day; tomorrow when unset) |
INBOX_DISCARD {path} | deletes it (destructive: an agent’s call waits for a yes) |
An INBOX_* only reaches notes directly in the inbox folder. When a capture
becomes a target’s thing, its inbox note is removed through the app’s door:
that removal is the move’s other half, not a deletion the caller asked for.
Tests to read#
features/capture/src/parse.rs,features/capture/src/inbox.rs,features/capture/src/target.rs: the parser (the issue’s[[Lab]] tomorrow !high #design), hand-set chips, extension tokens, and reading notes back.features/capture/tests/inbox.rs: the actions over a real vault folder with a made-up target. It covers capture, list, process, file, defer and discard, each checked in the markdown.extensions/tasks/tests/vault.rs: the real Tasks extension, linked in and as its process. An inbox capture processed into a task is checked on disk.features/extensions/tests/interop.rscapture_targets_are_registered_while_loaded.apps/sandbox/media/tests/architect_tours.rs: the capture tour (architect_capture::TOUR,features/capture/tours/capture-tour.styx: the composer, Into, the deck) played over the Architect app.
Status#
Done:
- the parser, shared with Tasks (
TASKS_ADD); - the inbox and its actions;
[[capture_targets]]and thetasktarget;- the composer and the deck;
- the capture window on a system-wide shortcut, from the menu-bar item and
CAPTURE_OPEN.
Next:
- inline pickers for
@and#, and a project picker from the vault’s projects; - the phone’s sheet with the chips on the Typing Toolbar;
- the Board’s target in the sandbox;
- daily-note and project targets;
- the shortcut as a setting;
- the iOS share sheet and widget.
Linked from
- FeaturesOne page per major architect feature: what it is, the least code to use it, a tour of its code, the tests to read, and its status.
- TasksHow the Tasks extension is built: tasks as vault notes in TaskNotes' shape, reached through the host service; its list, Today, My tasks and a kanban view type for Bases; the architect.tasks service.
- Extensions and scriptsAdding to an app at runtime, without rebuilding it: data-only extensions, WASM components over a versioned WIT world drawn from the Action List, Luau scripts for macros, out-of-process plugins on a desk — with capabilities, and views as frame documents.