@hardlydifficult/task-list
v2.0.171
Published
Opinionated task-list automation with a single async entrypoint. The default path is Linear. Trello is supported, but only when you ask for it explicitly.
Readme
@hardlydifficult/task-list
Opinionated task-list automation with a single async entrypoint. The default path is Linear. Trello is supported, but only when you ask for it explicitly.
Installation
npm install @hardlydifficult/task-listQuick Start
import { createTaskList } from "@hardlydifficult/task-list";
const tasks = await createTaskList({ team: "Core" });
const bug = await tasks.createTask({
project: "Bot",
title: "Fix login",
description: "Users cannot log in on mobile",
labels: ["Bug"],
});
await bug.moveTo("In Progress");
await bug.tag("Escalated");Providers
Linear
Linear is the default. If you omit provider, the package expects Linear credentials.
const tasks = await createTaskList({
apiKey: process.env.LINEAR_API_KEY,
team: "Core",
});You can also pass teamId directly:
const tasks = await createTaskList({
apiKey: process.env.LINEAR_API_KEY,
teamId: "team-uuid",
});Trello
Trello must be selected explicitly.
const tasks = await createTaskList({
provider: "trello",
apiKey: process.env.TRELLO_API_KEY,
token: process.env.TRELLO_API_TOKEN,
});Session API
const tasks = await createTaskList({ team: "Core" });
const projects = await tasks.projects();
const bot = await tasks.project("Bot");
const sameBot = await tasks.projectById(bot.id);
const issue = await tasks.task("ISS-123");Create a task by project name
await tasks.createTask({
project: "Bot",
title: "Ship changelog",
status: "Todo",
labels: ["Bug"],
priority: "High",
});Watch a project
const watch = tasks.watch({
project: "Bot",
whenStatus: "Todo",
moveTo: "In Progress",
everyMs: 60_000,
onTask: async (task) => {
console.log("Picked up:", task.title);
},
});
// Later
watch.stop();Project API
Projects are loaded snapshots with synchronous task filtering and explicit refresh.
const project = await tasks.project("Bot");
const openBugs = project.tasks({
status: "Todo",
labels: ["Bug"],
});
await project.createTask({
title: "Tighten auth flow",
description: "Handle expired sessions cleanly",
});
await project.refresh();Available project methods:
project.tasks(filter?)project.findTask(id)project.findStatus(name)project.findLabel(name)project.createTask({ title, ... })project.updateTasks(filter, changes)project.createLabel(name, options?)project.deleteLabel(name)project.refresh()
Task API
Tasks are stateful. Mutating methods update the current instance and return it.
const task = await tasks.task("ISS-123");
await task.update({
title: "Fix login on mobile",
labels: ["Bug", "Escalated"],
});
await task.moveTo("Done");
await task.tag("Verified");
await task.untag("Bug");
await task.refresh();Public fields:
idtitledescriptionstatusprojectIdlabelsurlpriority
Matching Rules
- Project, label, and status lookups use exact case-insensitive matching.
- Partial matches are intentionally rejected.
- Lookup errors include the available names to make fixes obvious.
Environment Variables
Optional environment variables:
LINEAR_API_KEY=...
TRELLO_API_KEY=...
TRELLO_API_TOKEN=...Errors
All custom errors extend TaskListError and include a machine-readable code.
PROVIDER_NOT_CONFIGUREDPROJECT_NOT_FOUNDTASK_NOT_FOUNDSTATUS_NOT_FOUNDLABEL_NOT_FOUNDTEAM_NOT_FOUNDAPI_ERRORLINEAR_GRAPHQL_ERROR
