No Nonsense Tasks
sundial-org/awesome-openclaw-skills
No-nonsense task manager using SQLite. An agent skill from sundial-org/awesome-openclaw-skills.
Structured project/task management for OpenClaw agents — markdown-first authoring, SQLite-backed querying, bidirectional sync, CLI, Apple Notes integration.
$ npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install LeoYeAI/openclaw-master-skills taskflow --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/taskflow .claude/skills/taskflow && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "taskflow" agent skill from https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflow into .claude/skills/taskflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "taskflow", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflowType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install LeoYeAI/openclaw-master-skills taskflow --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/taskflow .agents/skills/taskflow && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "taskflow" agent skill from https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflow into .agents/skills/taskflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "taskflow", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install LeoYeAI/openclaw-master-skills taskflow --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/taskflow .cursor/skills/taskflow && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "taskflow" agent skill from https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflow into .cursor/skills/taskflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "taskflow", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/LeoYeAI/openclaw-master-skills.git --path skills/taskflow--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install LeoYeAI/openclaw-master-skills taskflow --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/taskflow .gemini/skills/taskflow && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "taskflow" agent skill from https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflow into .gemini/skills/taskflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "taskflow", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install LeoYeAI/openclaw-master-skills taskflowInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/taskflow .github/skills/taskflow && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "taskflow" agent skill from https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflow into .github/skills/taskflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "taskflow", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install LeoYeAI/openclaw-master-skills taskflow --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/LeoYeAI/openclaw-master-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/taskflow .opencode/skills/taskflow && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "taskflow" agent skill from https://github.com/LeoYeAI/openclaw-master-skills/tree/main/skills/taskflow into .opencode/skills/taskflow/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "taskflow", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
taskflowStructured project/task management for OpenClaw agents — markdown-first authoring, SQLite-backed querying, bidirectional sync, CLI, Apple Notes integration.
Taskflow is an agent skill from LeoYeAI/openclaw-master-skills. Structured project/task management for OpenClaw agents — markdown-first authoring, SQLite-backed querying, bidirectional sync, CLI, Apple Notes integration.
Its SKILL.md is about 6.5k tokens, which your agent loads only when the skill is triggered. The skill folder holds 22 other files, including scripts (for example `README.md`, `_meta.json` and `examples/DASHBOARD-HOWTO.md`).
It sits in Productivity & Automation, covering Task management. It works with SQLite. The repository describes itself as: 🧠 Curated collection of 1209+ best OpenClaw skills — weekly updated by MyClaw.ai. The licence is MIT.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit e5199b5. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 5 files in scripts/ (JavaScript, from the files we listed), which the agent can run.
Shell commands in SKILL.md call:
nodesqlite3From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Taskflow loads about 6.5k tokens when it runs. Until then it costs about 41 tokens; SKILL.md has 2,116 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from LeoYeAI/openclaw-master-skills at commit e5199b5, republished under its MIT licence (© LeoYeAI). 2,116 words, ~6,506 tokens.
.claude/skills/taskflow/SKILL.md (or your agent's skills folder). This skill also uses 16 other files; get the full folder from GitHub.TaskFlow gives any OpenClaw agent a structured project/task/plan system with markdown-first authoring, SQLite-backed querying, and bidirectional sync.
Principle: Markdown is canonical. Edit tasks/*.md directly. The SQLite DB is a derived index, not the source of truth.
OPENCLAW_WORKSPACE is a high-trust value. All TaskFlow scripts resolve file paths from it, and the CLI and sync daemon use it to locate the SQLite database, markdown task files, and log directory.
Rules for safe use:
Set it only from trusted, controlled sources. The value must come from:
.zshrc, .bashrc, /etc/environment)Environment= directive in a template you controlEnvironmentVariables dictionary you installedNever accept OPENCLAW_WORKSPACE from:
Validate the path exists before use. Any script that reads OPENCLAW_WORKSPACE should confirm the directory exists before proceeding:
import { existsSync } from 'node:fs'
import path from 'node:path'
const workspace = process.env.OPENCLAW_WORKSPACE
if (!workspace) {
console.error('OPENCLAW_WORKSPACE is not set. Aborting.')
process.exit(1)
}
if (!existsSync(workspace)) {
console.error(`OPENCLAW_WORKSPACE path does not exist: ${workspace}`)
process.exit(1)
}
// Resolve to absolute path to neutralize any relative-path tricks
const safeWorkspace = path.resolve(workspace)Do not construct paths from untrusted input. Even with a valid OPENCLAW_WORKSPACE, never concatenate unvalidated user input onto it (e.g. path.join(workspace, userSlug, '../../../etc/passwd')). Use path.resolve() and check that the resolved path starts with the workspace root:
function safeJoin(base, ...parts) {
const resolved = path.resolve(base, ...parts)
if (!resolved.startsWith(path.resolve(base) + path.sep)) {
throw new Error(`Path traversal attempt detected: ${resolved}`)
}
return resolved
}Treat OPENCLAW_WORKSPACE as a local system path only. It must point to a directory on the local filesystem. Remote paths (NFS mounts, network shares) may work but are outside the tested configuration and could introduce TOCTOU (time-of-check/time-of-use) race conditions.
Add to your shell profile (.zshrc, .bashrc, etc.):
export OPENCLAW_WORKSPACE="/path/to/your/.openclaw/workspace"All TaskFlow scripts and the CLI resolve paths from this variable. Without it, they fall back to process.cwd(), which is almost never what you want.
See also: OPENCLAW_WORKSPACE Trust Boundary above for security requirements.
ln -sf {baseDir}/scripts/taskflow-cli.mjs /opt/homebrew/bin/taskflow # macOS (Apple Silicon)
# or: ln -sf {baseDir}/scripts/taskflow-cli.mjs /usr/local/bin/taskflowtaskflow setupThe wizard handles the rest: creates workspace directories, walks you through adding your first project(s), initializes the database, syncs, and optionally installs the macOS LaunchAgent for periodic sync.
Alternative — manual setup:
<details>
<summary>Manual steps (if you prefer explicit control)</summary>
# Create workspace dirs
mkdir -p "$OPENCLAW_WORKSPACE/tasks" "$OPENCLAW_WORKSPACE/plans" "$OPENCLAW_WORKSPACE/memory" "$OPENCLAW_WORKSPACE/logs"
# Bootstrap the DB schema
taskflow init
# Create PROJECTS.md and tasks/<slug>-tasks.md manually (see templates/)
# Sync markdown → DB
taskflow sync files-to-db
# Verify
taskflow status</details>
When a user asks you to set up TaskFlow or you detect it has not been initialized:
$OPENCLAW_WORKSPACE/PROJECTS.md and $OPENCLAW_WORKSPACE/memory/taskflow.sqlite.taskflow setup --name "Project Name" --desc "One-liner description"taskflow status to confirm.taskflow setup (it detects the state automatically and offers to init + sync).taskflow status — already set up.AGENTS.md with the new project slug so future sessions discover it via cat PROJECTS.md.taskflow setupThe interactive wizard will:
PROJECTS.md and tasks/<slug>-tasks.md from templatesNon-interactive (scripted installs):
taskflow setup --name "My Project" --desc "What it does"Passing --name skips all interactive prompts (daemon install is also skipped in non-interactive mode).
<workspace>/
├── PROJECTS.md # Project registry (one ## block per project)
├── tasks/<slug>-tasks.md # Task list per project
├── plans/<slug>-plan.md # Optional: architecture/design doc per project
└── taskflow/
├── SKILL.md # This file
├── scripts/
│ ├── taskflow-cli.mjs # CLI entry point (symlink target)
│ ├── task-sync.mjs # Bidirectional markdown ↔ SQLite sync
│ ├── init-db.mjs # Bootstrap SQLite schema (idempotent)
│ ├── export-projects-overview.mjs # JSON export of project/task state
│ └── apple-notes-export.mjs # Optional: project state → Apple Notes (macOS only)
├── templates/ # Starter files for new projects
├── schema/
│ └── taskflow.sql # Full DDL
└── system/
├── com.taskflow.sync.plist.xml # Periodic sync (macOS LaunchAgent)
├── taskflow-sync.service # Periodic sync (Linux systemd user unit)
└── taskflow-sync.timer # Systemd timer (60s interval)
<workspace>/
└── taskflow.config.json # Apple Notes config (auto-created on first notes run)Follow this full checklist when creating a new project:
PROJECTS.md## <slug>
- Name: <Human-Readable Name>
- Status: active
- Description: One-sentence description of the project.slug is lowercase, hyphenated (e.g., my-project). It becomes the canonical project ID everywhere.active, paused, done.Copy taskflow/templates/tasks-template.md → tasks/<slug>-tasks.md and update the project name in the heading.
The file must contain these five section headers in this order:
# <Project Name> — Tasks
## In Progress
## Pending Validation
## Backlog
## Blocked
## DoneCopy taskflow/templates/plan-template.md → plans/<slug>-plan.md for architecture docs, design decisions, and phased roadmaps. Plan files are not synced to SQLite — they are reference-only for the agent.
You do not need to manually insert into the projects table. The sync engine auto-creates the project row from PROJECTS.md on the next files-to-db run. If you want to be explicit via Node.js, use a parameterized statement:
// Safe: parameterized insert — no string interpolation in the SQL
db.prepare(`INSERT INTO projects (id, name, description, status)
VALUES (:id, :name, :description, 'active')`)
.run({ id: slug, name: projectName, description: projectDesc })Every task line follows this exact format:
- [x| ] (task:<id>) [<priority>] [<owner>] <title>| Field | Details |
|---|---|
[ ] / [x] | Open / completed. Sync drives status from section header, not this checkbox. |
(task:<id>) | Task ID. Format: <slug>-NNN (zero-padded 3-digit). Sequential per project. |
[<priority>] | Required. Must come before owner tag. See priority table below. |
[<owner>] | Optional. Agent/model tag (e.g., codex, sonnet, claude). |
<title> | Human-readable task title. |
Priority tag MUST come before owner tag. The sync parser is positional — it reads the first [Px] bracket as priority, and the next [tag] as owner. Swapping them will misparse the task.
Task titles must be plain text only. Before writing any user-supplied string as a task title, apply the following rules:
Reject lines that look like section headers. A title may not start with one or more # characters followed by a space (e.g. # My heading, ## Done). These would corrupt the sync parser's section detection.
Reject the exact section header strings even without leading whitespace:
In Progress, Pending Validation, Backlog, Blocked, DoneEscape or strip markdown special characters that have structural meaning in the task file:
| Character | Risk | Safe action |
|---|---|---|
# | Looks like a header | Strip or reject |
- (dash + space at line start) | Looks like a list item / task | Strip leading - |
[ ] / [x] | Looks like a checkbox | Escape brackets: \[ \] |
] / [ alone | Can corrupt (task:id) parse | Escape: \[ \] |
Newlines (\n, \r) | Creates multi-line titles | Strip / reject |
Maximum length. Titles should be ≤ 200 characters. Truncate or reject longer strings.
Example sanitization (Node.js):
// Safe: sanitize a user-supplied task title before writing to markdown
function sanitizeTitle(raw) {
if (typeof raw !== 'string') throw new TypeError('title must be a string')
// Strip newlines
let title = raw.replace(/[\r\n]+/g, ' ').trim()
// Reject lines that look like section headers (# Heading or bare header words)
if (/^#{1,6}\s/.test(title)) {
throw new Error('Title may not start with a markdown heading (#)')
}
const BANNED_HEADERS = /^(in progress|pending validation|backlog|blocked|done)$/i
if (BANNED_HEADERS.test(title)) {
throw new Error('Title may not be a reserved section header name')
}
// Escape structural markdown characters
title = title
.replace(/\[/g, '\\[')
.replace(/\]/g, '\\]')
// Enforce length limit
if (title.length > 200) {
throw new Error('Title exceeds 200 character limit')
}
return title
}These rules apply whenever a task title comes from any external or user-supplied source (CLI args, API payloads, file imports). Titles hard-coded by agents in their own sessions are low-risk but should still avoid structural characters.
✅ Correct: - [ ] (task:myproject-007) [P1] [codex] Implement search
❌ Wrong: - [ ] (task:myproject-007) [codex] [P1] Implement search
| Tag | Default Meaning |
|---|---|
P0 | Critical — must do now, blocks everything |
P1 | High — important, do soon |
P2 | Normal — standard priority (default) |
P3 | Low — nice to have |
P9 | Someday — no urgency, parking lot |
Priorities are configurable per-installation but the tags themselves (P0–P3, P9) are what the sync engine validates.
A note can follow a task line as an indented - note: line:
- [ ] (task:myproject-003) [P1] [codex] Implement auth flow
- note: blocked on API key from vendorKnown limitation (v1): Notes are one-way. Removing or editing a note in markdown does not propagate to the DB. This is tracked for a post-MVP fix.
## In Progress
- [ ] (task:myproject-001) [P1] [codex] Wire up OAuth login
- note: PR open, needs review
## Backlog
- [ ] (task:myproject-002) [P2] Add rate limiting middleware
- [ ] (task:myproject-003) [P3] Write integration testsDetermine the next ID. Scan the task file for the highest existing <slug>-NNN and increment by 1. Or query SQLite using a parameterized statement (never interpolate the slug into SQL strings):
// Node.js — safe, parameterized
const db = new DatabaseSync(dbPath)
const row = db
.prepare(`SELECT MAX(CAST(SUBSTR(id, LENGTH(:slug) + 2) AS INTEGER)) AS max_seq
FROM tasks_v2
WHERE project_id = :slug`)
.get({ slug: projectSlug })
const nextSeq = (row.max_seq ?? 0) + 1
const nextId = `${projectSlug}-${String(nextSeq).padStart(3, '0')}`⚠️ Never construct SQL by string interpolation. Use
db.prepare()with named or positional parameters (?or:name) for all values that come from external input. This applies even for read-only queries.
Append the task line to the correct section (## Backlog for new work, ## In Progress if starting immediately).
Format the line using the exact format above. No trailing spaces. Priority tag before owner tag.
Move the task line from its current section to the target section in the markdown file.
| Target State | Move to Section |
|---|---|
| Started / picked up | ## In Progress |
| Needs human review | ## Pending Validation |
| Not started yet | ## Backlog |
| Waiting on dependency | ## Blocked |
| Finished | ## Done |
Also flip the checkbox: [ ] for active states, [x] for Done (and optionally Pending Validation).
The periodic sync (60s) will pick up the change and update SQLite automatically. To force an immediate sync:
node taskflow/scripts/task-sync.mjs files-to-dbcat tasks/<slug>-tasks.mdFor a quick in-session view, just read the relevant section.
⚠️ SQL Safety Rule: Any query that incorporates a variable value (project slug, task ID, status string, etc.) must use parameterized statements — not string interpolation. The
sqlite3CLI examples below use only static, hardcoded literal values and are shown as diagnostic/inspection tools only. For programmatic use, always use the Node.jsdb.prepare()API with bound parameters.
# All in-progress tasks across all projects (by priority)
# Safe: 'in_progress' is a static literal, not a variable
sqlite3 "$OPENCLAW_WORKSPACE/memory/taskflow.sqlite" \
"SELECT id, project_id, priority, title
FROM tasks_v2
WHERE status = 'in_progress'
ORDER BY priority, project_id;"
# Task count by status per project (no variables — safe for CLI)
sqlite3 "$OPENCLAW_WORKSPACE/memory/taskflow.sqlite" \
"SELECT project_id, status, COUNT(*) AS count
FROM tasks_v2
GROUP BY project_id, status
ORDER BY project_id, status;"Do not embed shell variables directly in the SQL string (e.g.
WHERE project_id = '$SLUG'). That pattern is SQL injection waiting to happen. Use the Node.js API with parameters instead.
import { DatabaseSync } from 'node:sqlite'
import path from 'node:path'
const dbPath = path.join(process.env.OPENCLAW_WORKSPACE, 'memory', 'taskflow.sqlite')
const db = new DatabaseSync(dbPath)
db.exec('PRAGMA foreign_keys = ON')
// ── Backlog for a specific project ─────────────────────────────
// :slug is a named parameter — never interpolated into the SQL string
const backlog = db
.prepare(`SELECT id, priority, title
FROM tasks_v2
WHERE project_id = :slug AND status = 'backlog'
ORDER BY priority`)
.all({ slug: 'my-project' }) // value bound at runtime, never in SQL string
// ── Audit trail for a specific task ────────────────────────────
const transitions = db
.prepare(`SELECT from_status, to_status, actor, at
FROM task_transitions_v2
WHERE task_id = ?
ORDER BY at`)
.all('my-project-007') // positional parameter — also safe
// ── Write: update task status ───────────────────────────────────
// NEVER: db.exec(`UPDATE tasks_v2 SET status='${newStatus}' WHERE id='${id}'`)
// ALWAYS:
db.prepare(`UPDATE tasks_v2 SET status = :status, updated_at = datetime('now')
WHERE id = :id`)
.run({ status: 'done', id: 'my-project-007' })# Terminal summary: all projects + task counts by status
taskflow status
# Add a task in markdown with automatic next ID
taskflow add taskflow "Implement quick add command" --priority P1 --owner codex
# List current tasks for a project (excludes done by default)
taskflow list taskflow
taskflow list --project "TaskFlow" --all
taskflow list task --status backlog,pending_validation --json
# JSON export of full project/task state (for dashboards, integrations)
node taskflow/scripts/export-projects-overview.mjs
# Detect drift between markdown and DB (exit 1 if mismatch)
node taskflow/scripts/task-sync.mjs check
# Sync markdown → DB (normal direction; run after editing task files)
node taskflow/scripts/task-sync.mjs files-to-db
# Sync DB → markdown (run after programmatic DB updates)
node taskflow/scripts/task-sync.mjs db-to-filesTaskFlow can maintain a live Apple Note with your current project status. The note is rendered as rich HTML and written via AppleScript.
# Push current status to Apple Notes (creates note on first run)
taskflow notesOn first run (or during taskflow setup), a new note is created in the configured folder and its Core Data ID is saved to:
$OPENCLAW_WORKSPACE/taskflow.config.jsonConfig schema:
{
"appleNotesId": "x-coredata://...",
"appleNotesFolder": "Notes",
"appleNotesTitle": "TaskFlow - Project Status"
}Important — never delete the shared note. The note is always edited in-place. Deleting and recreating it generates a new Core Data ID and breaks any existing share links. If the note is accidentally deleted, taskflow notes will create a new one and update the config automatically.
For hourly auto-refresh, add a cron entry:
# Run: crontab -e
0 * * * * OPENCLAW_WORKSPACE=/path/to/workspace /path/to/node /path/to/taskflow/scripts/apple-notes-export.mjsOr install a dedicated LaunchAgent (macOS) targeting apple-notes-export.mjs with an hourly StartInterval of 3600.
This feature is entirely optional and macOS-specific. On other platforms, taskflow notes exits gracefully with a message.
These rules keep daily memory logs clean and prevent duplication.
Completed `myproject-007` (OAuth login). Moved `myproject-008` to In Progress.tasks/<slug>-tasks.md is the single source of truth for all pending work. Memory files should not list what's left to do.At the start of a session involving a project:
cat PROJECTS.md — identify the project slug and statuscat tasks/<slug>-tasks.md — load current task statecat plans/<slug>-plan.md — load architecture context (if it exists)The sync daemon runs task-sync.mjs files-to-db every 60 seconds in the background. This means markdown edits are automatically reflected in SQLite within a minute.
logs/taskflow-sync.stdout.log and logs/taskflow-sync.stderr.log (relative to workspace)sync_state table prevents concurrent syncstaskflow install-daemonThis detects your platform and installs the appropriate unit. On macOS it installs and loads the LaunchAgent; on Linux it writes systemd user units and enables the timer.
Templates: taskflow/system/com.taskflow.sync.plist.xml
taskflow/system/com.taskflow.sync.plist.xml → ~/Library/LaunchAgents/com.taskflow.sync.plist{{workspace}} with the absolute path to your workspace (no trailing slash){{node}} with the path to your node binary (which node)launchctl load ~/Library/LaunchAgents/com.taskflow.sync.plistlaunchctl list | grep taskflowUninstall:
launchctl unload ~/Library/LaunchAgents/com.taskflow.sync.plist
rm ~/Library/LaunchAgents/com.taskflow.sync.plistTemplates: taskflow/system/taskflow-sync.service and taskflow/system/taskflow-sync.timer
# Create the user unit directory
mkdir -p ~/.config/systemd/user
# Copy templates, replacing placeholders
sed -e "s|{{workspace}}|$OPENCLAW_WORKSPACE|g" \
-e "s|{{node}}|$(which node)|g" \
taskflow/system/taskflow-sync.service > ~/.config/systemd/user/taskflow-sync.service
sed -e "s|{{workspace}}|$OPENCLAW_WORKSPACE|g" \
-e "s|{{node}}|$(which node)|g" \
taskflow/system/taskflow-sync.timer > ~/.config/systemd/user/taskflow-sync.timer
# Enable and start
systemctl --user daemon-reload
systemctl --user enable --now taskflow-sync.timerVerify:
systemctl --user status taskflow-sync.timer
journalctl --user -u taskflow-sync.serviceUninstall:
systemctl --user disable --now taskflow-sync.timer
rm ~/.config/systemd/user/taskflow-sync.{service,timer}
systemctl --user daemon-reloadNote: systemd user units require a login session. To run them without an interactive session (e.g. on a server), enable lingering:
loginctl enable-linger $USER
| Markdown Header | DB status value |
|---|---|
## In Progress | in_progress |
## Pending Validation | pending_validation |
## Backlog | backlog |
## Blocked | blocked |
## Done | done |
Section headers are fixed. Do not rename them. The sync parser maps these exact strings.
Things that work but might trip you up:
MAX(id) is lexicographic. Task IDs are text, so SELECT MAX(id) works only because IDs are zero-padded (-001, -002). If you create -1 instead of -001, sequencing breaks. Always zero-pad to 3 digits.## section a task lives under, not whether it's [x] or [ ]. The sync engine ignores the checkbox on read. On write-back, done tasks get [x], everything else gets [ ].- note: line from markdown, the old note stays in the DB (COALESCE preserves it). This is intentional for v1 -- notes are one-way display. To truly clear a note, update the DB directly.kill -9 won't. The lock auto-expires.projects row, it creates one with a name like "My Project" from slug "my-project". The name might not be what you want -- fix it in PROJECTS.md and re-sync.[P1] [codex] works. [codex] [P1] silently assigns codex as... nothing useful. Priority tag must come first.db-to-files rewrites all project task files, even unchanged ones.taskflow install-daemon to install.node:sqlite). No Python fallback in v1.New project: PROJECTS.md block + tasks/<slug>-tasks.md + optional plans/<slug>-plan.md
New task: taskflow add <project> "title" (or append manually to section)
Update status: Move line to correct ## section, flip checkbox if needed
Query simple: cat tasks/<slug>-tasks.md
Query complex: Use db.prepare('SELECT ... WHERE id = ?').all(id) — never interpolate variables into SQL
CLI status: taskflow status
CLI add: taskflow add dashboard "Fix cron panel" --priority P1 --owner codex
Force sync: node taskflow/scripts/task-sync.mjs files-to-db
Memory rule: Reference IDs in logs; never copy backlog into memory© LeoYeAI, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 16 other files (scripts) in skills/taskflow of LeoYeAI/openclaw-master-skills.
Open the folder on GitHubat commit e5199b5
Taskflow next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Taskflow this skillLeoYeAI/openclaw-master-skills | 2.2k | — | ~6.5k | Automated safety check: Pass | MIT | |
| No Nonsense Taskssundial-org/awesome-openclaw-skills | 663 | — | ~835 | Automated safety check: Pass | None | |
| Kanbancyanluna-git/cyanluna.skills | 183 | — | ~3.6k | Automated safety check: Pass | MIT | |
| Retinuejklthinking/retinue | 112 | — | ~279 | Automated safety check: Pass | MIT | |
| Kanban Initcyanluna-git/cyanluna.skills | 183 | — | ~1.3k | Automated safety check: Pass | MIT | |
| Task Backlog Managermp-web3/claude-starter-kit | 109 | — | ~1.2k | Automated safety check: Notes | MIT |
sundial-org/awesome-openclaw-skills
No-nonsense task manager using SQLite. An agent skill from sundial-org/awesome-openclaw-skills.
cyanluna-git/cyanluna.skills
Manage project tasks in a local SQLite DB (~/.claude/kanban-dbs/{project}.db).
jklthinking/retinue
Coordinate work through a local Retinue workspace using its MCP tools.
cyanluna-git/cyanluna.skills
Initialize the current project in local SQLite kanban. An agent skill from cyanluna-git/cyanluna.skills.
mp-web3/claude-starter-kit
Keeps a personal task backlog in SQLite behind a /tasks command that adds, reviews, completes and measures tasks against a list of long-term problems.
Othmane-Khadri/YALC-the-GTM-operating-system
Poll Unipile / Instantly for the status of running campaigns, advance sequence steps that are due, and sync results to Notion.
LeoYeAI/openclaw-master-skills
Manages pipelines on a DevOps quality and efficiency platform through its OpenAPI: list workspaces and templates, create, update, run and cancel pipelines, and read run records.
LeoYeAI/openclaw-master-skills
Patches OpenClaw's Feishu extension so an edited document triggers an isolated agent session that reads the doc and replies inline, turning it into a live chat space.
LeoYeAI/openclaw-master-skills
Multi-context memory management system for OpenClaw agents with group-isolated storage, global shared memory, workspace organization, and group-specific skills isolation.
LeoYeAI/openclaw-master-skills
Runs a brand's AI-search visibility work end to end: diagnosing how AI platforms represent it, repositioning it, producing AI-optimized content and monitoring ongoing mentions.
LeoYeAI/openclaw-master-skills
Installs and authenticates the gws CLI, then automates Gmail, Drive, Sheets, Calendar, Docs, Chat and Tasks with ready-made recipes, persona bundles and security audits.
LeoYeAI/openclaw-master-skills
Runs four advisor roles, a fitness coach, nutritionist, data analyst and TCM practitioner, to build a health profile and track workouts, diet and wellness over time.
Works with
Categories
Structured project/task management for OpenClaw agents — markdown-first authoring, SQLite-backed querying, bidirectional sync, CLI, Apple Notes integration. Taskflow is an agent skill from LeoYeAI/openclaw-master-skills. Structured project/task management for OpenClaw agents — markdown-first authoring, SQLite-backed querying, bidirectional sync, CLI, Apple Notes integration.
Taskflow fits situations like: tasks that involve Task management.
Run `npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a claude-code`. Or copy the skill folder (skills/taskflow in LeoYeAI/openclaw-master-skills) into .claude/skills/taskflow in your project. Claude Code loads it when a task matches its description.
Run `npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a codex`. Or copy the skill folder (skills/taskflow in LeoYeAI/openclaw-master-skills) into .agents/skills/taskflow in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add LeoYeAI/openclaw-master-skills --skill taskflow -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/taskflow, .gemini/skills/taskflow, .github/skills/taskflow and .opencode/skills/taskflow in your project.
Going by SKILL.md and its folder, Taskflow needs JavaScript for the scripts in its folder and the command-line tools its instructions call (node and sqlite3). Our summary lists: Node.js.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Taskflow is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.5k tokens (SKILL.md is roughly 26k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Taskflow: No Nonsense Tasks (sundial-org/awesome-openclaw-skills, 663 stars), Kanban (cyanluna-git/cyanluna.skills, 183 stars), Retinue (jklthinking/retinue, 112 stars) and Kanban Init (cyanluna-git/cyanluna.skills, 183 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
LeoYeAI (a GitHub user) maintains it in LeoYeAI/openclaw-master-skills, which has 2,158 GitHub stars. The repository holds 1,215 skills in this directory. The repository was last updated on July 20, 2026.
Source: LeoYeAI/openclaw-master-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.