Data format

Both projects and tasks are markdown files with YAML frontmatter. This page documents every key the plugin writes, what type it holds, and when it appears.

If you want to hand-edit, script against, or migrate your data — this is the contract.

Project file

Path: <projectsFolder>/<Project title>.md. Frontmatter marker: pm-project: true.

Frontmatter schema

KeyTypeAlways presentNotes
pm-projectbooleanyesAlways true. The marker.
idstringyesStable project ID.
titlestringyes
descriptionstringyesEmpty string if unset.
colorstringyesHex color, e.g. #5ba0e2.
iconstringyesEmoji.
taskIdsstring[]yesTop-level task IDs, in display order.
customFieldsarrayyesSee Custom field definitions below. Empty array if none.
teamMembersstring[]yesPer-project assignee list. Empty if none.
savedViewsarrayyesSee Saved views below. Empty if none.
createdAtstringyesISO 8601 timestamp.
updatedAtstringyesISO 8601 timestamp.

Example

---
pm-project: true
id: "p_a4f3c1"
title: "Website Redesign"
description: "Q3 site refresh"
color: "#5ba0e2"
icon: "🎨"
taskIds:
  - "t_111111"
  - "t_222222"
customFields:
  - id: "contract_value"
    name: "Contract value"
    type: "number"
teamMembers:
  - "Stepan"
  - "Jason"
savedViews:
  - id: "v_a1b2"
    name: "My open items"
    filter:
      text: ""
      statuses: ["todo", "in-progress"]
      priorities: []
      assignees: ["Stepan"]
      tags: []
      dueDateFilter: "any"
      showArchived: false
    sortKey: "due"
    sortDir: "asc"
    viewMode: "table"
createdAt: "2026-05-01T10:00:00.000Z"
updatedAt: "2026-05-23T14:31:02.000Z"
---

# 🎨 Website Redesign

Q3 site refresh

## Tasks
- [[audit-current-site|Audit current site]]
- [[new-homepage-copy|New homepage copy]]

Task file

Path: <projectsFolder>/<Project title>_tasks/<slug>.md. Frontmatter marker: pm-task: true.

File naming

<slug>.md, where the slug is the title — lowercased, non-alphanumeric stripped, hyphenated, max 40 characters.

Example: audit-current-site.md.

Slug collisions within the same project are rejected: the task modal shows an inline error and won’t save until the title is changed. Tasks created before plugin version 1.5 keep their <slug>-<short-id>.md filenames until the title changes or the file is renamed.

Frontmatter schema

KeyTypeAlways presentNotes
pm-taskbooleanyesAlways true. The marker.
projectIdstringyesThe owning project’s ID.
parentIdstring | nullyesParent task’s ID, or null for top-level.
idstringyesStable task ID.
titlestringyes
typestringyes"task" or "milestone".
statusstringyesStatus ID (must exist in settings or it’ll remap on next load).
prioritystringyes"critical", "high", "medium", "low".
startstringyesYYYY-MM-DD or "" for unset.
duestringyesYYYY-MM-DD or "" for unset.
progressnumberyes0–100.
assigneesstring[]yesNames. Empty array if none.
tagsstring[]yesFree-form tags. Empty if none.
subtaskIdsstring[]yesDirect children’s IDs.
dependenciesstring[]yesIDs of tasks this task is blocked by.
collapsedbooleanyesWhether the subtask tree is collapsed in the UI.
createdAtstringyesISO 8601 timestamp.
updatedAtstringyesISO 8601 timestamp.
recurrenceobjectnoSee Recurrence below. Omitted if not set.
timeEstimatenumbernoHours. Omitted if unset.
timeLogsarraynoSee Time logs below. Omitted if empty.
customFieldsobjectnoPer-field values. Omitted if empty.

The markdown body of the file is the task’s description.

Example

---
pm-task: true
projectId: "p_a4f3c1"
parentId: null
id: "t_111111aabbcc"
title: "Audit current site"
type: "task"
status: "in-progress"
priority: "high"
start: "2026-05-20"
due: "2026-05-30"
progress: 40
assignees:
  - "Stepan"
tags:
  - "discovery"
subtaskIds:
  - "t_111111aabbdd"
dependencies: []
collapsed: false
timeEstimate: 10
timeLogs:
  - date: "2026-05-22"
    hours: 1.5
    note: "First pass"
customFields:
  contract_value: 4200
createdAt: "2026-05-15T08:00:00.000Z"
updatedAt: "2026-05-23T14:00:00.000Z"
---

Audit the existing site against the redesign brief. Flag anything that doesn't carry over.

Custom field definitions

Inside a project’s customFields array. One entry per field:

- id: "contract_value"
  name: "Contract value"
  type: "number"
- id: "sprint"
  name: "Sprint"
  type: "multiselect"
  options:
    - "Q3"
    - "Q4"
    - "Mobile"
  icon: "🏃"

Allowed type values: text, number, date, select, multiselect, person, checkbox, url.

Options is required for select and multiselect.

Custom field values

Stored on each task under customFields, keyed by field ID:

Field typeStored value
text, url, select, personstring
numbernumber
datestring (YYYY-MM-DD)
checkboxboolean
multiselectstring[]

If a field has no value on a task, the key is omitted.

Recurrence

Optional on a task:

recurrence:
  interval: "weekly"     # daily / weekly / monthly / yearly
  every: 2               # every N intervals
  endDate: "2026-12-31"  # optional

Time logs

Each entry:

timeLogs:
  - date: "2026-05-22"     # YYYY-MM-DD
    hours: 1.5             # number
    note: "First draft"    # free-form string

Saved views

Stored on the project (see project example above). Schema:

- id: string
  name: string
  filter:
    text: string
    statuses: string[]
    priorities: ("critical"|"high"|"medium"|"low")[]
    assignees: string[]
    tags: string[]
    dueDateFilter: "any"|"overdue"|"this-week"|"this-month"|"no-date"
    showArchived: boolean
  sortKey: "title"|"status"|"priority"|"assignees"|"due"|"progress"
  sortDir: "asc"|"desc"
  viewMode: "table"|"gantt"|"kanban"   # optional

Archive

There is no archived: true field. A task is archived when its file is inside the <Project>_tasks/Archive/ subfolder. The plugin sets a runtime flag on load based on file location, but it isn’t written back.

What’s safe to hand-edit

  • Everything in the markdown body (the description).
  • Any standard frontmatter field. The plugin re-reads on file change.
  • Custom field values.

What to be careful with:

  • IDs. Must be unique within a project. Don’t copy a file without changing its id.
  • Status / priority IDs. Must match what’s configured in settings, or the task gets remapped on next load.
  • Date format. Always YYYY-MM-DD. Use "" (empty string), not null, for unset.

Where to go next