
GhostPaw Questlog
io.github.GhostPawJS由 GitHub 账号 GhostPawJS 发布v0.13.0更新于 Nov 5, 2026
Local tasks, calendar commitments, and recurring work.
概览
本地 SQLite 任务与日历服务器,让助手捕获、规划、执行并完成带有书面结果的任务。
- 可以做什么
- 搜索与查看日志:跨实体全文搜索、按可用/逾期/即将到期等视图筛选,并查看单个条目的详情
- 捕获与整理工作:记录待定线索,创建任务与任务线,把线索落实为结构化工作
- 规划与执行任务:设置截止、推迟与排期时间,开始、完成、放弃或记录投入,并校验前置解锁条件
- 组织与分类:在任务线之间移动任务、管理重复模板、打标签、附加或领取奖励、归档或软删除
- 通过专用工具维护重复性工作与奖励生命周期
- 适用场景
- 适合希望助手在本机维护长期个人任务与日历记录的场景,把对话内容变成可追踪的承诺,只有写下结果才算完成,也适用于重复性工作和前置依赖链。
- 运行要求
- 以本地 stdio 进程运行,可用发布版二进制或 npm 包(需 Node 24 及以上)。数据默认存放在 ~/.ghostpaw/questlog.db 的 SQLite 文件中,可通过 GHOSTPAW_QUESTLOG_DB 环境变量或 --db 路径更改。未声明需要账号或 API 密钥。
安装
在 SourceWeft 中
- 打开 控制台中的 GhostPaw Questlog,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
[GhostPaw questlog: Your agent said it was done. Was it?]
@ghostpaw/questlog
[npm] [CI] [site] [runtime deps] [MCP Registry] [node] [license]
Agent tasks as quests that finish only with a written outcome.
A unified task and calendar model for Node.js, built on SQLite.
Questlog treats tasks, events, deadlines, recurring commitments, and loose intake as one coherent data model instead of separate systems. It ships as a single prebundled blob with zero runtime dependencies, designed for two audiences at once: human developers working directly in code, and LLM agents operating through a structured tool facade.
MCP server
Every client below starts the same stdio server: ghostpaw-questlog mcp.
For npm-based environments, use npx -y @ghostpaw/questlog mcp (Node 24+).
Data lives in ~/.ghostpaw/questlog.db unless the GHOSTPAW_QUESTLOG_DB
environment variable (absolute path) or --db <path> says otherwise.
Claude Code
or as a plugin, which also installs the skill:
Codex CLI (~/.codex/config.toml)
Cursor (.cursor/mcp.json), Claude Desktop (claude_desktop_config.json)
or a project .mcp.json:
Claude Desktop users can also install server.mcpb from the
latest GitHub release.
A Dockerfile is included for container hosts:
docker build -t ghostpaw-questlog . && docker run -i --rm -v questlog:/data ghostpaw-questlog.
The server speaks MCP 2026-07-28 (stateless, server/discover) and the
initialize-based revisions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05.
CLI
Install the release binary for ghostpaw-questlog (questlog is an alias).
add accepts comma-separated tags (--tag a,b) and repeated --tag flags, --objective (defaults to the title),
--questline <id>, and --due as YYYY-MM-DD, DD.MM.YYYY, today, tomorrow,
+3d, an ISO date-time with timezone, or milliseconds since epoch. Date-only
values use local end of day.
--objective is the one flag that reads a file: @path, @- for stdin, and
@@text for a literal @text (help marks it (@file, @- stdin, @@ literal @)). Every
other value, including titles, --outcome and per-tool flags, is literal.
list --tag work --tag urgent requires all tags and supports quest views; unknown tags return an empty list.
list defaults to available quests; list --help lists all supported views.
Its --limit and --offset paginate text and JSON. JSON data includes total, offset, limit, and hasMore.
search --fts enables raw FTS5 syntax; search text is literal by default.
search --limit caps matches in both formats. show prints full quest detail.
Lists show local due dates, overdue markers, and recorded outcomes. Plain JSON
adds ISO UTC siblings for numeric timestamp fields ending in At.
done stores --outcome with the finished quest; without it the command asks for one and exits 3.
Revise a title with questlog quest revise <id> --title "New title".
Count filtered quests with questlog list --count-by tag|prefix.
Find similar open quest titles with questlog list --view quests.duplicates.
Commands print text by default, including hooks, delivery views and each watch tick; call and direct tool commands return the raw tool result as JSON. Use --json for the full tool result
and --compact for compact JSON. --db path works before or after the command.
Each command accepts --help. Exit codes are 0 for success, 1 for invalid input
or a tool error, 2 for usage errors, and 3 when clarification is needed or a quest, delivery, or hook target is not found.
An empty hook list prints No hooks ([] with --json). Delivery text timestamps use local time; JSON retains UTC/epoch timestamps. hook label names the database, not an individual target.
questlog skill --short prints the compact cheat sheet; questlog skill --list lists guides.
ISO date-times without a zone (for example 2026-10-29T09:00) use the local time zone.
The call command and the per-tool form still reach every tool and parameter:
questlog mcp starts the stdio server.
The default database is ~/.ghostpaw/questlog.db. Override it with --db <path>
or GHOSTPAW_QUESTLOG_DB; top-level help shows the selected path. New database
files are reported on stderr. The npm entry requires Node 24+ and exits 2 with
an installation hint on older Node versions, including for help and version.
Agent Skill
SKILL.md (repo root) and skills/questlog/SKILL.md follow the
Agent Skills format and ship in the npm package.
Copy skills/questlog/ into your agent's skills folder, or print it:
Install
Release binary (default)
Each line downloads the latest release asset, checks it against the release’s SHA256SUMS and installs it on the PATH (~/.local/bin on Linux/macOS; the Windows script adds its folder to the user PATH).
These lines never edit ~/.profile or other shell startup files: export PATH applies to the current shell only. To keep it in new shells, use the ~/.profile line below.
linux-x64:
linux-arm64:
darwin-arm64:
darwin-x64:
windows-x64 (PowerShell; persistently adds its folder to the user PATH):
Pinned to a release:
Also adding ~/.local/bin to ~/.profile (edits ~/.profile once; skipped if it already mentions ~/.local/bin; zsh login shells read ~/.zprofile instead, so use that file name there):
To skip the persistent Windows user PATH edit (the installer still installs and prints the folder to add):
Scripts that compare versions should use --version --short or --version --json.
Standalone binaries are available from GitHub Releases.
A session with the 0.9.1 linux-x64 binary against a fresh database:
[questlog 0.9.1: --version, three add calls, list, search, done with an outcome, and show]
The same session as an animated GIF.
Other release installers:
For aqua, define a
github_release package in aqua.yaml:
questlog-registry.yaml:
Install scripts verify SHA256SUMS. To verify a downloaded archive's build attestation:
Set GHOSTPAW_VERIFY=attestation for attestation verification in install.sh.
Binaries are unsigned; macOS binaries carry an ad-hoc signature. For a browser
download on macOS, remove quarantine with
xattr -d com.apple.quarantine /path/to/ghostpaw-questlog.
Linux binaries require glibc 2.28+; use npx on Alpine.
See the binary build workflow.
npx / npm (for npm-based environments)
The npm package requires Node 24+:
Library (for harnesses embedding it in code)
See library usage. The library uses built-in node:sqlite with zero runtime dependencies.
Quick Start
Docs
The live demo runs the library in your browser against an in-memory SQLite database. Each view below opens a different part of it:
- Dashboard: open, available, overdue and pending work
- Intake: capture rumors and triage them into quests
- Quests: start, block and finish quests with an outcome
- Planning: questlines and scheduling
- Search: full-text search across the log
The Model
Seven concepts, strict separation of concerns:
The unified model means one entity type covers every temporal intention:
State is derived, not toggled. A quest's availability comes from its lifecycle, timing fields, and unlock graph — computed at read time, never stored as a status flag.
Lifecycle at a glance
Questlog computes WoW-style markers on every read. They change as work moves through its lifecycle:
Intake
Quest progression
Other markers
Marker IDs are semantic strings (attention.available, progress.complete, ...) computed at read time, never stored. The markers namespace maps each to its symbol, color, label, and CSS class for consistent rendering across HTML, TTY, and plain text.
Two Audiences
Human developers
Use the read and write namespaces for direct-code access to every domain operation:
See HUMAN.md for the full human-facing guide with worked examples.
LLM agents
Use the tools, skills, and soul namespaces for a structured runtime surface designed to minimize LLM cognitive load:
Every tool returns a discriminated result with outcome: 'success' | 'no_op' | 'needs_clarification' | 'error', structured entities, next-step hints, and actionable recovery advice. No thrown exceptions to parse, no ambiguous prose.
See LLM.md for the full AI-facing guide covering soul, tools, and skills.
Tools
Twelve tools shaped around operator intent, not raw storage operations:
Each tool exports runtime metadata — name, description, JSON Schema, input descriptions, side-effect level — so agent harnesses can wire them without reading docs.
The run_quest tool refuses to start a quest with unmet unlock prerequisites and returns the blocking quests with inspection hints. Set force: true to start anyway with a warning. The library startQuest function remains permissive.
Key Properties
- Zero runtime dependencies. Only
node:sqlite(built into Node 24+). - Single prebundled blob. One ESM + one CJS entry in
dist/. No subpath exports, no code splitting. - Pure SQLite storage. FTS5 full-text search, CHECK-constrained state transitions, trigger-maintained indexes. Bring your own
DatabaseSyncinstance. - Derived state. Availability, blocking, deferral, overdue, and markers are computed at read time from fields and relationships, never stored as flags.
- Intention-shaped writes.
captureRumor,settleRumor,startQuest,finishQuest,abandonQuest— operations that say what happened, not generic CRUD. - RFC 5545 recurrence. Standard RRULE strings for recurring work. No custom recurrence format.
- WoW-style markers. Semantic marker IDs (
attention.available,progress.complete, ...) computed on every read, renderable to any channel. - Colocated tests. Every non-type module has a colocated
.test.tsfile. The behavior described in docs is backed by executable coverage.
Performance
Measured with npm run bench on Node 24.14.0, Linux, Intel Xeon (shared
cloud vCPU), 10,000 quests in a file-backed database:
The library search returns every match with a highlighted snippet, so a query
that matches the whole log pays for building all of those rows. Cold start
(process spawn to first response, median) is about 30 ms for --version and
the MCP server.
Package Surface
All domain types are also available at the root for TypeScript consumers:
Documentation
Development
The repo is pinned to Node 24.14.0 via .nvmrc / .node-version / .tool-versions / mise.toml / Volta. Use whichever version manager you prefer.
Support
If this package helps your project, consider sponsoring its maintenance:
Webhooks
Configure opt-in outbound wakes with the release binary. No server or scheduler is started. With no targets, tick makes no network calls. Targets and retry state live in the database.
Save the signing secret printed once by hook add (including its --json result).
--secret-stdin reads a supplied secret from standard input; there is no secret flag.
Secrets and custom header values are stored in the database. On POSIX, new database files
and their WAL/SHM siblings use mode 0600, and directories created for them use 0700.
Existing database permissions are preserved; Windows uses its existing access controls.
Prefer --header-stdin for real keys (one Name: value line per header), keeping
values out of shell history and process arguments:
questlog hook add https://example.org/wake --header-stdin < /secure/headers.txt.
Keep that file private (0600 on POSIX). Repeatable --header "Name: value" remains
available, but exposes values in process arguments.
Headers accompany every delivery and test. Header names are shown with values replaced by
***; values are never included in list, show, test, tick, watch, or tool output.
Names must be HTTP tokens; host, content-length, content-type, and x-questlog-*
are reserved (case insensitive). To change headers, remove the hook and add it again.
Use separate invocations for --header-stdin and --secret-stdin.
URL userinfo is rejected; use a custom header or query key instead.
questlog show d_… prints delivery status, attempts, HTTP status, next attempt,
redacted target URL, and event ids; add --json for JSON.
List output redacts URL userinfo and query strings. Removal deletes the target and its deliveries.
A target covers the database unless --tag restricts it to quests with that tag;
rumors have no tags and reach database targets only. --events defaults to all five events.
The label defaults to the database filename without directory or extension (questlog for memory).
Only use labels suitable for disclosure to the receiver.
For cron:
Cron's PATH may need $HOME/.local/bin/questlog tick --db /path/to/quests.db.
watch repeats tick (default 60 seconds, minimum 5), finishing its current tick on SIGINT/SIGTERM.
Tick exits 0 after running even when deliveries need retrying. Dry runs roll back all changes,
including repeatable materialization, and make no network calls.
Events are detected from the model at tick time:
quest.due: an unresolved, undeleted quest reaches its effective due time (owndue_at, otherwise its undeleted questline's due time).quest.overdue: that effective deadline is strictly earlier than now and the quest remains unresolved.quest.unblocked: an unresolved quest is available, all active prerequisites have succeeded or been deleted, and at least one prerequisite succeeded after its unlock was installed. Occurrence time is the latest active prerequisite success or not-before time, whichever is later.repeatable.spawned: a concrete repeatable instance was created; occurrence time is its creation time. Tick first materializes due anchors through the existing spawn operation.rumor.captured: an undeleted rumor was created; occurrence time is its creation time, even if subsequently settled or dismissed.
Each type, entity and occurrence timestamp has a persistent unique event key. Repeated ticks and restarts do not create another occurrence. Changes removed before any tick cannot be reconstructed. Occurrences earlier than target creation are excluded, preventing backlog floods. Tags are evaluated when assigning an event. Already assigned events retain their batch membership.
One POST batch per target per tick contains only identifiers, types, timestamps, and the DB label:
Headers are content-type: application/json, user-agent: questlog/<version>,
x-questlog-delivery: <deliveryId>, x-questlog-timestamp: <unix seconds>, and
x-questlog-signature: sha256=<hex HMAC-SHA256(secret, timestamp + "." + rawBody)>.
No titles, objectives, details, or tag text are sent. hook test sends a logged hook.test
event immediately, ignoring the min gap. Add and test are CLI-only in the tool facade;
manage_hooks supports list, remove, tick (with dry_run), and deliveries.
2xx delivers the batch. Requests time out after 5 seconds. Other responses, timeouts, and network errors retry after 30 seconds, 1 minute, 2 minutes, 4 minutes, and so on, capped at 1 hour, plus less than 1 second jitter. The target's min gap also applies to retries. Eight unsuccessful attempts mark a delivery failed. Retries retain the delivery id and events. Pending batches wait behind retries. Only the last 500 delivered entries per target are kept; pending and failed entries are retained. Transactions and two-minute leases prevent overlapping ticks from claiming the same delivery. A crash after receipt but before recording success can cause another request: receivers must dedupe by delivery id.
Verifying a delivery
Compute HMAC-SHA256 over timestamp + "." + rawBody with the secret and compare in constant
time. Reject timestamps older than 5 minutes (and timestamps too far in the future), then
dedupe on x-questlog-delivery. Use durable deduplication storage in a production receiver.
This 15-line Node example uses an in-memory set:
Repeatables accept an optional IANA time zone, such as Europe/Berlin, via
repeatableQuest.tz in manage_repeatable create input. Zoned RRULEs retain local
wall-clock time across DST. Omitted or null zones keep existing UTC behavior.
Ambiguous local times use the earlier instant; nonexistent times move forward.
The facade accepts action: "revise" (or "update") with
repeatableQuestId and tz; null clears the zone. Existing spawned quests are
unchanged. Invalid zones are rejected; the plain CLI exits 2.
Set GHOSTPAW_OUTPUT=json to select CLI JSON output as with --json.
Other values leave the default output unchanged.
When opening the default database, the CLI prints using default db <path> to stderr. Suppress this notice with --quiet or GHOSTPAW_QUIET=1.
Due selection and consumer claims
questlog due [--within 15m] [--tag work --tag team] [--limit 100] [--json]
selects open overdue/due quests and recurring occurrences through the inclusive
horizon (default 0m). Durations use integer m, h, or d; limits are 1–1000.
Tags require every named tag. JSON data contains items and hasMore.
Each item has kind, key, questId or repeatableId + occurrenceAt,
title, epoch-millisecond dueAt, overdue, and tags. Text prints one line per item: key, due status, local date/time (as in list/show),
then title and space-separated #tags, omitted when empty. For example:
The occurrence example uses Europe/Berlin local time. Recurring occurrences use the stored time zone and due offset (default zero), and retain their occurrence key after materialization. Resolved/deleted instances are excluded.
questlog due --claim worker atomically records consumer-specific claims;
reruns return only unclaimed items. Other consumers are independent.
Release with questlog due --release 12 --claim worker, or
questlog due --release occurrence:3:1792882920000 --claim worker using an item's key.
Release only removes the mark; a subsequent due call selects it again if still open.
Claims on resolved/deleted items need no cleanup.
questlog tick --claim worker [--within 2h] claims up to 100 due items and sends
one quest.due event per new claim through normal webhook batching/retries.
Its payload adds the item fields above and consumer; this opt-in payload includes
titles and tags. Plain tick retains its existing behavior. Dry-run rolls claims back.
The MCP/tool due accepts within, tags, limit, claim, and release;
it is marked as writing state because claim/release persist marks.
来源:README.md,提交 9e02b81
工具
0版本历史
5- v0.13.0最新Nov 5, 2026
- v0.12.0Nov 5, 2026
- v0.11.3Oct 30, 2026
- v0.11.1Oct 29, 2026
- v0.6.2Oct 25, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分