AgentSkillsCN

things:jxa

读取并查询Things 3中的数据(列表、待办事项、项目、标签、日志簿)。此工具不支持写入操作——如需创建或更新数据,请使用things:url;若要快速收纳内容,则可直接使用things:inbox。

SKILL.md
--- frontmatter
name: things:jxa
description: Read and query Things 3 data (lists, todos, projects, tags, logbook). Not for writes — use things:url to create/update, things:inbox for quick captures.
allowed-tools: ["Bash(osascript -l JavaScript ${CLAUDE_PLUGIN_ROOT}/scripts/jxa/*:*)", "Bash(bun ${CLAUDE_PLUGIN_ROOT}/scripts/format-output.ts:*)", Read]

Things JXA

Read and query Things 3 data via JXA. Queries use a pipeline: osascript -l JavaScript <jxa> <args> | bun <root>/scripts/format-output.ts [--json] [--columns name,status] [--count-prefix "completed items"]

<root> is ${CLAUDE_PLUGIN_ROOT}.

Scripts

ScriptUsageDescription
find-todos.js<tag|project> <name> [--logbook]Find todos by tag (across Inbox/Today/Anytime/Upcoming/Someday) or project
query-list.js<list-id>Query todos from any built-in list
query-logbook.js<start-iso> <end-iso>Query logbook with early termination. Full scans of 10k+ items are slow.
query-metadata.js<projects|areas|tags>List projects, areas, or tags (tags omit todoCount for performance)
export-markdown.jsosascript <root>/skills/jxa/scripts/export-markdown.js [list-id]Export a list to markdown checklist

query-logbook.js

Compute ISO dates in the shell:

bash
osascript -l JavaScript ${CLAUDE_PLUGIN_ROOT}/scripts/jxa/query-logbook.js "$(date -v-7d -u +%Y-%m-%dT%H:%M:%SZ)" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" | bun ${CLAUDE_PLUGIN_ROOT}/scripts/format-output.ts --count-prefix "completed items"

Built-in List IDs

TMInboxListSource (Inbox), TMTodayListSource (Today), TMNextListSource (Anytime), TMCalendarListSource (Upcoming), TMSomedayListSource (Someday), TMLogbookListSource (Logbook)

Repeating Tasks

Detect via midnight heuristic: creationDate at T00:00:00 local time = repeating instance. Templates have activationDate: null. See troubleshooting.md for examples.

Inline JXA

For one-off queries: osascript -l JavaScript -e '...'. JXA arrays lack .map()/.filter() — use for-loops.

Status Values

open, completed, canceled

Reference

Tips

  • Use properties() for batch reads instead of individual getters
  • open -g -a "Things3" to launch Things if not running