taskin
v5.0.0
Published
Task management system integrated with Git workflows
Maintainers
Readme
Taskin
Task management system integrated with Git workflows
Taskin is a command-line tool that helps you manage tasks directly from your terminal, with seamless Git integration and dynamic provider loading.
✨ Features
- 🎯 Multiple Task Providers - File System, Redmine, Jira, GitHub Issues (and more!)
- 🔌 Dynamic Provider Installation - Automatically installs providers when needed
- 📦 Lightweight CLI - Only installs what you use
- 🔒 Secure Configuration - API keys protected in
.gitignore - 🎨 Beautiful CLI - Colorful, interactive, and user-friendly
- ⚡ Fast & Efficient - Built with performance in mind
- 🧪 Well Tested - Comprehensive test coverage
🚀 Installation
# Using npx (recommended - no installation needed!)
npx taskin init
# Or install globally
npm install -g taskin
# Or with pnpm
pnpm add -g taskin
# Or with yarn
yarn global add taskinNote: Please report any issues on GitHub.
📦 Available Packages
Taskin is built as a modular ecosystem. Besides the CLI, you can use individual packages:
Core Packages
| Package | Description | npm |
| --------------------------------- | -------------------------------- | --------------------------------------------------------------------------------------- |
| taskin | Complete CLI + programmatic API | |
| @opentask/taskin-types | TypeScript types and Zod schemas | Coming soon |
| @opentask/taskin-core | Core task management logic | Coming soon |
| @opentask/taskin-task-manager | Task lifecycle orchestration | Coming soon |
Task Providers
| Provider | Description | Status | npm | | ----------------------------------------- | ------------------------------------- | -------------- | ----------- | | @opentask/taskin-file-system-provider | File System provider (Markdown files) | ✅ Stable | Coming soon | | @opentask/taskin-redmine-provider | Redmine integration | 🚧 Coming Soon | - | | @opentask/taskin-jira-provider | Jira Cloud integration | 🚧 Coming Soon | - | | @opentask/taskin-github-provider | GitHub Issues integration | 🚧 Coming Soon | - |
Utilities
| Package | Description | npm | | ------------------------------ | -------------------- | ----------- | | @opentask/taskin-git-utils | Git workflow helpers | Coming soon | | @opentask/taskin-utils | Shared utilities | Coming soon |
💡 Tip: When you run
taskin init, providers are automatically installed on-demand. You don't need to install them manually!
Quick Start
Initialize Taskin in your project: ```bash npx taskin init ```
Select your preferred task provider:
- 📁 File System - Store tasks as Markdown files locally
- 🔴 Redmine - Sync with Redmine issues (coming soon)
- 🔵 Jira - Sync with Jira issues (coming soon)
- 🐙 GitHub Issues - Sync with GitHub (coming soon)
List all tasks: ```bash taskin list taskin list --json # JSON array, for another tool to consume ```
Start working on a task: ```bash taskin start task-001 ```
Commands
taskin init- Initialize Taskin in your project with interactive setuptaskin list [filter] [options]- List the open tasks (filteris free text over id, title, type, status and assignee — the same search as the dashboard's top bar). Without a status criterion only open tasks are listed, in the text output and in--jsonalike;--status,--closedand--activereplace that default rather than narrowing it--all- Show every task, closed ones included (refused together with--open,--closed,--activeor--status)--open- Show only open tasks (pending, in-progress, paused, in-review, blocked) — already the default, kept for scripts--closed- Show only closed tasks (done, canceled)--active- Show only tasks started and not finished (in-progress, paused, in-review)--scored- Show only tasks that already have a difficulty (for prioritising)--unscored- Show only tasks still without a difficulty (the queue left to rate)--sort <mode>-manual(priority, the default),diff-ascordiff-desc--status <status>- Filter by specific status--type <type>- Filter by task type-u, --assignee <assignee>- Filter by assignee id or name, whole or in part
taskin new- Create a new task (alias:create)-g, --group <group-id>- Born in this existing group-p, --priority <n>- Born with this priority number--difficulty <1-5>- Born scored; an invalid value is refused before any file is created
taskin start <id>- Start working on a task (suggests commits)taskin pause <id>- Pause work on a task (auto-commits work in progress)taskin review <id>- Mark a task as ready for reviewtaskin finish <id>- Complete a task (suggests commits)
new, start, review and finish each accept --no-skip-ci. See
The CI-skip tag.
taskin stats [options]- Show statistics--user- User statistics--team- Team statistics--period <day|week|month|year>- Time period for stats
taskin config [options]- Configure automation level--level <manual|assisted|autopilot>- Set commit automation level
taskin lint- Validate task files. Exits1when an error is left — with--fixtoo, which corrects what it can and reports what it cannot (an attachment over the size limit, for instance)taskin group- Manage task groups (alias:groups)list- List the groups as a tree: each subgroup indented two spaces under its parent. A group whose parent is missing from the groups file is shown at the top level (taskin lintreports it)create <name> [--id <id>] [--parent <group-id>]- Create a group (alias:add). With--parentit is born inside that existing groupnest <group-id> <parent-id>- Put a group inside another; its subgroups go along. Up to four levels; a group inside itself or inside one of its own subgroups is refused, in one line and with exit1unnest <group-id>- Take a group out of its parent, back to the top levelrename <id> <name>- Rename it; no task file is touchedremove <id> [--reassign-to <id>]- Delete it, saying where its tasks go. Its subgroups move up to its parent — or to the top level — and the command says sojoin <task-id> <group-id>- Put a task in an existing groupleave <task-id>- Take a task out of its groupmove <group-id>- Move a whole group, its members together and in their order. Exactly one of--top,--bottom,--before <task-or-group>or--after <task-or-group>; the target is a task that is not in a group, or another group. Only the members are written — a group of three writes three files — and the command prints how many
taskin priority <task-id> [n]- Give one task its place in the queue; lower comes first. Exactly one of:<n>- An absolute number, a whole number from 1--before <task-id>- Right before that task--after <task-id>- Right after it--top/--bottom- To the top or the bottom of the queue. A grouped task goes to the top or bottom of its own group, as the dashboard buttons do; to move a whole group, usetaskin group move
The relative forms are for when you know what goes before what and not which number you want. They write only what changes — normally one file; the neighbourhood when the numbers leave no room; never the unnumbered tasks past the insertion point.
--topwrites one file.--bottomafter a tail of tasks with noPrioritynumbers that tail once — with 480 unnumbered tasks, 481 files — and every later move costs one. Each form prints how many task files it wrote.taskin difficulty <task-id> <1-5>- Score how hard a task is, from 1 (trivial) to 5 (very hard) — the command for the queuetaskin list --unscoredshows. Anything else is refused without writing. There is no way to clear a score: a wrong one is corrected by scoring again, as on the dashboard.A provider without groups does not offer
joinandleave, and the CLI says so in one line instead of failing. A provider with groups but without groups inside groups refusescreate --parent,nestandunnestthe same way.taskin prioritize- Number every task's priority, once and on purpose--dry-run- Report how many would be numbered, without writing
taskin dashboard [options]- Start the web dashboard (see Avatars)--open/--closed/--active/--all- Open the board on one of the filters. Without any, the board shows the open tasks; a control on the screen switches between Open, Active, Closed and All--filter-open- Show only open tasks--filter-closed- Show only closed tasks
On the prioritization board, moving a task or a group — arrows, top, bottom, dragging — goes over the WebSocket as
move-before/move-after(ormove-group-before/move-group-after), with the first, last or neighbouring visible row as the reference. The numbers come from the same rule astaskin priority --beforeandtaskin group move, so the board writes what they write. Undo re-sends the previous values of only the tasks the move changed.taskin mcp-server- Start MCP server for Claude Desktop integration (alias:mcp)taskin mcp-install- Register the MCP server in this project's.mcp.json-f, --force- Replace an existingtaskinentry that differs--no-probe- Skip starting the server to verify the entry works
taskin help- Show help information
Avatars
The dashboard never sends your browser to a third party for an avatar image. The
domain stores the identity — avatarHash, the md5 of the normalised email —
and the dashboard server proxies the image at /avatar/<hash>, same-origin. The
page therefore only ever asks its own server, which is what lets a strict
img-src 'self' policy work and keeps each viewer's IP and referrer away from
the avatar provider.
Without internet, or when the provider is slow or has no image for that address, nothing hangs and nothing breaks: the request is aborted after a short timeout, the server answers 404 or 504, and the avatar component falls back to the person's initials. Both outcomes are cached — including the negative one, so a missing avatar is not re-fetched on every page load.
The CI-skip tag
The commits Taskin writes on its own carry a tag so a status change does not
burn a pipeline run — [skip ci] by default, configurable per project as
automation.ciSkipTag in .taskin.json. An empty string appends nothing, which
is how a project asks for CI to run on those commits too.
There is one case the project-wide setting cannot get right. GitHub reads
only the head commit of a push. When you commit your work and then run
taskin finish, the status commit lands on top — and its tag skips the whole
push, including the release of the work you just finished.
For that push, turn the tag off for the one call:
taskin finish 042 --no-skip-ciThe flag only turns the tag off. There is no way to force it on in a project that configured an empty string: a project that asked for "CI always" has no use for skipping case by case.
Automation Levels
Taskin supports three automation levels for git commits:
- manual - You're in control: all commits are suggestions only
- assisted (default) - Smart suggestions: auto-commits status changes, suggests work commits
- autopilot - Let Taskin drive: auto-commits everything
Configure with: taskin config --level <level>
What the auto-commits never take:
- A status commit contains only the task file. Anything you had staged stays staged and out of it.
- A work commit (
pause, andfinishin autopilot) is refused when a change looks sensitive: an.envfile (templates like.env.exampleare fine), a private key or certificate store, a credentials file, or an added line with a token. Nothing is staged; Taskin prints the file, line and reason, and the command to commit yourself once you've dealt with it. - The work commit's body lists every file it took.
🤖 MCP Server (Model Context Protocol)
Taskin includes an MCP server that allows AI assistants like Claude Desktop to interact with your tasks:
taskin mcp-serverRegistering it in a project
taskin mcp-installWrites .mcp.json at the project root — not wherever you ran it from, which
matters in a monorepo, where a subdirectory has no lockfile to detect the
package manager from. It merges with servers already configured there, leaves a
differing taskin entry alone until you pass --force, and refuses a malformed
file instead of destroying it.
Then it starts the server over stdio and compares the tools it advertises
against the ones this version offers. Asking only "did it answer?" is not
enough: the command can resolve to a different taskin — an older global
install answers happily, with the wrong set of tools. Skip the check with
--no-probe.
Integration with Claude Desktop
Available MCP Tools:
list_tasks- List tasks, with optional filters — only the open ones unless a status criterion orall: trueis givenprioritize_tasks- Give every task a priority number, once and on purposelist_groups- List the task groups, each with its id and namejoin_group- Put a task in an existing group (only offered when the provider has groups)leave_group- Take a task out of its group (only offered when the provider has groups)move_group- Move a whole group: exactly one ofbefore/after(a task or another group),top: trueorbottom: true(only offered when the provider has groups)set_priority- Place one task: an absolutepriority, orbefore/afteranother taskset_difficulty- Score one task, a wholedifficultyfrom 1 to 5
The listing tools take the same sort vocabulary the prioritization board uses:
manual (by priority), diff-asc and diff-desc. taskin list --json emits
groups as groups — a group node carries its id, its name, the members that
matched, and how many the filter left out — so a consumer never has to
reimplement the grouping rule to get it back. Nested groups stay nested: a
node is { group: { id, name, parentId?, hidden }, tasks, groups }, with
tasks the direct members and groups the subgroups in the same shape. The
text output of taskin list (manual order) prints the same tree: a
▸ <name> (<id>) line per group, with its members and subgroups indented
under it.
start_task- Start working on a taskfinish_task- Mark a task as finished
Available MCP Prompts:
start-task-workflow- Guide for starting tasksfinish-task-workflow- Guide for finishing taskstask-summary- Get task summary and insights
Available MCP Resources:
taskin://tasks- Access all tasks
📦 Programmatic Usage
Taskin can also be used as a library in your TypeScript/JavaScript projects:
npm install taskinimport { createTaskin, getTaskin, type ITaskin } from 'taskin';
// Create a Taskin instance with custom tasks directory
const taskin = createTaskin('./my-tasks');
// Or use the default instance (uses ./TASKS)
const taskin = getTaskin();
// Use the API
const tasks = await taskin.list();
await taskin.start('task-001');
await taskin.pause('task-001', { message: 'Break time!' });
await taskin.finish('task-001');
// Lint tasks
const lintResult = await taskin.lint({ path: './TASKS' });
console.log(`Checked ${lintResult.tasksChecked} tasks`);TypeScript Support
Taskin is written in TypeScript and exports full type definitions:
import type { Task, TaskId, TaskStatus, ITaskin } from 'taskin';
// All types are available for your TypeScript projects
function processTask(task: Task): void {
console.log(`Processing ${task.title}`);
}🏗️ Architecture
Taskin uses a plugin-based architecture with dynamic provider loading:
- Providers are loaded on-demand (only when selected)
- Automatic installation via npm/pnpm/yarn
- Easy to extend with custom providers
📚 See ARCHITECTURE.md for detailed technical documentation.
📝 Creating Tasks
Use the taskin new command to create new task files:
Interactive Mode (Recommended)
Simply run without arguments for a guided experience:
taskin newYou'll be prompted to select:
- Task type (feat, fix, refactor, docs, test, chore)
- Title
- Description (optional)
- Assignee (optional)
Command-line Mode
Or provide all options directly:
# Create a new feature task
taskin new -t feat -T "Add user authentication" -d "Implement JWT-based auth" -u ana-souza
# Create a bug fix task
taskin new --type fix --title "Fix login error" --user ana-souza
# Using the 'create' alias
taskin create -t docs -T "Update README"Options:
-t, --type <type>- Task type: feat, fix, refactor, docs, test, chore-T, --title <title>- Task title (required in command-line mode)-d, --description <description>- Task description-u, --user <user>- Assigned user: the id from.taskin/.taskin-users.json(the display name is accepted too). The file always records the id; someone not in the registry is written as typed, andtaskin lintwarns about it
The command will:
- Auto-generate a task number (e.g., 05)
- Create a markdown file in
TASKS/directory - Use a slug from the title for the filename
- Pre-populate with a standard template
�📖 Examples
See EXAMPLES.md for detailed usage examples and workflows.
🔌 Available Providers
| Provider | Status | Package |
| ---------------- | -------------- | --------------------------------------- |
| 📁 File System | ✅ Stable | @opentask/taskin-file-system-provider |
| 🔴 Redmine | 🚧 Coming Soon | @opentask/taskin-redmine-provider |
| 🔵 Jira | 🚧 Coming Soon | @opentask/taskin-jira-provider |
| 🐙 GitHub Issues | 🚧 Coming Soon | @opentask/taskin-github-provider |
Want to create your own provider? See ARCHITECTURE.md.
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📝 Requirements
- Node.js >= 20.0.0
- npm/pnpm/yarn
🐛 Issues
Found a bug? Have a feature request? Please open an issue.
� Team
OpenTask
- Website: opentask.com.br
- Email: [email protected]
Contributors:
- Sidarta Veloso (@sidartaveloso)
📄 License
MIT © OpenTask
