Skip to main content

Squillify development is paused indefinitely. Read why, and discover what this experiment achieved. Read the story

MicroSkills Reference

Markdown Checklist Extractor

productivity.todo_extract

ProductionBounded custom (Class B)Deterministicstrictfastv1.0.0
No network

Overview

You send Markdown and we hand back its checklist as structured items: the state of each box, where it sits in the nesting, the exact characters it occupies in your document, and an identity derived from the item's own text so two extractions of the same list line up. The grammar we read is GitHub's task-list extension and only that — a space, an x or an X between the brackets. A bullet that is not a checkbox is counted for you but never adopted into the list, because a document that mixes prose bullets with tasks is normal rather than broken.

Agents keep their plans in Markdown, and re-reading that plan with a hand-rolled parser gives a different answer every time the indentation changes.

Reliability

Same document, same options, same bytes back, including every identity: an identity is your document prefix, the first sixteen hex characters of the SHA-256 of the item's normalised text, and its position, so inserting a line at the top changes positions and leaves the hashes alone. Failures, none worth retrying unchanged: TODO_TEXT_INVALID means text was missing, was not a string, or was empty, so send the document itself; TODO_TEXT_TOO_LARGE means the document went past 262,144 characters, so split it and extract each part; TODO_LINE_LIMIT_EXCEEDED means it went past 40,000 lines, which is the same remedy of splitting the document; TODO_MARKER_SET_INVALID means listMarkers held something outside the five supported markers or repeated one, so send a clean set; TODO_DEPTH_INVALID means maxDepth sat outside 1 to 6, so pick a level in range; TODO_DOCUMENT_ID_INVALID means documentId was too long or used a character outside the allowed set, so shorten it and stick to letters, digits, dot, underscore, colon and hyphen; TODO_EXTRACT_WORK_REFUSED means the document's size and line count together project past our work budget, and the response tells you both numbers so you know how far to trim; TODO_OUTPUT_TOO_LARGE means the extracted list would not fit in one inline response, so lower maxItems or extract a section at a time.

Context footprint

Returns one record per checkbox plus a counts block. Item text is echoed because a task without its wording is not a task, and it is capped at 2,000 characters per item. A successful call costs 1 execution credit.

When to use it

When you hold a Markdown document and want its checkboxes as data you can compare, update and store.

When the items you want are not checkboxes, or when you want us to change something in a tracker rather than read a document.

Scope

Note
Read the GitHub-flavoured task-list items out of a Markdown document and return them as records with state, nesting, source offsets and a content-derived identity.

Non-goals

  • Does not write to any task tracker, calendar or note store
  • Does not accept a pattern, expression or selector of any kind
  • Does not adopt a plain bullet as a task; it counts it instead
  • Does not read anything inside a fenced code block
  • Does not renumber an ordered list; the author's numbers come back as written

Properties

IdempotentRetry safeStreaming supportedFile input supportedRequires external service

Capabilities

document-processingparsing

Cost & billing

Flat rate per invocation

MetercallsBillable onsuccessCost per call1 credit

File handling

Accepts file_refProduces file_refMax input256 KB

How we handle your data

Sensitive output possible
What this means

This skill may receive sensitive content and may return submitted, transformed, extracted, or reformatted content.

Squillify guarantees
  • Runs inside Squillify
  • This skill runs inside Squillify.
  • Payloads are not sent to an external service by this skill.
  • Squillify does not permanently store submitted payloads.
  • Telemetry records metadata only, not submitted content.
  • Submitted payloads are not used for training.
  • Submitted payloads are not reviewed by humans.
  • This skill does not target sensitive data.
  • The response may contain submitted or transformed content.
Your responsibility

Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.

Read the Microskill Data Handling Policy

Input schema

FieldTypeRequiredDescription
textstringYesMarkdown document to scan, 1 to 262144 characters over at most 40000 lines; fenced code is skipped.
documentIdstringNoDocument prefix for derived identities, 1 to 64 letters, digits, dots, underscores, colons or hyphens; omit it so identities start with a bare colon.
listMarkersarrayNoWhich markers open a list item, 1 to 5 of HYPHEN, ASTERISK, PLUS, ORDERED_DOT and ORDERED_PAREN; omit it to accept all five.
stateFilterstringNoKeep every item with ALL, only ticked boxes with CHECKED, or only open ones with UNCHECKED; omit it for ALL.
maxDepthintegerNoDeepest nesting level to report, 1 to 6; omit it for 6.
maxItemsintegerNoHow many items to return, 1 to 5000; omit it for 5000.

Output schema

FieldTypeRequiredDescription
itemsarrayYesChecklist in document order, 0 through 5000 closed items each with id, nesting, state, marker, offsets and flags.
summaryobjectYesClosed counts for the whole document: returned itemCount, checked and unchecked totals, non-task bullets, depth, truncation and clamp flags.

API contract

POST /v1/execute
curl
curl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"productivity.todo_extract","input":{"text":"- [ ] Draft the changelog\n- [x] Tag the release","documentId":"release-notes"}}'
Integrations
TypeScript SDK
import { Squillify } from "@squillify/sdk";

const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });

const { output } = await sq.execute("productivity.todo_extract", {"documentId":"release-notes","text":"# Release\n- [ ] Draft the changelog\n- [x] Tag the release\n"});

Errors

CodeHTTPRetryableDescription
VALIDATION_ERROR400NoThe request payload failed schema validation.
UNAUTHORIZED401NoMissing or invalid API key.
SKILL_NOT_ACCESSIBLE403NoThe API key is not granted access to this skill.
SKILL_NOT_AVAILABLE_FOR_PLAN403NoThis skill is not included in your current plan.
PLAN_ELIGIBILITY_UNAVAILABLE503YesPlan eligibility could not be decided. Retry after backoff.
SKILL_NOT_FOUND404NoThe requested skill or version does not exist.
TENANT_RATE_LIMITED429YesRequest rate limit exceeded. Retry after backoff.
QUOTA_EXCEEDED429YesPlan quota exhausted. Retryable once the quota period resets.
EXECUTION_TIMEOUT504YesExecution exceeded the allowed time budget.
TODO_TEXT_INVALID400NoThe request payload failed this skill's input validation.
TODO_TEXT_TOO_LARGE429NoA size, quota, rate, or time limit was exceeded.
TODO_LINE_LIMIT_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
TODO_MARKER_SET_INVALID400NoThe request payload failed this skill's input validation.
TODO_DEPTH_INVALID400NoThe request payload failed this skill's input validation.
TODO_DOCUMENT_ID_INVALID400NoThe request payload failed this skill's input validation.
TODO_EXTRACT_WORK_REFUSED429NoA size, quota, rate, or time limit was exceeded.
TODO_OUTPUT_TOO_LARGE429NoA size, quota, rate, or time limit was exceeded.

Other limits

LimitValue
Recommended inline bytes32 KiB

Limitations

  • Does not write to any task tracker, calendar or note store
  • Does not accept a pattern, expression or selector of any kind
  • Does not adopt a plain bullet as a task; it counts it instead
  • Does not read anything inside a fenced code block
  • Does not renumber an ordered list; the author's numbers come back as written
  • Extracting anything that is not a checkbox, such as a table or a heading
  • Matching arbitrary phrases in prose, which wants a pattern skill instead

How to call

POST /v1/execute (requires authentication)

Request bodyjson
{
  "skillKey": "productivity.todo_extract",
  "input": {
    "documentId": "release-notes",
    "text": "# Release\n- [ ] Draft the changelog\n- [x] Tag the release\n"
  }
}

Examples

Release checklist with one box already ticked

Inputjson
{
  "documentId": "release-notes",
  "text": "# Release\n- [ ] Draft the changelog\n- [x] Tag the release\n"
}
Expected outputjson
{
  "summary": {
    "itemCount": 2,
    "checkedCount": 1,
    "uncheckedCount": 1,
    "nonTaskListItemCount": 0,
    "maxDepthSeen": 0,
    "depthClampedCount": 0,
    "textTruncatedCount": 0,
    "truncated": false
  },
  "items": [
    {
      "id": "release-notes:b7cde273a37783e2:0",
      "ordinal": 0,
      "depth": 0,
      "state": "UNCHECKED",
      "marker": "HYPHEN",
      "text": "Draft the changelog",
      "charStart": 10,
      "charEnd": 35,
      "lineStart": 2,
      "lineEnd": 2,
      "flags": []
    },
    {
      "id": "release-notes:79cc6c7a03b3a75b:1",
      "ordinal": 1,
      "depth": 0,
      "state": "CHECKED",
      "marker": "HYPHEN",
      "text": "Tag the release",
      "charStart": 36,
      "charEnd": 57,
      "lineStart": 3,
      "lineEnd": 3,
      "flags": []
    }
  ]
}
Tip
The heading is not a list item, so it is neither adopted nor counted.

Nested checklist filtered down to the open items

Inputjson
{
  "stateFilter": "UNCHECKED",
  "text": "- [ ] Ship the API\n  - [x] Write the docs\n- Not a task"
}
Expected outputjson
{
  "summary": {
    "itemCount": 1,
    "checkedCount": 1,
    "uncheckedCount": 1,
    "nonTaskListItemCount": 1,
    "maxDepthSeen": 1,
    "depthClampedCount": 0,
    "textTruncatedCount": 0,
    "truncated": false
  },
  "items": [
    {
      "id": ":f47efc55f052a94b:0",
      "ordinal": 0,
      "depth": 0,
      "state": "UNCHECKED",
      "marker": "HYPHEN",
      "text": "Ship the API",
      "charStart": 0,
      "charEnd": 18,
      "lineStart": 1,
      "lineEnd": 1,
      "flags": []
    }
  ]
}
Tip
Filtering runs after positions are assigned, so the surviving item keeps ordinal 0 and the plain bullet is counted rather than adopted.
  • Turn a Markdown planning document into structured tasks an agent can act on
  • Diff two versions of a checklist and see which items really changed

Avoid for

  • Extracting anything that is not a checkbox, such as a table or a heading
  • Matching arbitrary phrases in prose, which wants a pattern skill instead

Composable with

Safety & privacy

  • Runs without calling any external service.
  • Your payloads are never stored permanently.
  • Telemetry captures metadata only — never your payload contents.
  • We never train models on your payloads.
  • No human reviews your payloads.

Tags

checklistmarkdownparsingproductivity