Build Drafts Pro
YESreplaces $1.67/mosaves $20.04/yrback to the verdict
A capture surface whose only hard requirement is that it appears the instant you ask for it, plus a scriptable action system that sends the captured text onward, with a queue so an action failing never costs you what you wrote.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree
Why Runs the application and the action sandbox.
Get it nodejs.org, or nvm install 22. open ↗
Verify
node --version prints v22 or higher - installfree
Why Everything depends on the window appearing instantly from anywhere, and this is platform-specific work.
Get it Whatever your desktop framework provides, and check it works when another application is fullscreen.
Verify
The hotkey fires from a fullscreen application and the window appears above it - have readyfree
Why The queue and retry behaviour are only testable against something that can actually be unreachable.
Get it A note-taking service, a task tool, or a webhook endpoint you control. One is enough.
Verify
An action posts to it successfully and queues when it is unreachable - decidefree
Why It is the primary requirement, and a threshold you did not write down becomes whatever the implementation happens to do.
Get it Pick a number in milliseconds you would notice, and measure against it from phase 1 rather than at the end.
Verify
A number is written down and the measurement is in the test output
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- drafts(id, body, created_at, updated_at, state, source) · state is inbox, archived or trashed - tags(draft_id, tag) · assigned by hand or by an action - actions(id, name, script, hotkey, requires_network, enabled) - runs(id, draft_id, action_id, started_at, ended_at, status, output, error) - queue(id, draft_id, action_id, attempts, next_attempt_at, delivered_at, last_error) - versions(draft_id, ordinal, body, at) · because a destructive action should never be the only copy - A draft is never deleted by an action succeeding, which is what makes running actions safe.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
DB_PATH | required | ~/.local/share/drafts/drafts.db | Every draft ever captured, including archived ones. Back it up. |
CAPTURE_HOTKEY | required | Cmd+Shift+Space | The global hotkey. Choose one nothing else claims, which is harder than it sounds. |
MAX_CAPTURE_DELAY_MS | required | 120 | The threshold that fails the build. The primary requirement made checkable. |
ACTION_DIR | required | ~/.config/drafts/actions | Action scripts. Imported ones sit here disabled until you enable them. |
SYNC_REMOTE | optional | s3://my-drafts/store | Phase 5 only. Absent means one machine, which is a fine way to run. |
The build, in order
A box that is already there
The hotkey produces a cursor in an empty box with no perceptible delay.
Show a built window, do not build one. The first capture is the one that matters.
Files
src/window.tsKeypress to typeable, logged. A number, not an impression.
Files
src/metrics.tsKilling the process mid-word must lose nothing.
Files
src/persist.ts
done when · tick each as it passeswatch out- Creating the window on the hotkey means the first capture of a session takes a second or more, which is exactly long enough for the thought to be gone, and it is the failure the whole tool exists to prevent. Keep a window warm and show it, rather than building one.
Actions that do something with the text
One keystroke sends the draft somewhere useful.
Body, tags, a few operations. Small is what keeps it sandboxable.
Files
src/api.tsDeclared capabilities only. Test that an undeclared access fails.
Files
src/sandbox.tssrc/sandbox.test.tsOutput and error. Debugging an action without the record is guesswork.
Files
src/runs.ts
done when · tick each as it passeswatch out- Running action scripts with the application's full privileges means one copied script can read every file you own, and people copy scripts from forums constantly. Sandbox by default and require an action to declare network or filesystem access explicitly, which also makes the queue decision in phase 3 possible.
Nothing lost when the destination is down
An action sending somewhere unreachable retries instead of failing you.
The declaration from phase 2 is what makes this automatic.
Files
src/queue.tsThen surface as failed rather than retrying forever.
Files
src/worker.tsDelivery is not deletion. The archive is what makes capture safe.
Files
src/drafts.ts
done when · tick each as it passeswatch out- An action that posts to a service and reports success on a request that was never acknowledged loses the note quietly, and you find out when you go looking for something you are sure you wrote down. Only mark delivered on a confirmed response, and keep the draft regardless.
Finding what you captured
Six months of captures are searchable in the time it takes to type.
State is a filter, not a boundary. Archived is where things live.
Files
src/search.tsAt ten thousand drafts. Anything slower breaks the habit.
Files
src/search.tsSo an action that rewrote a draft did not hide the original.
Files
src/versions.ts
done when · tick each as it passeswatch out- Excluding archived drafts from search makes the archive worthless, and archived is where almost everything ends up. Search everything by default and let state be a filter rather than a boundary.
Two machines and a shared action libraryproduct builder
Drafts and actions follow you, and a shared action is inspected before it runs.
Drafts and actions. Capture data should not require a service.
Files
src/sync.tsAn imported action is arbitrary code. Read it before it runs.
Files
src/import.tsAn update that adds network access is a new decision.
Files
src/import.ts
done when · tick each as it passeswatch out- An imported action that runs before you read it is arbitrary code execution with a friendly name, and action libraries are exactly how people share these. Show the source and declared capabilities, require an explicit enable, and re-prompt when an updated action changes what it declares.
That is the whole plan for Drafts Pro. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Mobile capture.
- Dictation and voice capture.
- The large community action library.
- Rich text and attachments.
- its iPhone and Mac capture speed, action directory, and Apple automation depth
- cross-device sync
- large proprietary style models
- browser and office-suite extensions
- team style guides
- Actions chained into a workflow, once single actions are reliable
- Templates that pre-fill a capture for a recurring kind of note
- A daily digest of what you captured, which is where an archive starts being read
Need the files? The project pack on the verdict page hands your agent the whole brief · more writing tools.