OpenPlanner is a local-first planning runtime for agent-facing calendar and task
workflows. It ships an installed openplanner JSON runner, an Agent
Skills-compatible skill, and SQLite-backed local storage.
Tell your agent:
Install OpenPlanner from https://github.com/yazanabuashour/openplanner.
Complete all required steps before reporting success:
1. Install and verify the openplanner runner binary with `openplanner --version`.
2. Verify the planning runner with `printf '%s\n' '{"action":"validate"}' | openplanner planning`.
3. Register the OpenPlanner skill from skills/openplanner/SKILL.md using your native skill system.
The agent should install the openplanner runner and place the
skills/openplanner skill where that agent normally loads skills. OpenPlanner
does not require one canonical skill path: Codex, Claude Code, OpenClaw, Hermes,
and other Agent Skills-compatible agents each manage skill locations in their
own way.
A complete local agent-use install has three parts:
openplanner --versionsucceeds.printf '%s\n' '{"action":"validate"}' | openplanner planningreturns unrejected JSON.- The matching skill is registered from
skills/openplanner/SKILL.md,https://github.com/yazanabuashour/openplanner/tree/<tag>/skills/openplanner, oropenplanner_<version>_skill.tar.gz.
Tell your agent:
Upgrade OpenPlanner from https://github.com/yazanabuashour/openplanner.
Complete all required steps before reporting success:
1. Upgrade and verify the openplanner runner binary with `openplanner --version`.
2. Verify the planning runner with `printf '%s\n' '{"action":"validate"}' | openplanner planning`.
3. Re-register the OpenPlanner skill from skills/openplanner/SKILL.md using your native skill system.
The runner and skill should come from the same tag or checkout.
Until the first release tag is published, build the runner from a checkout:
go build -o ./bin/openplanner ./cmd/openplannerPut that binary on PATH, then install or copy skills/openplanner using your
agent's skill installation workflow. The portable skill payload is the folder
containing SKILL.md; agent-specific directories are intentionally not part of
OpenPlanner's release contract.
After v0.1.0, release archives will include platform builds of the
openplanner runner, install.sh, and an openplanner_<version>_skill.tar.gz
archive for manual skill installation. The release installer installs and
verifies only the runner; skill registration remains delegated to the target
agent's native skill system.
curl -fsSL https://github.com/yazanabuashour/openplanner/releases/latest/download/install.sh | shOptional per-agent examples are in docs/agent-install.md. Those examples are not the OpenPlanner install contract.
Use OpenPlanner locally by installing the runner on PATH, registering the
matching skill with your agent, and letting the runner use its default SQLite
path at ${XDG_DATA_HOME:-~/.local/share}/openplanner/openplanner.db. For an
isolated or test planner, set OPENPLANNER_DATABASE_PATH=<database-path> before
agent runs or pass openplanner planning --db <database-path> during manual
checks. OPENPLANNER_DATABASE_PATH is the only supported environment override
for runtime storage; future runtime config belongs in the local database instead
of additional environment variables.
The local agent-use runner/skill gate passed the current 39-scenario production
suite with recommendation ship_openplanner_runner_local_agent_use:
docs/agent-eval-results/op-runner-2026-04-22-local-agent-use-final.md.
OpenPlanner's v1 product surface is the installed openplanner planning JSON runner
plus the portable skills/openplanner payload. Agents should integrate
through that runner and skill rather than importing repository packages.
The internal/runner, internal/service, internal/store, and domain packages are
implementation boundaries that support the runner. They are not public extension points
and do not carry SDK compatibility promises.
A public SDK, REST API, OpenAPI contract, hosted service, package registry, and web UI are not v1 product deliverables unless a future roadmap issue explicitly reapproves them.
The skill calls the installed runner:
printf '%s\n' '{"action":"list_agenda","from":"2026-04-16T00:00:00Z","to":"2026-04-17T00:00:00Z"}' \
| openplanner planningThe runner reads structured JSON from stdin, validates and normalizes the
request, performs the local planning operation, and writes structured JSON to
stdout. By default, it stores SQLite data at
${XDG_DATA_HOME:-~/.local/share}/openplanner/openplanner.db. Override the path
with OPENPLANNER_DATABASE_PATH or openplanner planning --db <path>; --db
wins when both are present. Runtime configuration beyond the database path is
stored in the SQLite database, not in separate environment variables. See
docs/local-data-backup.md
for backup, restore, and recovery verification guidance for local data, and
docs/local-data-security.md for the local
planning data security model.
Supported routine actions are:
ensure_calendarcreate_eventcreate_taskupdate_calendarupdate_eventupdate_taskdelete_calendardelete_eventdelete_taskcreate_event_task_linkdelete_event_task_linklist_event_task_linkscancel_event_occurrencereschedule_event_occurrencecancel_task_occurrencereschedule_task_occurrencelist_agendalist_eventslist_taskscomplete_tasklist_pending_remindersdismiss_reminderexport_icalendarimport_icalendarvalidate
Update actions use patch semantics: omitted fields are preserved, non-null
fields are set, and null clears clearable optional fields. Use event_id for
update_event, task_id for update_task, and exactly one of calendar_id or
calendar_name for update_calendar.
Recurring events and tasks support occurrence-level cancellation and timing-only
reschedules without changing the base recurrence rule. Use occurrence_at for
timed occurrences and occurrence_date for all-day events or date-based tasks.
Agenda entries keep a stable occurrence_key based on the original occurrence;
use that key with complete_task when completing a moved recurring task.
Timed events may include time_zone with an IANA timezone name such as
America/New_York. The start_at, end_at, occurrence_at, and replacement
timed fields still must be strict RFC3339 values, and their numeric offsets must
match the named zone. Timezone-aware recurring events keep their local wall-clock
time across DST transitions. All-day events remain date-only and do not accept
time_zone.
{"action":"cancel_event_occurrence","event_id":"<event-id>","occurrence_at":"2026-04-17T09:00:00Z"}
{"action":"reschedule_event_occurrence","event_id":"<event-id>","occurrence_at":"2026-04-18T09:00:00Z","start_at":"2026-04-19T11:00:00Z"}
{"action":"create_event","calendar_name":"Work","title":"Weekly sync","start_at":"2026-03-03T09:00:00-05:00","time_zone":"America/New_York","recurrence":{"frequency":"weekly","count":2}}
{"action":"cancel_task_occurrence","task_id":"<task-id>","occurrence_date":"2026-04-17"}
{"action":"reschedule_task_occurrence","task_id":"<task-id>","occurrence_date":"2026-04-18","due_date":"2026-04-19"}
{"action":"complete_task","task_id":"<task-id>","occurrence_key":"<key-from-list-agenda-result>"}Events support optional attendee metadata through attendees. Each attendee
requires email; optional fields are display_name, role, participation_status,
and rsvp. role defaults to required and accepts required, optional,
chair, or non_participant. participation_status defaults to
needs_action and accepts needs_action, accepted, declined, tentative,
or delegated. Duplicate attendee emails on one event are rejected
case-insensitively.
The event time_zone field maps to iCalendar TZID during export and import.
The runner supports iCalendar export with export_icalendar and import with
import_icalendar.
{"action":"export_icalendar"}
{"action":"export_icalendar","calendar_name":"Work"}
{"action":"import_icalendar","content":"BEGIN:VCALENDAR\r\nVERSION:2.0\r\n..."}
{"action":"import_icalendar","calendar_name":"Work","content":"BEGIN:VCALENDAR\r\nVERSION:2.0\r\n..."}The export action returns an icalendar object with content_type, filename,
optional calendar metadata, event_count, task_count, and content. The
content value is complete .ics text; the runner does not write files
directly.
The import action accepts complete .ics text in content; it does not read
files directly. It imports supported VEVENT and VTODO fields, recurrence,
occurrence exceptions, reminders, attendees, task status, priority, and tags.
Repeat imports update existing rows by iCalendar UID within the target
calendar. The result includes icalendar_import counts for calendars, events,
tasks, created rows, updated rows, skipped rows, and component skip reasons.
{"action":"create_event","calendar_name":"Work","title":"Planning","start_at":"2026-04-16T09:00:00Z","attendees":[{"email":"alex@example.com","display_name":"Alex Rivera","role":"required","participation_status":"accepted","rsvp":true}]}
{"action":"update_event","event_id":"<id-from-prior-runner-result>","attendees":null}Tasks support optional metadata. priority is one of low, medium, or
high and defaults to medium. status is one of todo, in_progress, or
done and defaults to todo. tags is an array of lowercase labels using
letters, digits, _, or -; list_tasks matches all supplied tags when
filtering.
Events and tasks can be linked explicitly for prep, follow-up, and agenda-based
completion workflows. Use create_event_task_link with event_id and
task_id, list_event_task_links with optional event_id and/or task_id,
and delete_event_task_link with both IDs. Event responses include
linked_task_ids; task responses include linked_event_ids; agenda event and
task items include the corresponding linked IDs.
{"action":"create_event_task_link","event_id":"<event-id>","task_id":"<task-id>"}
{"action":"list_event_task_links","event_id":"<event-id>"}
{"action":"delete_event_task_link","event_id":"<event-id>","task_id":"<task-id>"}Events and tasks support optional reminder rules through reminders, an array
of objects with positive before_minutes values. Reminder offsets are measured
before the event start or task due time. Use list_pending_reminders with
from and to RFC3339 bounds to query pending reminder occurrences, including
expanded recurring occurrences, and use dismiss_reminder with the returned
reminder_occurrence_id to dismiss an occurrence idempotently.
{"action":"create_task","calendar_name":"Personal","title":"Take medicine","due_at":"2026-04-16T10:00:00Z","reminders":[{"before_minutes":60}]}
{"action":"list_pending_reminders","from":"2026-04-16T08:00:00Z","to":"2026-04-16T10:00:00Z","limit":10}
{"action":"dismiss_reminder","reminder_occurrence_id":"<id-from-list-pending-reminders-result>"}Delete actions use event_id for delete_event, task_id for delete_task,
and exactly one of calendar_id or calendar_name for delete_calendar.
Calendar deletion is empty-calendar-only and never cascades to contained events
or tasks.
Install the pinned toolchain with:
mise installExercise the JSON runner with:
mise exec -- go build -o ./bin/openplanner ./cmd/openplanner
./bin/openplanner --version
printf '%s\n' '{"action":"validate"}' | ./bin/openplanner planningRun the local quality gates with:
mise exec -- make checkmake check runs formatting validation, Agent Skills validation, the Go test
suite, govulncheck, and golangci-lint.
The 0.1.0 release deliverables are:
- platform archives for the
openplannerrunner binary - the single-file
openplannerskill archive - a canonical source archive, SHA256 checksums, an SPDX SBOM, and GitHub attestations for release verification
Until v0.1.0 exists, local development should build the runner from a checkout
or install from main.
- CONTRIBUTING.md explains how outside contributors should propose changes.
- SECURITY.md explains how to report vulnerabilities privately and what response timing to expect.
- docs/maintainers.md documents Beads-based maintainer workflow and repo administration notes.
- docs/release-verification.md explains the published release assets and how to verify them.
- docs/local-data-backup.md explains backup, restore, and recovery checks for local OpenPlanner data.
- docs/local-data-security.md documents the local data threat model and parser hardening follow-ups.
- docs/security-operations.md defines recurring security review, advisory rehearsal, and high-risk surface review expectations.
- docs/agent-evals.md explains how to evaluate production agent workflows.
- internal/runner contains the JSON-friendly task facade for production agent workflows.
- cmd/openplanner contains the installed JSON runner.
- skills/openplanner/SKILL.md is the portable Agent Skills-compatible OpenPlanner skill.
- LICENSE defines the project license.
Outside contributors can work entirely through GitHub issues and pull requests. Beads is maintainer-only workflow tooling and is not required for community contributions.
See CONTRIBUTING.md for contribution expectations and CODE_OF_CONDUCT.md for community standards.