taskin 4.1.4 → 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 +282 -155
- package/package.json +7 -7
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
|
|
@@ -5518,6 +5573,10 @@ var listCommand = defineCommand({
|
|
|
5518
5573
|
{
|
|
5519
5574
|
flags: "--closed",
|
|
5520
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"
|
|
5521
5580
|
}
|
|
5522
5581
|
],
|
|
5523
5582
|
handler: async (filter, options) => {
|
|
@@ -5526,36 +5585,28 @@ var listCommand = defineCommand({
|
|
|
5526
5585
|
});
|
|
5527
5586
|
async function listTasks(filter, options) {
|
|
5528
5587
|
requireTaskinProject();
|
|
5529
|
-
|
|
5588
|
+
const comoJson = options.json === true;
|
|
5589
|
+
if (!comoJson) {
|
|
5590
|
+
printHeader("Task List", "\u{1F4CA}");
|
|
5591
|
+
}
|
|
5530
5592
|
const { provider: taskProvider } = await resolveTaskProvider();
|
|
5531
5593
|
const tasks = await taskProvider.getAllTasks();
|
|
5532
|
-
if (tasks.length === 0) {
|
|
5594
|
+
if (tasks.length === 0 && !comoJson) {
|
|
5533
5595
|
console.log(colors.warning("No tasks found in TASKS/ directory"));
|
|
5534
5596
|
return;
|
|
5535
5597
|
}
|
|
5536
|
-
const
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
}
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
}
|
|
5549
|
-
if (options.assignee) {
|
|
5550
|
-
filteredTasks = filteredTasks.filter(
|
|
5551
|
-
(t) => t.assignee?.name.toLowerCase().includes(options.assignee.toLowerCase()) || t.assignee?.id.toLowerCase().includes(options.assignee.toLowerCase())
|
|
5552
|
-
);
|
|
5553
|
-
}
|
|
5554
|
-
if (filter) {
|
|
5555
|
-
const lowerFilter = filter.toLowerCase();
|
|
5556
|
-
filteredTasks = filteredTasks.filter(
|
|
5557
|
-
(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)
|
|
5558
|
-
);
|
|
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;
|
|
5559
5610
|
}
|
|
5560
5611
|
if (filteredTasks.length === 0) {
|
|
5561
5612
|
console.log(colors.warning("No tasks match the filters"));
|
|
@@ -5634,6 +5685,72 @@ init_esm_shims();
|
|
|
5634
5685
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
5635
5686
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5636
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
|
|
5637
5754
|
import { TaskIdSchema as TaskIdSchema4 } from "@opentask/taskin-types";
|
|
5638
5755
|
function readTaskId(raw) {
|
|
5639
5756
|
if (typeof raw !== "string")
|
|
@@ -5652,7 +5769,7 @@ function invalidTaskId(raw) {
|
|
|
5652
5769
|
isError: true
|
|
5653
5770
|
};
|
|
5654
5771
|
}
|
|
5655
|
-
var TaskMCPServer = class {
|
|
5772
|
+
var TaskMCPServer = class _TaskMCPServer {
|
|
5656
5773
|
server;
|
|
5657
5774
|
taskManager;
|
|
5658
5775
|
config;
|
|
@@ -5691,12 +5808,7 @@ var TaskMCPServer = class {
|
|
|
5691
5808
|
arguments: request.params.arguments
|
|
5692
5809
|
});
|
|
5693
5810
|
return {
|
|
5694
|
-
content:
|
|
5695
|
-
{
|
|
5696
|
-
type: "text",
|
|
5697
|
-
text: result.content
|
|
5698
|
-
}
|
|
5699
|
-
],
|
|
5811
|
+
content: result.content,
|
|
5700
5812
|
isError: result.isError
|
|
5701
5813
|
};
|
|
5702
5814
|
});
|
|
@@ -5762,6 +5874,22 @@ var TaskMCPServer = class {
|
|
|
5762
5874
|
*/
|
|
5763
5875
|
listTools() {
|
|
5764
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
|
+
},
|
|
5765
5893
|
{
|
|
5766
5894
|
name: "start_task",
|
|
5767
5895
|
description: "Start working on a task by changing its status to in-progress",
|
|
@@ -5800,6 +5928,8 @@ var TaskMCPServer = class {
|
|
|
5800
5928
|
try {
|
|
5801
5929
|
this.log(`Calling tool: ${params.name}`, params.arguments);
|
|
5802
5930
|
switch (params.name) {
|
|
5931
|
+
case "list_tasks":
|
|
5932
|
+
return await this.handleListTasks(params.arguments ?? {});
|
|
5803
5933
|
case "start_task": {
|
|
5804
5934
|
const taskId = readTaskId(params.arguments?.taskId);
|
|
5805
5935
|
return taskId ? await this.handleStartTask(taskId) : invalidTaskId(params.arguments?.taskId);
|
|
@@ -6003,6 +6133,35 @@ Let me start by marking the task as done using the finish_task tool.`
|
|
|
6003
6133
|
throw new Error(`Unknown prompt: ${params.name}`);
|
|
6004
6134
|
}
|
|
6005
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
|
+
}
|
|
6006
6165
|
/**
|
|
6007
6166
|
* List available resources
|
|
6008
6167
|
*/
|
|
@@ -6025,15 +6184,13 @@ Let me start by marking the task as done using the finish_task tool.`
|
|
|
6025
6184
|
this.log(`Reading resource: ${params.uri}`);
|
|
6026
6185
|
const uri = params.uri;
|
|
6027
6186
|
if (uri === "taskin://tasks") {
|
|
6187
|
+
const tarefas = await this.selecionarTarefas({});
|
|
6028
6188
|
return {
|
|
6029
6189
|
contents: [
|
|
6030
6190
|
{
|
|
6031
6191
|
uri,
|
|
6032
6192
|
mimeType: "application/json",
|
|
6033
|
-
text: JSON.stringify(
|
|
6034
|
-
message: "Task list would be here",
|
|
6035
|
-
note: "Requires ITaskProvider integration"
|
|
6036
|
-
})
|
|
6193
|
+
text: JSON.stringify(tarefas, null, 2)
|
|
6037
6194
|
}
|
|
6038
6195
|
]
|
|
6039
6196
|
};
|
|
@@ -6092,7 +6249,7 @@ async function startMCPServer(options) {
|
|
|
6092
6249
|
});
|
|
6093
6250
|
info("Starting MCP server...");
|
|
6094
6251
|
await mcpServer.connect({ transport });
|
|
6095
|
-
success("
|
|
6252
|
+
success("MCP server started successfully");
|
|
6096
6253
|
info("");
|
|
6097
6254
|
info(chalk6.bold("Server Information:"));
|
|
6098
6255
|
info(` \u2022 Transport: ${chalk6.cyan(transport)}`);
|
|
@@ -6114,7 +6271,7 @@ async function startMCPServer(options) {
|
|
|
6114
6271
|
info("");
|
|
6115
6272
|
const cleanup = async () => {
|
|
6116
6273
|
info("\nShutting down MCP server...");
|
|
6117
|
-
success("
|
|
6274
|
+
success("Server stopped");
|
|
6118
6275
|
process.exit(0);
|
|
6119
6276
|
};
|
|
6120
6277
|
process.on("SIGINT", cleanup);
|
|
@@ -6287,7 +6444,7 @@ async function createTask(options, gitService) {
|
|
|
6287
6444
|
console.log(colors.secondary(`\u{1F4C1} Path: ${createdPath}`));
|
|
6288
6445
|
}
|
|
6289
6446
|
if (autoSyncActive) {
|
|
6290
|
-
success("
|
|
6447
|
+
success("Task committed and pushed to remote");
|
|
6291
6448
|
}
|
|
6292
6449
|
console.log();
|
|
6293
6450
|
console.log(colors.info("Next steps:"));
|
|
@@ -6442,7 +6599,7 @@ async function pauseTask(taskId, options) {
|
|
|
6442
6599
|
console.log(colors.secondary(` - Add all changes: git add -A`));
|
|
6443
6600
|
console.log(colors.secondary(` - Commit: git commit -m "${commitMessage2}"`));
|
|
6444
6601
|
console.log();
|
|
6445
|
-
info("
|
|
6602
|
+
info("Dry run complete");
|
|
6446
6603
|
return;
|
|
6447
6604
|
}
|
|
6448
6605
|
if (task.status !== "in-progress") {
|
|
@@ -6476,7 +6633,7 @@ async function pauseTask(taskId, options) {
|
|
|
6476
6633
|
}
|
|
6477
6634
|
await taskManager.pauseTask(normalizedId);
|
|
6478
6635
|
success("Task paused successfully!");
|
|
6479
|
-
success("
|
|
6636
|
+
success("Auto-committed work in progress");
|
|
6480
6637
|
info("Status updated to paused");
|
|
6481
6638
|
console.log();
|
|
6482
6639
|
info("Next steps:");
|
|
@@ -6663,7 +6820,7 @@ async function reviewTask(taskId, options) {
|
|
|
6663
6820
|
});
|
|
6664
6821
|
console.log();
|
|
6665
6822
|
}
|
|
6666
|
-
info("
|
|
6823
|
+
info("Dry run complete");
|
|
6667
6824
|
return;
|
|
6668
6825
|
}
|
|
6669
6826
|
if (reviewHooks.pre && reviewHooks.pre.length > 0 && !options.skipMerge) {
|
|
@@ -6682,7 +6839,7 @@ async function reviewTask(taskId, options) {
|
|
|
6682
6839
|
const failedPre = preResults.find((r) => !r.success);
|
|
6683
6840
|
if (failedPre && !hookSettings.continueOnError) {
|
|
6684
6841
|
console.log();
|
|
6685
|
-
error("
|
|
6842
|
+
error("Pre-review hooks failed!");
|
|
6686
6843
|
error("Fix the errors above and try again.");
|
|
6687
6844
|
process.exit(1);
|
|
6688
6845
|
}
|
|
@@ -6704,7 +6861,7 @@ async function reviewTask(taskId, options) {
|
|
|
6704
6861
|
const failedCheck = duringResults.find((r) => !r.success);
|
|
6705
6862
|
if (failedCheck && !hookSettings.continueOnError) {
|
|
6706
6863
|
console.log();
|
|
6707
|
-
error("
|
|
6864
|
+
error("Review checks failed!");
|
|
6708
6865
|
error("Fix the errors above and try again.");
|
|
6709
6866
|
console.log();
|
|
6710
6867
|
info("Tip: Run individual checks to see full error details");
|
|
@@ -6714,7 +6871,7 @@ async function reviewTask(taskId, options) {
|
|
|
6714
6871
|
}
|
|
6715
6872
|
info("Marking task as ready for review...");
|
|
6716
6873
|
const updatedTask = await taskManager.reviewTask(task.id);
|
|
6717
|
-
success(
|
|
6874
|
+
success(`Task ${updatedTask.id} status changed to: ${updatedTask.status}`);
|
|
6718
6875
|
if (behavior.autoCommitStatusChange) {
|
|
6719
6876
|
try {
|
|
6720
6877
|
const message = appendCiSkipTag(
|
|
@@ -6725,7 +6882,7 @@ async function reviewTask(taskId, options) {
|
|
|
6725
6882
|
cwd: monorepoRoot,
|
|
6726
6883
|
stdio: "ignore"
|
|
6727
6884
|
});
|
|
6728
|
-
success("
|
|
6885
|
+
success("Auto-committed status change");
|
|
6729
6886
|
} catch {
|
|
6730
6887
|
}
|
|
6731
6888
|
}
|
|
@@ -6746,7 +6903,7 @@ async function reviewTask(taskId, options) {
|
|
|
6746
6903
|
console.log();
|
|
6747
6904
|
}
|
|
6748
6905
|
const totalDuration = [...reviewHooks.pre ?? [], ...reviewHooks.during ?? [], ...reviewHooks.post ?? []].length > 0 ? "with hooks" : "";
|
|
6749
|
-
success(
|
|
6906
|
+
success(`Task ready for review! ${totalDuration}`);
|
|
6750
6907
|
await sendTaskNotification(configManager, "task:review", normalizedId, task.title);
|
|
6751
6908
|
if (options.sound !== false) {
|
|
6752
6909
|
await playSound("review");
|
|
@@ -6839,7 +6996,7 @@ async function startTask(taskId, _options, gitService) {
|
|
|
6839
6996
|
)
|
|
6840
6997
|
);
|
|
6841
6998
|
console.log();
|
|
6842
|
-
info("
|
|
6999
|
+
info("Dry run complete");
|
|
6843
7000
|
return;
|
|
6844
7001
|
}
|
|
6845
7002
|
if (task.status === "in-progress") {
|
|
@@ -6858,7 +7015,7 @@ async function startTask(taskId, _options, gitService) {
|
|
|
6858
7015
|
if (behavior.autoCommitStatusChange) {
|
|
6859
7016
|
const committed = await git.commitTaskStatusChangeOnBranch(normalizedId, "in-progress", behavior.defaultBranch);
|
|
6860
7017
|
if (committed) {
|
|
6861
|
-
success("
|
|
7018
|
+
success("Auto-committed status change");
|
|
6862
7019
|
}
|
|
6863
7020
|
}
|
|
6864
7021
|
console.log();
|
|
@@ -7077,102 +7234,72 @@ function getStatusEmoji(status) {
|
|
|
7077
7234
|
|
|
7078
7235
|
// src/lib/help.ts
|
|
7079
7236
|
init_esm_shims();
|
|
7080
|
-
|
|
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) {
|
|
7081
7281
|
printHeader("Taskin - Task Management System", icons.rocket);
|
|
7082
7282
|
console.log(colors.info("\u{1F4CB} AVAILABLE COMMANDS"));
|
|
7083
7283
|
console.log(colors.highlight("\u2550".repeat(60)));
|
|
7084
7284
|
console.log();
|
|
7085
|
-
const
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
name: colors.highlight("taskin new"),
|
|
7102
|
-
alias: colors.secondary("Alias: create"),
|
|
7103
|
-
description: "Create a new task",
|
|
7104
|
-
examples: [
|
|
7105
|
-
'taskin new -t feat -T "Add login" -d "Implement user authentication"',
|
|
7106
|
-
'taskin new --type fix --title "Fix bug" --user "John"',
|
|
7107
|
-
'taskin create -t docs -T "Update README"'
|
|
7108
|
-
],
|
|
7109
|
-
icon: "\u{1F4DD}"
|
|
7110
|
-
},
|
|
7111
|
-
{
|
|
7112
|
-
name: colors.highlight("taskin start") + colors.normal(" <task-id>"),
|
|
7113
|
-
alias: colors.secondary("Alias: begin"),
|
|
7114
|
-
description: "Start working on a task (suggests commits)",
|
|
7115
|
-
examples: ["taskin start 001", "taskin start task-001", "taskin start 001 --force"],
|
|
7116
|
-
icon: "\u{1F680}"
|
|
7117
|
-
},
|
|
7118
|
-
{
|
|
7119
|
-
name: colors.highlight("taskin pause") + colors.normal(" <task-id>"),
|
|
7120
|
-
alias: colors.secondary("Alias: stop"),
|
|
7121
|
-
description: "Pause a task (auto-commits work in progress)",
|
|
7122
|
-
examples: ["taskin pause 001", 'taskin pause 001 -m "saving progress"'],
|
|
7123
|
-
icon: "\u23F8\uFE0F"
|
|
7124
|
-
},
|
|
7125
|
-
{
|
|
7126
|
-
name: colors.highlight("taskin finish") + colors.normal(" <task-id>"),
|
|
7127
|
-
alias: colors.secondary("Alias: done"),
|
|
7128
|
-
description: "Finish a task (suggests commits)",
|
|
7129
|
-
examples: ["taskin finish 001", "taskin done task-001"],
|
|
7130
|
-
icon: "\u2705"
|
|
7131
|
-
},
|
|
7132
|
-
{
|
|
7133
|
-
name: colors.highlight("taskin config") + colors.normal(" [options]"),
|
|
7134
|
-
alias: colors.secondary("Options: --level <manual|assisted|autopilot>"),
|
|
7135
|
-
description: "Configure automation level",
|
|
7136
|
-
examples: ["taskin config", "taskin config --level assisted", "taskin config --level autopilot"],
|
|
7137
|
-
icon: "\u2699\uFE0F"
|
|
7138
|
-
},
|
|
7139
|
-
{
|
|
7140
|
-
name: colors.highlight("taskin lint") + colors.normal(" [options]"),
|
|
7141
|
-
alias: colors.secondary("Options: -p, --path <directory>"),
|
|
7142
|
-
description: "Validate task markdown files",
|
|
7143
|
-
examples: ["taskin lint", "taskin lint --path ./TASKS", "taskin lint -p /path/to/tasks"],
|
|
7144
|
-
icon: "\u{1F50D}"
|
|
7145
|
-
},
|
|
7146
|
-
{
|
|
7147
|
-
name: colors.highlight("taskin dashboard") + colors.normal(" [options]"),
|
|
7148
|
-
alias: colors.secondary("Options: --host, --port, --filter-open, --filter-closed"),
|
|
7149
|
-
description: "Start the web dashboard",
|
|
7150
|
-
examples: [
|
|
7151
|
-
"taskin dashboard",
|
|
7152
|
-
"taskin dashboard --port 3000",
|
|
7153
|
-
"taskin dashboard --filter-open",
|
|
7154
|
-
"taskin dashboard --filter-closed -o"
|
|
7155
|
-
],
|
|
7156
|
-
icon: "\u{1F4CA}"
|
|
7157
|
-
},
|
|
7158
|
-
{
|
|
7159
|
-
name: colors.highlight("taskin mcp-server"),
|
|
7160
|
-
alias: colors.secondary("Alias: mcp"),
|
|
7161
|
-
description: "Start MCP server for Claude Desktop integration",
|
|
7162
|
-
examples: ["taskin mcp-server", "taskin mcp"],
|
|
7163
|
-
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
|
+
}
|
|
7164
7301
|
}
|
|
7165
|
-
|
|
7166
|
-
commands.forEach((cmd, index) => {
|
|
7167
|
-
console.log(colors.warning(`${cmd.icon} ${cmd.name}`));
|
|
7168
|
-
console.log(colors.normal(` ${cmd.alias}`));
|
|
7169
|
-
console.log(colors.info(` ${cmd.description}`));
|
|
7170
|
-
console.log();
|
|
7171
|
-
console.log(colors.normal(` ${colors.info("\u{1F4DD} Examples:")}`));
|
|
7172
|
-
cmd.examples.forEach((example) => {
|
|
7173
|
-
console.log(colors.secondary(` ${example}`));
|
|
7174
|
-
});
|
|
7175
|
-
if (index < commands.length - 1) {
|
|
7302
|
+
if (index < comandos.length - 1) {
|
|
7176
7303
|
console.log();
|
|
7177
7304
|
console.log(colors.normal(` ${colors.secondary("\u2500".repeat(50))}`));
|
|
7178
7305
|
console.log();
|
|
@@ -7574,7 +7701,7 @@ var program = new Command();
|
|
|
7574
7701
|
program.name("taskin").description("\u{1F680} Task Management System").version(getVersion());
|
|
7575
7702
|
program.helpOption("-h, --help", "Display help information");
|
|
7576
7703
|
program.command("help").description("Show help information").action(() => {
|
|
7577
|
-
showCustomHelp();
|
|
7704
|
+
showCustomHelp(program);
|
|
7578
7705
|
});
|
|
7579
7706
|
initCommand(program);
|
|
7580
7707
|
listCommand(program);
|
|
@@ -7591,15 +7718,15 @@ dashboardCommand(program);
|
|
|
7591
7718
|
mcpServerCommand(program);
|
|
7592
7719
|
notifyCommand(program);
|
|
7593
7720
|
program.on("option:help", () => {
|
|
7594
|
-
showCustomHelp();
|
|
7721
|
+
showCustomHelp(program);
|
|
7595
7722
|
process.exit(0);
|
|
7596
7723
|
});
|
|
7597
7724
|
if (process.argv.length <= 2) {
|
|
7598
|
-
showCustomHelp();
|
|
7725
|
+
showCustomHelp(program);
|
|
7599
7726
|
process.exit(0);
|
|
7600
7727
|
}
|
|
7601
7728
|
if (process.argv.length === 3 && (process.argv[2] === "--help" || process.argv[2] === "-h")) {
|
|
7602
|
-
showCustomHelp();
|
|
7729
|
+
showCustomHelp(program);
|
|
7603
7730
|
process.exit(0);
|
|
7604
7731
|
}
|
|
7605
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,12 +79,12 @@
|
|
|
79
79
|
"play-sound": "^1.1.6",
|
|
80
80
|
"ws": "^8.18.3",
|
|
81
81
|
"zod": "^3.25.76",
|
|
82
|
-
"@opentask/taskin-
|
|
83
|
-
"@opentask/taskin-
|
|
84
|
-
"@opentask/taskin-
|
|
85
|
-
"@opentask/taskin-task-
|
|
86
|
-
"@opentask/taskin-task-server-ws": "0.3.
|
|
87
|
-
"@opentask/taskin-types": "2.
|
|
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
88
|
"@opentask/taskin-utils": "1.1.1"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|