taskin 4.1.3 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +292 -156
- package/package.json +8 -8
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -3456,6 +3456,51 @@ init_esm_shims();
|
|
|
3456
3456
|
// ../task-manager/src/index.ts
|
|
3457
3457
|
init_esm_shims();
|
|
3458
3458
|
|
|
3459
|
+
// ../task-manager/src/filter-tasks/index.ts
|
|
3460
|
+
init_esm_shims();
|
|
3461
|
+
|
|
3462
|
+
// ../task-manager/src/filter-tasks/filter-tasks.ts
|
|
3463
|
+
init_esm_shims();
|
|
3464
|
+
var EM_ABERTO = ["pending", "in-progress", "paused", "in-review", "blocked"];
|
|
3465
|
+
var ENCERRADOS = ["done", "canceled"];
|
|
3466
|
+
var contem = (valor, procurado) => valor !== void 0 && valor.toLowerCase().includes(procurado);
|
|
3467
|
+
function casaResponsavel(task, procurado) {
|
|
3468
|
+
const alvo = procurado.toLowerCase();
|
|
3469
|
+
return contem(task.assignee?.id, alvo) || contem(task.assignee?.name, alvo);
|
|
3470
|
+
}
|
|
3471
|
+
function filterTasks(tasks, criteria) {
|
|
3472
|
+
return tasks.filter((task) => {
|
|
3473
|
+
if (criteria.status !== void 0) {
|
|
3474
|
+
if (task.status !== criteria.status) return false;
|
|
3475
|
+
} else if (criteria.open && !EM_ABERTO.includes(task.status)) {
|
|
3476
|
+
return false;
|
|
3477
|
+
} else if (criteria.closed && !ENCERRADOS.includes(task.status)) {
|
|
3478
|
+
return false;
|
|
3479
|
+
}
|
|
3480
|
+
if (criteria.type !== void 0 && task.type !== criteria.type) return false;
|
|
3481
|
+
if (criteria.assignee !== void 0 && !casaResponsavel(task, criteria.assignee)) return false;
|
|
3482
|
+
if (criteria.text !== void 0) {
|
|
3483
|
+
const procurado = criteria.text.toLowerCase();
|
|
3484
|
+
const casa = task.id.toLowerCase().includes(procurado) || contem(task.title, procurado) || contem(task.status, procurado) || casaResponsavel(task, procurado);
|
|
3485
|
+
if (!casa) return false;
|
|
3486
|
+
}
|
|
3487
|
+
return true;
|
|
3488
|
+
});
|
|
3489
|
+
}
|
|
3490
|
+
function summarizeTask(task) {
|
|
3491
|
+
return {
|
|
3492
|
+
id: task.id,
|
|
3493
|
+
title: task.title,
|
|
3494
|
+
status: task.status,
|
|
3495
|
+
type: task.type,
|
|
3496
|
+
...task.assignee && { assignee: { id: task.assignee.id, name: task.assignee.name } },
|
|
3497
|
+
...task.order !== void 0 && { priority: task.order },
|
|
3498
|
+
...task.groupId && { groupId: task.groupId },
|
|
3499
|
+
...task.groupName && { groupName: task.groupName },
|
|
3500
|
+
...task.difficulty !== void 0 && { difficulty: task.difficulty }
|
|
3501
|
+
};
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3459
3504
|
// ../task-manager/src/metrics.types.ts
|
|
3460
3505
|
init_esm_shims();
|
|
3461
3506
|
|
|
@@ -3502,6 +3547,16 @@ var TaskManager = class {
|
|
|
3502
3547
|
await this.taskProvider.updateTask(updatedTask);
|
|
3503
3548
|
return updatedTask;
|
|
3504
3549
|
}
|
|
3550
|
+
/**
|
|
3551
|
+
* Every task the configured provider knows about.
|
|
3552
|
+
*
|
|
3553
|
+
* Pass-through on purpose: the manager owns the state transitions, not the
|
|
3554
|
+
* storage. Having it here is what lets a consumer holding only the manager —
|
|
3555
|
+
* the MCP server — answer "what work exists?".
|
|
3556
|
+
*/
|
|
3557
|
+
async getAllTasks() {
|
|
3558
|
+
return await this.taskProvider.getAllTasks();
|
|
3559
|
+
}
|
|
3505
3560
|
async finishTask(taskId) {
|
|
3506
3561
|
const task = await this.taskProvider.findTask(taskId);
|
|
3507
3562
|
if (!task) {
|
|
@@ -4313,7 +4368,7 @@ async function startDashboard(options) {
|
|
|
4313
4368
|
}
|
|
4314
4369
|
});
|
|
4315
4370
|
await wsServer.start();
|
|
4316
|
-
success(
|
|
4371
|
+
success(`WebSocket server running on ws://${host}:${wsPort}`);
|
|
4317
4372
|
info(`Starting dashboard server on http://${host}:${port}...`);
|
|
4318
4373
|
const isDev = __dirname2.includes("/src/");
|
|
4319
4374
|
const dashboardDist = isDev ? path8.join(__dirname2, "..", "..", "dashboard-dist") : path8.join(__dirname2, "..", "dashboard-dist");
|
|
@@ -4364,7 +4419,7 @@ async function startDashboard(options) {
|
|
|
4364
4419
|
if (actualPort !== port) {
|
|
4365
4420
|
warning(`Port ${port} was in use. Dashboard started on port ${actualPort}.`);
|
|
4366
4421
|
}
|
|
4367
|
-
success(
|
|
4422
|
+
success(`Dashboard available at http://${host}:${actualPort}`);
|
|
4368
4423
|
const filterParams = new URLSearchParams();
|
|
4369
4424
|
if (options.open) {
|
|
4370
4425
|
filterParams.set("filter", "open");
|
|
@@ -4396,7 +4451,7 @@ async function startDashboard(options) {
|
|
|
4396
4451
|
httpServer.close(() => resolve());
|
|
4397
4452
|
});
|
|
4398
4453
|
await wsServer.stop();
|
|
4399
|
-
success("
|
|
4454
|
+
success("Servers stopped");
|
|
4400
4455
|
process.exit(0);
|
|
4401
4456
|
};
|
|
4402
4457
|
process.on("SIGINT", cleanup);
|
|
@@ -4943,7 +4998,7 @@ async function finishTask(taskId, options, gitService) {
|
|
|
4943
4998
|
);
|
|
4944
4999
|
console.log(colors.secondary(` - Push: git push`));
|
|
4945
5000
|
console.log();
|
|
4946
|
-
info("
|
|
5001
|
+
info("Dry run complete");
|
|
4947
5002
|
return;
|
|
4948
5003
|
}
|
|
4949
5004
|
if (task.status === "done") {
|
|
@@ -4962,7 +5017,7 @@ async function finishTask(taskId, options, gitService) {
|
|
|
4962
5017
|
if (behavior.autoCommitStatusChange) {
|
|
4963
5018
|
const committed = await git.commitTaskStatusChangeOnBranch(normalizedId, "done", behavior.defaultBranch);
|
|
4964
5019
|
if (committed) {
|
|
4965
|
-
success("
|
|
5020
|
+
success("Auto-committed status change");
|
|
4966
5021
|
}
|
|
4967
5022
|
}
|
|
4968
5023
|
if (behavior.autoSync && behavior.originBranch && behavior.defaultBranch) {
|
|
@@ -4974,7 +5029,7 @@ async function finishTask(taskId, options, gitService) {
|
|
|
4974
5029
|
ciSkipTag: behavior.ciSkipTag
|
|
4975
5030
|
});
|
|
4976
5031
|
if (squashed) {
|
|
4977
|
-
success(
|
|
5032
|
+
success(`Squash commit pushed to ${behavior.originBranch}`);
|
|
4978
5033
|
}
|
|
4979
5034
|
} catch (squashError) {
|
|
4980
5035
|
error(
|
|
@@ -4990,7 +5045,7 @@ async function finishTask(taskId, options, gitService) {
|
|
|
4990
5045
|
cwd: process.cwd(),
|
|
4991
5046
|
stdio: "ignore"
|
|
4992
5047
|
});
|
|
4993
|
-
success("
|
|
5048
|
+
success("Auto-committed completed work");
|
|
4994
5049
|
} catch {
|
|
4995
5050
|
}
|
|
4996
5051
|
}
|
|
@@ -5227,7 +5282,7 @@ async function initializeTaskin(options) {
|
|
|
5227
5282
|
};
|
|
5228
5283
|
info("Creating configuration file...");
|
|
5229
5284
|
writeFileSync2(configFile, JSON.stringify(config, null, 2), "utf-8");
|
|
5230
|
-
success(
|
|
5285
|
+
success(`Created ${colors.highlight(".taskin.json")}`);
|
|
5231
5286
|
if (process.env.CI !== "true" && selectedProvider.id === "fs") {
|
|
5232
5287
|
await promptCreateFirstUser(cwd);
|
|
5233
5288
|
}
|
|
@@ -5310,7 +5365,7 @@ async function setupProviderConfig(provider, cwd) {
|
|
|
5310
5365
|
}));
|
|
5311
5366
|
const answers = await inquirer2.prompt(questions);
|
|
5312
5367
|
console.log();
|
|
5313
|
-
success(
|
|
5368
|
+
success(`${provider.name} configuration saved`);
|
|
5314
5369
|
return answers;
|
|
5315
5370
|
}
|
|
5316
5371
|
async function setupFileSystemProvider(cwd) {
|
|
@@ -5352,7 +5407,7 @@ This is a sample task created during Taskin initialization.
|
|
|
5352
5407
|
You can edit or delete this file. Use \`taskin list\` to see all tasks.
|
|
5353
5408
|
`;
|
|
5354
5409
|
writeFileSync2(sampleTaskFile, sampleTask, "utf-8");
|
|
5355
|
-
success(
|
|
5410
|
+
success(`Created sample task ${colors.highlight("task-001-setup-project.md")}`);
|
|
5356
5411
|
}
|
|
5357
5412
|
return {
|
|
5358
5413
|
tasksDir: "TASKS",
|
|
@@ -5397,7 +5452,7 @@ async function promptCreateFirstUser(cwd) {
|
|
|
5397
5452
|
email: answers.email
|
|
5398
5453
|
};
|
|
5399
5454
|
await userRegistry.saveUser(user);
|
|
5400
|
-
success(
|
|
5455
|
+
success(`User "${user.name}" (${user.email}) created successfully!`);
|
|
5401
5456
|
}
|
|
5402
5457
|
|
|
5403
5458
|
// src/commands/lint.ts
|
|
@@ -5473,8 +5528,17 @@ async function executeLint(options) {
|
|
|
5473
5528
|
console.log();
|
|
5474
5529
|
}
|
|
5475
5530
|
if (result.valid) {
|
|
5476
|
-
|
|
5531
|
+
if (notices.length === 0) {
|
|
5532
|
+
console.log(chalk5.green(`\u2705 All task files are valid!
|
|
5477
5533
|
`));
|
|
5534
|
+
} else {
|
|
5535
|
+
const partes = [
|
|
5536
|
+
result.warningCount > 0 ? `${result.warningCount} warning(s)` : "",
|
|
5537
|
+
result.infoCount > 0 ? `${result.infoCount} info` : ""
|
|
5538
|
+
].filter(Boolean);
|
|
5539
|
+
console.log(chalk5.green(`\u2705 No errors \u2014 ${partes.join(" and ")} above, listed for a human to decide.
|
|
5540
|
+
`));
|
|
5541
|
+
}
|
|
5478
5542
|
}
|
|
5479
5543
|
if (!result.valid && !options.fix) {
|
|
5480
5544
|
console.log(chalk5.blue(`\u{1F4A1} Run with --fix to automatically fix format issues
|
|
@@ -5509,6 +5573,10 @@ var listCommand = defineCommand({
|
|
|
5509
5573
|
{
|
|
5510
5574
|
flags: "--closed",
|
|
5511
5575
|
description: "Show only closed tasks (done, canceled)"
|
|
5576
|
+
},
|
|
5577
|
+
{
|
|
5578
|
+
flags: "--json",
|
|
5579
|
+
description: "Print the tasks as JSON, for other tools to consume"
|
|
5512
5580
|
}
|
|
5513
5581
|
],
|
|
5514
5582
|
handler: async (filter, options) => {
|
|
@@ -5517,36 +5585,28 @@ var listCommand = defineCommand({
|
|
|
5517
5585
|
});
|
|
5518
5586
|
async function listTasks(filter, options) {
|
|
5519
5587
|
requireTaskinProject();
|
|
5520
|
-
|
|
5588
|
+
const comoJson = options.json === true;
|
|
5589
|
+
if (!comoJson) {
|
|
5590
|
+
printHeader("Task List", "\u{1F4CA}");
|
|
5591
|
+
}
|
|
5521
5592
|
const { provider: taskProvider } = await resolveTaskProvider();
|
|
5522
5593
|
const tasks = await taskProvider.getAllTasks();
|
|
5523
|
-
if (tasks.length === 0) {
|
|
5594
|
+
if (tasks.length === 0 && !comoJson) {
|
|
5524
5595
|
console.log(colors.warning("No tasks found in TASKS/ directory"));
|
|
5525
5596
|
return;
|
|
5526
5597
|
}
|
|
5527
|
-
const
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
}
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
}
|
|
5540
|
-
if (options.assignee) {
|
|
5541
|
-
filteredTasks = filteredTasks.filter(
|
|
5542
|
-
(t) => t.assignee?.name.toLowerCase().includes(options.assignee.toLowerCase()) || t.assignee?.id.toLowerCase().includes(options.assignee.toLowerCase())
|
|
5543
|
-
);
|
|
5544
|
-
}
|
|
5545
|
-
if (filter) {
|
|
5546
|
-
const lowerFilter = filter.toLowerCase();
|
|
5547
|
-
filteredTasks = filteredTasks.filter(
|
|
5548
|
-
(t) => t.id.includes(lowerFilter) || t.title.toLowerCase().includes(lowerFilter) || t.status.toLowerCase().includes(lowerFilter) || t.assignee?.name.toLowerCase().includes(lowerFilter) || t.assignee?.id.toLowerCase().includes(lowerFilter)
|
|
5549
|
-
);
|
|
5598
|
+
const criteria = {
|
|
5599
|
+
...options.status && { status: options.status },
|
|
5600
|
+
...options.type && { type: options.type },
|
|
5601
|
+
...options.assignee && { assignee: options.assignee },
|
|
5602
|
+
...options.open && { open: true },
|
|
5603
|
+
...options.closed && { closed: true },
|
|
5604
|
+
...filter && { text: filter }
|
|
5605
|
+
};
|
|
5606
|
+
const filteredTasks = filterTasks(tasks, criteria);
|
|
5607
|
+
if (comoJson) {
|
|
5608
|
+
console.log(JSON.stringify(filteredTasks.map(summarizeTask), null, 2));
|
|
5609
|
+
return;
|
|
5550
5610
|
}
|
|
5551
5611
|
if (filteredTasks.length === 0) {
|
|
5552
5612
|
console.log(colors.warning("No tasks match the filters"));
|
|
@@ -5625,6 +5685,72 @@ init_esm_shims();
|
|
|
5625
5685
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
5626
5686
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5627
5687
|
import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5688
|
+
|
|
5689
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/index.js
|
|
5690
|
+
init_esm_shims();
|
|
5691
|
+
|
|
5692
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/filter-tasks/index.js
|
|
5693
|
+
init_esm_shims();
|
|
5694
|
+
|
|
5695
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/filter-tasks/filter-tasks.js
|
|
5696
|
+
init_esm_shims();
|
|
5697
|
+
var EM_ABERTO2 = ["pending", "in-progress", "paused", "in-review", "blocked"];
|
|
5698
|
+
var ENCERRADOS2 = ["done", "canceled"];
|
|
5699
|
+
var contem2 = (valor, procurado) => valor !== void 0 && valor.toLowerCase().includes(procurado);
|
|
5700
|
+
function casaResponsavel2(task, procurado) {
|
|
5701
|
+
const alvo = procurado.toLowerCase();
|
|
5702
|
+
return contem2(task.assignee?.id, alvo) || contem2(task.assignee?.name, alvo);
|
|
5703
|
+
}
|
|
5704
|
+
function filterTasks2(tasks, criteria) {
|
|
5705
|
+
return tasks.filter((task) => {
|
|
5706
|
+
if (criteria.status !== void 0) {
|
|
5707
|
+
if (task.status !== criteria.status)
|
|
5708
|
+
return false;
|
|
5709
|
+
} else if (criteria.open && !EM_ABERTO2.includes(task.status)) {
|
|
5710
|
+
return false;
|
|
5711
|
+
} else if (criteria.closed && !ENCERRADOS2.includes(task.status)) {
|
|
5712
|
+
return false;
|
|
5713
|
+
}
|
|
5714
|
+
if (criteria.type !== void 0 && task.type !== criteria.type)
|
|
5715
|
+
return false;
|
|
5716
|
+
if (criteria.assignee !== void 0 && !casaResponsavel2(task, criteria.assignee))
|
|
5717
|
+
return false;
|
|
5718
|
+
if (criteria.text !== void 0) {
|
|
5719
|
+
const procurado = criteria.text.toLowerCase();
|
|
5720
|
+
const casa = task.id.toLowerCase().includes(procurado) || contem2(task.title, procurado) || contem2(task.status, procurado) || casaResponsavel2(task, procurado);
|
|
5721
|
+
if (!casa)
|
|
5722
|
+
return false;
|
|
5723
|
+
}
|
|
5724
|
+
return true;
|
|
5725
|
+
});
|
|
5726
|
+
}
|
|
5727
|
+
function summarizeTask2(task) {
|
|
5728
|
+
return {
|
|
5729
|
+
id: task.id,
|
|
5730
|
+
title: task.title,
|
|
5731
|
+
status: task.status,
|
|
5732
|
+
type: task.type,
|
|
5733
|
+
...task.assignee && { assignee: { id: task.assignee.id, name: task.assignee.name } },
|
|
5734
|
+
...task.order !== void 0 && { priority: task.order },
|
|
5735
|
+
...task.groupId && { groupId: task.groupId },
|
|
5736
|
+
...task.groupName && { groupName: task.groupName },
|
|
5737
|
+
...task.difficulty !== void 0 && { difficulty: task.difficulty }
|
|
5738
|
+
};
|
|
5739
|
+
}
|
|
5740
|
+
|
|
5741
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/metrics.types.js
|
|
5742
|
+
init_esm_shims();
|
|
5743
|
+
|
|
5744
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/task-manager.js
|
|
5745
|
+
init_esm_shims();
|
|
5746
|
+
|
|
5747
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/task-manager.types.js
|
|
5748
|
+
init_esm_shims();
|
|
5749
|
+
|
|
5750
|
+
// node_modules/@opentask/taskin-task-server-mcp/node_modules/@opentask/taskin-task-manager/dist/user-registry.types.js
|
|
5751
|
+
init_esm_shims();
|
|
5752
|
+
|
|
5753
|
+
// node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.js
|
|
5628
5754
|
import { TaskIdSchema as TaskIdSchema4 } from "@opentask/taskin-types";
|
|
5629
5755
|
function readTaskId(raw) {
|
|
5630
5756
|
if (typeof raw !== "string")
|
|
@@ -5643,7 +5769,7 @@ function invalidTaskId(raw) {
|
|
|
5643
5769
|
isError: true
|
|
5644
5770
|
};
|
|
5645
5771
|
}
|
|
5646
|
-
var TaskMCPServer = class {
|
|
5772
|
+
var TaskMCPServer = class _TaskMCPServer {
|
|
5647
5773
|
server;
|
|
5648
5774
|
taskManager;
|
|
5649
5775
|
config;
|
|
@@ -5682,12 +5808,7 @@ var TaskMCPServer = class {
|
|
|
5682
5808
|
arguments: request.params.arguments
|
|
5683
5809
|
});
|
|
5684
5810
|
return {
|
|
5685
|
-
content:
|
|
5686
|
-
{
|
|
5687
|
-
type: "text",
|
|
5688
|
-
text: result.content
|
|
5689
|
-
}
|
|
5690
|
-
],
|
|
5811
|
+
content: result.content,
|
|
5691
5812
|
isError: result.isError
|
|
5692
5813
|
};
|
|
5693
5814
|
});
|
|
@@ -5753,6 +5874,22 @@ var TaskMCPServer = class {
|
|
|
5753
5874
|
*/
|
|
5754
5875
|
listTools() {
|
|
5755
5876
|
const tools = [
|
|
5877
|
+
{
|
|
5878
|
+
name: "list_tasks",
|
|
5879
|
+
description: "List the tasks in the project. Returns a JSON array with what identifies each task \u2014 id, title, status, type, assignee \u2014 without the markdown body. Fetch a task body by id after choosing one.",
|
|
5880
|
+
inputSchema: {
|
|
5881
|
+
type: "object",
|
|
5882
|
+
properties: {
|
|
5883
|
+
status: { type: "string", description: "Exact status (pending, in-progress, done, ...)" },
|
|
5884
|
+
type: { type: "string", description: "Exact type (feat, fix, chore, ...)" },
|
|
5885
|
+
assignee: { type: "string", description: "Assignee id or name, whole or in part" },
|
|
5886
|
+
open: { type: "boolean", description: "Only tasks still open" },
|
|
5887
|
+
closed: { type: "boolean", description: "Only tasks already closed" },
|
|
5888
|
+
text: { type: "string", description: "Free text over id, title, status and assignee" }
|
|
5889
|
+
},
|
|
5890
|
+
required: []
|
|
5891
|
+
}
|
|
5892
|
+
},
|
|
5756
5893
|
{
|
|
5757
5894
|
name: "start_task",
|
|
5758
5895
|
description: "Start working on a task by changing its status to in-progress",
|
|
@@ -5791,6 +5928,8 @@ var TaskMCPServer = class {
|
|
|
5791
5928
|
try {
|
|
5792
5929
|
this.log(`Calling tool: ${params.name}`, params.arguments);
|
|
5793
5930
|
switch (params.name) {
|
|
5931
|
+
case "list_tasks":
|
|
5932
|
+
return await this.handleListTasks(params.arguments ?? {});
|
|
5794
5933
|
case "start_task": {
|
|
5795
5934
|
const taskId = readTaskId(params.arguments?.taskId);
|
|
5796
5935
|
return taskId ? await this.handleStartTask(taskId) : invalidTaskId(params.arguments?.taskId);
|
|
@@ -5994,6 +6133,35 @@ Let me start by marking the task as done using the finish_task tool.`
|
|
|
5994
6133
|
throw new Error(`Unknown prompt: ${params.name}`);
|
|
5995
6134
|
}
|
|
5996
6135
|
}
|
|
6136
|
+
/**
|
|
6137
|
+
* Le e seleciona as tarefas, pela mesma seam que o CLI usa.
|
|
6138
|
+
*
|
|
6139
|
+
* `filterTasks` e `summarizeTask` vivem no pacote agnostico justamente para
|
|
6140
|
+
* que a resposta aqui e a de `taskin list --json` nao possam divergir — ja
|
|
6141
|
+
* houve duas filtragens discordando no repositorio.
|
|
6142
|
+
*/
|
|
6143
|
+
async selecionarTarefas(criteria) {
|
|
6144
|
+
const tasks = await this.taskManager.getAllTasks();
|
|
6145
|
+
return filterTasks2(tasks, criteria).map(summarizeTask2);
|
|
6146
|
+
}
|
|
6147
|
+
/** Converte os argumentos crus da chamada MCP no criterio tipado. */
|
|
6148
|
+
static criterioDe(args) {
|
|
6149
|
+
return {
|
|
6150
|
+
...typeof args.status === "string" && { status: args.status },
|
|
6151
|
+
...typeof args.type === "string" && { type: args.type },
|
|
6152
|
+
...typeof args.assignee === "string" && { assignee: args.assignee },
|
|
6153
|
+
...args.open === true && { open: true },
|
|
6154
|
+
...args.closed === true && { closed: true },
|
|
6155
|
+
...typeof args.text === "string" && { text: args.text }
|
|
6156
|
+
};
|
|
6157
|
+
}
|
|
6158
|
+
async handleListTasks(args) {
|
|
6159
|
+
const tarefas = await this.selecionarTarefas(_TaskMCPServer.criterioDe(args));
|
|
6160
|
+
return {
|
|
6161
|
+
content: [{ type: "text", text: JSON.stringify(tarefas, null, 2) }],
|
|
6162
|
+
isError: false
|
|
6163
|
+
};
|
|
6164
|
+
}
|
|
5997
6165
|
/**
|
|
5998
6166
|
* List available resources
|
|
5999
6167
|
*/
|
|
@@ -6016,15 +6184,13 @@ Let me start by marking the task as done using the finish_task tool.`
|
|
|
6016
6184
|
this.log(`Reading resource: ${params.uri}`);
|
|
6017
6185
|
const uri = params.uri;
|
|
6018
6186
|
if (uri === "taskin://tasks") {
|
|
6187
|
+
const tarefas = await this.selecionarTarefas({});
|
|
6019
6188
|
return {
|
|
6020
6189
|
contents: [
|
|
6021
6190
|
{
|
|
6022
6191
|
uri,
|
|
6023
6192
|
mimeType: "application/json",
|
|
6024
|
-
text: JSON.stringify(
|
|
6025
|
-
message: "Task list would be here",
|
|
6026
|
-
note: "Requires ITaskProvider integration"
|
|
6027
|
-
})
|
|
6193
|
+
text: JSON.stringify(tarefas, null, 2)
|
|
6028
6194
|
}
|
|
6029
6195
|
]
|
|
6030
6196
|
};
|
|
@@ -6083,7 +6249,7 @@ async function startMCPServer(options) {
|
|
|
6083
6249
|
});
|
|
6084
6250
|
info("Starting MCP server...");
|
|
6085
6251
|
await mcpServer.connect({ transport });
|
|
6086
|
-
success("
|
|
6252
|
+
success("MCP server started successfully");
|
|
6087
6253
|
info("");
|
|
6088
6254
|
info(chalk6.bold("Server Information:"));
|
|
6089
6255
|
info(` \u2022 Transport: ${chalk6.cyan(transport)}`);
|
|
@@ -6105,7 +6271,7 @@ async function startMCPServer(options) {
|
|
|
6105
6271
|
info("");
|
|
6106
6272
|
const cleanup = async () => {
|
|
6107
6273
|
info("\nShutting down MCP server...");
|
|
6108
|
-
success("
|
|
6274
|
+
success("Server stopped");
|
|
6109
6275
|
process.exit(0);
|
|
6110
6276
|
};
|
|
6111
6277
|
process.on("SIGINT", cleanup);
|
|
@@ -6278,7 +6444,7 @@ async function createTask(options, gitService) {
|
|
|
6278
6444
|
console.log(colors.secondary(`\u{1F4C1} Path: ${createdPath}`));
|
|
6279
6445
|
}
|
|
6280
6446
|
if (autoSyncActive) {
|
|
6281
|
-
success("
|
|
6447
|
+
success("Task committed and pushed to remote");
|
|
6282
6448
|
}
|
|
6283
6449
|
console.log();
|
|
6284
6450
|
console.log(colors.info("Next steps:"));
|
|
@@ -6433,7 +6599,7 @@ async function pauseTask(taskId, options) {
|
|
|
6433
6599
|
console.log(colors.secondary(` - Add all changes: git add -A`));
|
|
6434
6600
|
console.log(colors.secondary(` - Commit: git commit -m "${commitMessage2}"`));
|
|
6435
6601
|
console.log();
|
|
6436
|
-
info("
|
|
6602
|
+
info("Dry run complete");
|
|
6437
6603
|
return;
|
|
6438
6604
|
}
|
|
6439
6605
|
if (task.status !== "in-progress") {
|
|
@@ -6467,7 +6633,7 @@ async function pauseTask(taskId, options) {
|
|
|
6467
6633
|
}
|
|
6468
6634
|
await taskManager.pauseTask(normalizedId);
|
|
6469
6635
|
success("Task paused successfully!");
|
|
6470
|
-
success("
|
|
6636
|
+
success("Auto-committed work in progress");
|
|
6471
6637
|
info("Status updated to paused");
|
|
6472
6638
|
console.log();
|
|
6473
6639
|
info("Next steps:");
|
|
@@ -6654,7 +6820,7 @@ async function reviewTask(taskId, options) {
|
|
|
6654
6820
|
});
|
|
6655
6821
|
console.log();
|
|
6656
6822
|
}
|
|
6657
|
-
info("
|
|
6823
|
+
info("Dry run complete");
|
|
6658
6824
|
return;
|
|
6659
6825
|
}
|
|
6660
6826
|
if (reviewHooks.pre && reviewHooks.pre.length > 0 && !options.skipMerge) {
|
|
@@ -6673,7 +6839,7 @@ async function reviewTask(taskId, options) {
|
|
|
6673
6839
|
const failedPre = preResults.find((r) => !r.success);
|
|
6674
6840
|
if (failedPre && !hookSettings.continueOnError) {
|
|
6675
6841
|
console.log();
|
|
6676
|
-
error("
|
|
6842
|
+
error("Pre-review hooks failed!");
|
|
6677
6843
|
error("Fix the errors above and try again.");
|
|
6678
6844
|
process.exit(1);
|
|
6679
6845
|
}
|
|
@@ -6695,7 +6861,7 @@ async function reviewTask(taskId, options) {
|
|
|
6695
6861
|
const failedCheck = duringResults.find((r) => !r.success);
|
|
6696
6862
|
if (failedCheck && !hookSettings.continueOnError) {
|
|
6697
6863
|
console.log();
|
|
6698
|
-
error("
|
|
6864
|
+
error("Review checks failed!");
|
|
6699
6865
|
error("Fix the errors above and try again.");
|
|
6700
6866
|
console.log();
|
|
6701
6867
|
info("Tip: Run individual checks to see full error details");
|
|
@@ -6705,7 +6871,7 @@ async function reviewTask(taskId, options) {
|
|
|
6705
6871
|
}
|
|
6706
6872
|
info("Marking task as ready for review...");
|
|
6707
6873
|
const updatedTask = await taskManager.reviewTask(task.id);
|
|
6708
|
-
success(
|
|
6874
|
+
success(`Task ${updatedTask.id} status changed to: ${updatedTask.status}`);
|
|
6709
6875
|
if (behavior.autoCommitStatusChange) {
|
|
6710
6876
|
try {
|
|
6711
6877
|
const message = appendCiSkipTag(
|
|
@@ -6716,7 +6882,7 @@ async function reviewTask(taskId, options) {
|
|
|
6716
6882
|
cwd: monorepoRoot,
|
|
6717
6883
|
stdio: "ignore"
|
|
6718
6884
|
});
|
|
6719
|
-
success("
|
|
6885
|
+
success("Auto-committed status change");
|
|
6720
6886
|
} catch {
|
|
6721
6887
|
}
|
|
6722
6888
|
}
|
|
@@ -6737,7 +6903,7 @@ async function reviewTask(taskId, options) {
|
|
|
6737
6903
|
console.log();
|
|
6738
6904
|
}
|
|
6739
6905
|
const totalDuration = [...reviewHooks.pre ?? [], ...reviewHooks.during ?? [], ...reviewHooks.post ?? []].length > 0 ? "with hooks" : "";
|
|
6740
|
-
success(
|
|
6906
|
+
success(`Task ready for review! ${totalDuration}`);
|
|
6741
6907
|
await sendTaskNotification(configManager, "task:review", normalizedId, task.title);
|
|
6742
6908
|
if (options.sound !== false) {
|
|
6743
6909
|
await playSound("review");
|
|
@@ -6830,7 +6996,7 @@ async function startTask(taskId, _options, gitService) {
|
|
|
6830
6996
|
)
|
|
6831
6997
|
);
|
|
6832
6998
|
console.log();
|
|
6833
|
-
info("
|
|
6999
|
+
info("Dry run complete");
|
|
6834
7000
|
return;
|
|
6835
7001
|
}
|
|
6836
7002
|
if (task.status === "in-progress") {
|
|
@@ -6849,7 +7015,7 @@ async function startTask(taskId, _options, gitService) {
|
|
|
6849
7015
|
if (behavior.autoCommitStatusChange) {
|
|
6850
7016
|
const committed = await git.commitTaskStatusChangeOnBranch(normalizedId, "in-progress", behavior.defaultBranch);
|
|
6851
7017
|
if (committed) {
|
|
6852
|
-
success("
|
|
7018
|
+
success("Auto-committed status change");
|
|
6853
7019
|
}
|
|
6854
7020
|
}
|
|
6855
7021
|
console.log();
|
|
@@ -7068,102 +7234,72 @@ function getStatusEmoji(status) {
|
|
|
7068
7234
|
|
|
7069
7235
|
// src/lib/help.ts
|
|
7070
7236
|
init_esm_shims();
|
|
7071
|
-
|
|
7237
|
+
var EXEMPLOS = {
|
|
7238
|
+
init: ["taskin init", "taskin setup"],
|
|
7239
|
+
list: ["taskin list", "taskin list pending", "taskin list --status in-progress", "taskin list --type feat"],
|
|
7240
|
+
new: [
|
|
7241
|
+
'taskin new -t feat -T "Add login" -d "Implement user authentication"',
|
|
7242
|
+
'taskin new --type fix --title "Fix bug" --user "John"',
|
|
7243
|
+
'taskin create -t docs -T "Update README"'
|
|
7244
|
+
],
|
|
7245
|
+
start: ["taskin start 001", "taskin start task-001", "taskin start 001 --force"],
|
|
7246
|
+
pause: ["taskin pause 001", 'taskin pause 001 -m "saving progress"'],
|
|
7247
|
+
review: ["taskin review 001", "taskin review 001 --dry-run"],
|
|
7248
|
+
finish: ["taskin finish 001", "taskin done task-001"],
|
|
7249
|
+
stats: ["taskin stats", "taskin stats --team", "taskin stats --period month"],
|
|
7250
|
+
config: ["taskin config", "taskin config --level assisted", "taskin config --show"],
|
|
7251
|
+
export: ["taskin export", "taskin export --format json"],
|
|
7252
|
+
lint: ["taskin lint", "taskin lint --fix", "taskin lint --fix --metadata-style=list"],
|
|
7253
|
+
dashboard: ["taskin dashboard", "taskin dashboard --port 3000", "taskin dashboard --filter-open"],
|
|
7254
|
+
"mcp-server": ["taskin mcp-server", "taskin mcp"],
|
|
7255
|
+
notify: ["taskin notify --event task:done --task 001"]
|
|
7256
|
+
};
|
|
7257
|
+
var ICONE_PADRAO = "\u2022";
|
|
7258
|
+
function separarIcone(descricao) {
|
|
7259
|
+
const match = descricao.match(new RegExp("^(\\p{Extended_Pictographic}\\uFE0F?)\\s+(.*)$", "su"));
|
|
7260
|
+
return match?.[1] && match[2] !== void 0 ? { icone: match[1], texto: match[2] } : { icone: ICONE_PADRAO, texto: descricao };
|
|
7261
|
+
}
|
|
7262
|
+
var OCULTOS = ["help"];
|
|
7263
|
+
function assinatura(cmd) {
|
|
7264
|
+
const argumentos = cmd.usage().replace("[options]", "").trim();
|
|
7265
|
+
const nome = colors.highlight(`taskin ${cmd.name()}`);
|
|
7266
|
+
return argumentos ? nome + colors.normal(` ${argumentos}`) : nome;
|
|
7267
|
+
}
|
|
7268
|
+
function detalhes(cmd) {
|
|
7269
|
+
const partes = [];
|
|
7270
|
+
const aliases = cmd.aliases();
|
|
7271
|
+
if (aliases.length > 0) {
|
|
7272
|
+
partes.push(`Alias: ${aliases.join(", ")}`);
|
|
7273
|
+
}
|
|
7274
|
+
const flags = cmd.options.map((opcao) => opcao.flags.split(",")[0]?.trim()).filter(Boolean);
|
|
7275
|
+
if (flags.length > 0) {
|
|
7276
|
+
partes.push(`Options: ${flags.join(", ")}`);
|
|
7277
|
+
}
|
|
7278
|
+
return partes.length > 0 ? partes.join(" \xB7 ") : void 0;
|
|
7279
|
+
}
|
|
7280
|
+
function showCustomHelp(program2) {
|
|
7072
7281
|
printHeader("Taskin - Task Management System", icons.rocket);
|
|
7073
7282
|
console.log(colors.info("\u{1F4CB} AVAILABLE COMMANDS"));
|
|
7074
7283
|
console.log(colors.highlight("\u2550".repeat(60)));
|
|
7075
7284
|
console.log();
|
|
7076
|
-
const
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
name: colors.highlight("taskin new"),
|
|
7093
|
-
alias: colors.secondary("Alias: create"),
|
|
7094
|
-
description: "Create a new task",
|
|
7095
|
-
examples: [
|
|
7096
|
-
'taskin new -t feat -T "Add login" -d "Implement user authentication"',
|
|
7097
|
-
'taskin new --type fix --title "Fix bug" --user "John"',
|
|
7098
|
-
'taskin create -t docs -T "Update README"'
|
|
7099
|
-
],
|
|
7100
|
-
icon: "\u{1F4DD}"
|
|
7101
|
-
},
|
|
7102
|
-
{
|
|
7103
|
-
name: colors.highlight("taskin start") + colors.normal(" <task-id>"),
|
|
7104
|
-
alias: colors.secondary("Alias: begin"),
|
|
7105
|
-
description: "Start working on a task (suggests commits)",
|
|
7106
|
-
examples: ["taskin start 001", "taskin start task-001", "taskin start 001 --force"],
|
|
7107
|
-
icon: "\u{1F680}"
|
|
7108
|
-
},
|
|
7109
|
-
{
|
|
7110
|
-
name: colors.highlight("taskin pause") + colors.normal(" <task-id>"),
|
|
7111
|
-
alias: colors.secondary("Alias: stop"),
|
|
7112
|
-
description: "Pause a task (auto-commits work in progress)",
|
|
7113
|
-
examples: ["taskin pause 001", 'taskin pause 001 -m "saving progress"'],
|
|
7114
|
-
icon: "\u23F8\uFE0F"
|
|
7115
|
-
},
|
|
7116
|
-
{
|
|
7117
|
-
name: colors.highlight("taskin finish") + colors.normal(" <task-id>"),
|
|
7118
|
-
alias: colors.secondary("Alias: done"),
|
|
7119
|
-
description: "Finish a task (suggests commits)",
|
|
7120
|
-
examples: ["taskin finish 001", "taskin done task-001"],
|
|
7121
|
-
icon: "\u2705"
|
|
7122
|
-
},
|
|
7123
|
-
{
|
|
7124
|
-
name: colors.highlight("taskin config") + colors.normal(" [options]"),
|
|
7125
|
-
alias: colors.secondary("Options: --level <manual|assisted|autopilot>"),
|
|
7126
|
-
description: "Configure automation level",
|
|
7127
|
-
examples: ["taskin config", "taskin config --level assisted", "taskin config --level autopilot"],
|
|
7128
|
-
icon: "\u2699\uFE0F"
|
|
7129
|
-
},
|
|
7130
|
-
{
|
|
7131
|
-
name: colors.highlight("taskin lint") + colors.normal(" [options]"),
|
|
7132
|
-
alias: colors.secondary("Options: -p, --path <directory>"),
|
|
7133
|
-
description: "Validate task markdown files",
|
|
7134
|
-
examples: ["taskin lint", "taskin lint --path ./TASKS", "taskin lint -p /path/to/tasks"],
|
|
7135
|
-
icon: "\u{1F50D}"
|
|
7136
|
-
},
|
|
7137
|
-
{
|
|
7138
|
-
name: colors.highlight("taskin dashboard") + colors.normal(" [options]"),
|
|
7139
|
-
alias: colors.secondary("Options: --host, --port, --filter-open, --filter-closed"),
|
|
7140
|
-
description: "Start the web dashboard",
|
|
7141
|
-
examples: [
|
|
7142
|
-
"taskin dashboard",
|
|
7143
|
-
"taskin dashboard --port 3000",
|
|
7144
|
-
"taskin dashboard --filter-open",
|
|
7145
|
-
"taskin dashboard --filter-closed -o"
|
|
7146
|
-
],
|
|
7147
|
-
icon: "\u{1F4CA}"
|
|
7148
|
-
},
|
|
7149
|
-
{
|
|
7150
|
-
name: colors.highlight("taskin mcp-server"),
|
|
7151
|
-
alias: colors.secondary("Alias: mcp"),
|
|
7152
|
-
description: "Start MCP server for Claude Desktop integration",
|
|
7153
|
-
examples: ["taskin mcp-server", "taskin mcp"],
|
|
7154
|
-
icon: "\u{1F916}"
|
|
7285
|
+
const comandos = program2.commands.filter((cmd) => !OCULTOS.includes(cmd.name()));
|
|
7286
|
+
comandos.forEach((cmd, index) => {
|
|
7287
|
+
const exemplos = EXEMPLOS[cmd.name()] ?? [];
|
|
7288
|
+
const { icone, texto } = separarIcone(cmd.description());
|
|
7289
|
+
console.log(colors.warning(`${icone} ${assinatura(cmd)}`));
|
|
7290
|
+
const linhaDeDetalhes = detalhes(cmd);
|
|
7291
|
+
if (linhaDeDetalhes) {
|
|
7292
|
+
console.log(colors.normal(` ${colors.secondary(linhaDeDetalhes)}`));
|
|
7293
|
+
}
|
|
7294
|
+
console.log(colors.info(` ${texto}`));
|
|
7295
|
+
if (exemplos.length > 0) {
|
|
7296
|
+
console.log();
|
|
7297
|
+
console.log(colors.normal(` ${colors.info("\u{1F4DD} Examples:")}`));
|
|
7298
|
+
for (const exemplo of exemplos) {
|
|
7299
|
+
console.log(colors.secondary(` ${exemplo}`));
|
|
7300
|
+
}
|
|
7155
7301
|
}
|
|
7156
|
-
|
|
7157
|
-
commands.forEach((cmd, index) => {
|
|
7158
|
-
console.log(colors.warning(`${cmd.icon} ${cmd.name}`));
|
|
7159
|
-
console.log(colors.normal(` ${cmd.alias}`));
|
|
7160
|
-
console.log(colors.info(` ${cmd.description}`));
|
|
7161
|
-
console.log();
|
|
7162
|
-
console.log(colors.normal(` ${colors.info("\u{1F4DD} Examples:")}`));
|
|
7163
|
-
cmd.examples.forEach((example) => {
|
|
7164
|
-
console.log(colors.secondary(` ${example}`));
|
|
7165
|
-
});
|
|
7166
|
-
if (index < commands.length - 1) {
|
|
7302
|
+
if (index < comandos.length - 1) {
|
|
7167
7303
|
console.log();
|
|
7168
7304
|
console.log(colors.normal(` ${colors.secondary("\u2500".repeat(50))}`));
|
|
7169
7305
|
console.log();
|
|
@@ -7565,7 +7701,7 @@ var program = new Command();
|
|
|
7565
7701
|
program.name("taskin").description("\u{1F680} Task Management System").version(getVersion());
|
|
7566
7702
|
program.helpOption("-h, --help", "Display help information");
|
|
7567
7703
|
program.command("help").description("Show help information").action(() => {
|
|
7568
|
-
showCustomHelp();
|
|
7704
|
+
showCustomHelp(program);
|
|
7569
7705
|
});
|
|
7570
7706
|
initCommand(program);
|
|
7571
7707
|
listCommand(program);
|
|
@@ -7582,15 +7718,15 @@ dashboardCommand(program);
|
|
|
7582
7718
|
mcpServerCommand(program);
|
|
7583
7719
|
notifyCommand(program);
|
|
7584
7720
|
program.on("option:help", () => {
|
|
7585
|
-
showCustomHelp();
|
|
7721
|
+
showCustomHelp(program);
|
|
7586
7722
|
process.exit(0);
|
|
7587
7723
|
});
|
|
7588
7724
|
if (process.argv.length <= 2) {
|
|
7589
|
-
showCustomHelp();
|
|
7725
|
+
showCustomHelp(program);
|
|
7590
7726
|
process.exit(0);
|
|
7591
7727
|
}
|
|
7592
7728
|
if (process.argv.length === 3 && (process.argv[2] === "--help" || process.argv[2] === "-h")) {
|
|
7593
|
-
showCustomHelp();
|
|
7729
|
+
showCustomHelp(program);
|
|
7594
7730
|
process.exit(0);
|
|
7595
7731
|
}
|
|
7596
7732
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taskin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Task management system integrated with Git workflows",
|
|
5
5
|
"motivation": "Provide a CLI tool for task management integrated with Git workflows",
|
|
6
6
|
"solve": "Simplifies task tracking and management directly from the command line",
|
|
@@ -79,13 +79,13 @@
|
|
|
79
79
|
"play-sound": "^1.1.6",
|
|
80
80
|
"ws": "^8.18.3",
|
|
81
81
|
"zod": "^3.25.76",
|
|
82
|
-
"@opentask/taskin-file-system-provider": "3.2.
|
|
83
|
-
"@opentask/taskin-
|
|
84
|
-
"@opentask/taskin-task-server-
|
|
85
|
-
"@opentask/taskin-task-
|
|
86
|
-
"@opentask/taskin-
|
|
87
|
-
"@opentask/taskin-
|
|
88
|
-
"@opentask/taskin-
|
|
82
|
+
"@opentask/taskin-file-system-provider": "3.2.4",
|
|
83
|
+
"@opentask/taskin-git-utils": "3.0.3",
|
|
84
|
+
"@opentask/taskin-task-server-mcp": "0.3.0",
|
|
85
|
+
"@opentask/taskin-task-manager": "3.1.0",
|
|
86
|
+
"@opentask/taskin-task-server-ws": "0.3.3",
|
|
87
|
+
"@opentask/taskin-types": "2.2.0",
|
|
88
|
+
"@opentask/taskin-utils": "1.1.1"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@types/node": "^20.19.24",
|