duecard
A dated card with a pointer. Call the CLI. Do not scrape human output. Do not invent cards.
Prerequisite
command -v duecard
If missing, tell the human to install the CLI (npm install -g duecard). Do not write ~/.duecard/cards.jsonl by hand. Do not invent a fallback store.
Override the store with DUECARD_HOME (default ~/.duecard).
Invoke
Always pass --json. Never wait for stdin. Store a pointer (URL, session id, or path).
duecard <command> [args] --json
| Exit | Meaning |
|---|---|
| 0 | Success, and (for due / list / show) at least one card |
| 1 | Success, nothing due / nothing found |
| 2 | Hard error (bad argv, IO, invalid JSONL) |
Stdout is only JSON. Errors live in { "ok": false, "error": "..." }. Stderr is silent unless --verbose.
Commands
duecard add <title> --due <when> [--url|--waku|--grok|--path|--cursor|--claude|--codex <ptr>] [--why "..."] --json
duecard due --json
duecard list [--status open|done|dropped] --json
duecard show <id> --json
duecard done <id> --json
duecard drop <id> --json
duecard snooze <id> <when> --json
duecard open <id> --json
--due / snooze <when>: now, 2h, 1d, 3d, 2026-08-16 (local 09:00), or an ISO timestamp.
Use only one pointer flag. Ids are the only handle (dc_01, …). Unique prefixes work. Titles are not unique.
Snooze keeps open and moves due. Drop is “I do not want this.” Done is “I checked.”
Capture
Capture is opt-in.
- Offer one card when the last ask is clearly deferred, then wait for accept.
- Never dump a list of idle sessions.
- Never scan transcripts, plans, or chat JSONL to infer unfinished work.
- Never invent cards.
Session start
If you surface due cards at session start, run only:
duecard due --json
Print at most 3 titles. If count is 0 (exit 1), stay quiet.
A host-specific SessionStart hook is optional and separate from this skill. The hook still calls duecard due --json.
duecard due --json
{
"ok": true,
"now": "2026-08-15T11:20:00+10:00",
"count": 1,
"cards": [
{
"id": "dc_01",
"title": "Check early stats on the open-source algo post",
"why": "11 impressions in minutes; see if it died or kept going",
"due": "2026-08-15T18:00:00+10:00",
"pointer": { "type": "url", "value": "https://x.com/brooksy4503/status/2088193435140518024" }
}
]
}
Field names
Stable. Do not rename.
Card: id, title, why, due, status (open | done | dropped), pointer (type + value or null), source, created_at, updated_at, snooze_count.
pointer.type: url | waku | grok | path | cursor | claude | codex.
Gotchas
- Exit 1 is success with an empty result, not a failure.
- Do not parse the human table. Always
--json. - Do not open or summarize the pointed-at thing unless the user asks (
duecard openor they want the URL). - Do not rewrite
why.