taskin 2.0.4 → 2.1.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/dist/index.js CHANGED
@@ -51,7 +51,7 @@ var init_esm_shims = __esm({
51
51
  }
52
52
  });
53
53
 
54
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/i18n.js
54
+ // ../file-system-task-provider/dist/i18n.js
55
55
  function getI18n(locale = "en-US") {
56
56
  return i18nConfig[locale];
57
57
  }
@@ -63,7 +63,7 @@ function detectLocale(content) {
63
63
  }
64
64
  var i18nConfig;
65
65
  var init_i18n = __esm({
66
- "../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/i18n.js"() {
66
+ "../file-system-task-provider/dist/i18n.js"() {
67
67
  "use strict";
68
68
  init_esm_shims();
69
69
  i18nConfig = {
@@ -93,7 +93,7 @@ var init_i18n = __esm({
93
93
  }
94
94
  });
95
95
 
96
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/task-validator.js
96
+ // ../file-system-task-provider/dist/task-validator.js
97
97
  var task_validator_exports = {};
98
98
  __export(task_validator_exports, {
99
99
  createLintResult: () => createLintResult,
@@ -137,7 +137,6 @@ async function fixTaskFile(filePath) {
137
137
  return false;
138
138
  }
139
139
  let newContent = content;
140
- let wasModified = false;
141
140
  if (hasSectionStatus || hasSectionType || hasSectionAssignee) {
142
141
  const statusMatch = content.match(statusPattern);
143
142
  const typeMatch = content.match(typePattern);
@@ -176,7 +175,6 @@ async function fixTaskFile(filePath) {
176
175
  "",
177
176
  ...afterTitle
178
177
  ].join("\n");
179
- wasModified = true;
180
178
  }
181
179
  if (needsSpaceFix) {
182
180
  newContent = newContent.replace(
@@ -191,7 +189,6 @@ async function fixTaskFile(filePath) {
191
189
  /^(Assignee|Responsável):\s*(.+?)([ \t]*)$/im,
192
190
  (_, key, value) => `${key}: ${value.trim()} `
193
191
  );
194
- wasModified = true;
195
192
  }
196
193
  const finalContentRaw = newContent.replace(/\n{3,}/g, "\n\n").trim() + "\n";
197
194
  const originalContentRaw = content.replace(/\n{3,}/g, "\n\n").trim() + "\n";
@@ -343,7 +340,7 @@ function createLintResult(allIssues) {
343
340
  };
344
341
  }
345
342
  var init_task_validator = __esm({
346
- "../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/task-validator.js"() {
343
+ "../file-system-task-provider/dist/task-validator.js"() {
347
344
  "use strict";
348
345
  init_esm_shims();
349
346
  init_i18n();
@@ -7186,10 +7183,10 @@ import { Command } from "commander";
7186
7183
  // src/commands/dashboard.ts
7187
7184
  init_esm_shims();
7188
7185
 
7189
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/index.js
7186
+ // ../file-system-task-provider/dist/index.js
7190
7187
  init_esm_shims();
7191
7188
 
7192
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/file-system-metrics-adapter.js
7189
+ // ../file-system-task-provider/dist/file-system-metrics-adapter.js
7193
7190
  init_esm_shims();
7194
7191
  import { UserStatsSchema } from "@opentask/taskin-types";
7195
7192
  import { promises as fs } from "fs";
@@ -7237,6 +7234,46 @@ function emptyTemporalMetrics() {
7237
7234
  function removeCodeBlocks(content) {
7238
7235
  return content.replace(/```[\s\S]*?```/g, "");
7239
7236
  }
7237
+ function resolvePeriod(period = "week") {
7238
+ const now = /* @__PURE__ */ new Date();
7239
+ const until = now;
7240
+ let since;
7241
+ switch (period) {
7242
+ case "day":
7243
+ since = new Date(Date.now() - MILLISECONDS_PER_DAY);
7244
+ break;
7245
+ case "week":
7246
+ since = new Date(Date.now() - DAYS_PER_WEEK * MILLISECONDS_PER_DAY);
7247
+ break;
7248
+ case "month":
7249
+ since = new Date(Date.now() - 30 * MILLISECONDS_PER_DAY);
7250
+ break;
7251
+ case "quarter":
7252
+ since = new Date(Date.now() - 90 * MILLISECONDS_PER_DAY);
7253
+ break;
7254
+ case "year":
7255
+ since = new Date(Date.now() - 365 * MILLISECONDS_PER_DAY);
7256
+ break;
7257
+ case "all":
7258
+ since = /* @__PURE__ */ new Date(0);
7259
+ break;
7260
+ default:
7261
+ since = new Date(Date.now() - DAYS_PER_WEEK * MILLISECONDS_PER_DAY);
7262
+ }
7263
+ return { since, until };
7264
+ }
7265
+ function calculateActivityFrequency(commits, period) {
7266
+ const daysInPeriod = {
7267
+ day: 1,
7268
+ week: 7,
7269
+ month: 30,
7270
+ quarter: 90,
7271
+ year: 365,
7272
+ all: 365
7273
+ // Use 1 year as baseline for 'all'
7274
+ };
7275
+ return commits / daysInPeriod[period];
7276
+ }
7240
7277
  async function calculateCodeMetrics(gitAnalyzer, username, since, until) {
7241
7278
  if (!gitAnalyzer) {
7242
7279
  return emptyCodeMetrics();
@@ -7422,11 +7459,12 @@ var FileSystemMetricsAdapter = class {
7422
7459
  }
7423
7460
  return tasks;
7424
7461
  }
7425
- async getUserMetrics(userId, _query) {
7462
+ async getUserMetrics(userId, query) {
7426
7463
  const user = this.userRegistry.getUser(userId);
7427
7464
  const username = user ? user.name : userId;
7428
- const now = /* @__PURE__ */ new Date();
7429
- const weekAgo = new Date(Date.now() - DAYS_PER_WEEK * MILLISECONDS_PER_DAY);
7465
+ const { since, until } = resolvePeriod(query?.period || "week");
7466
+ const now = until;
7467
+ const weekAgo = since;
7430
7468
  const tasks = await this.readTaskFiles();
7431
7469
  const assigned = tasks.filter((t) => {
7432
7470
  if (!t.assignee)
@@ -7439,7 +7477,7 @@ var FileSystemMetricsAdapter = class {
7439
7477
  const temporalMetrics = await calculateTemporalMetrics(this.gitAnalyzer, username, weekAgo, now);
7440
7478
  const rawMetrics = {
7441
7479
  username,
7442
- period: "week",
7480
+ period: query?.period || "week",
7443
7481
  periodStart: toISOString(weekAgo),
7444
7482
  periodEnd: toISOString(now),
7445
7483
  codeMetrics,
@@ -7451,11 +7489,10 @@ var FileSystemMetricsAdapter = class {
7451
7489
  // TODO: calculate from task timestamps
7452
7490
  taskTypeDistribution: {},
7453
7491
  // TODO: calculate from task types
7454
- activityFrequency: codeMetrics.commits / DAYS_PER_WEEK
7455
- // commits per day
7492
+ activityFrequency: calculateActivityFrequency(codeMetrics.commits, query?.period || "week")
7456
7493
  },
7457
7494
  engagementMetrics: {
7458
- commitsPerDay: codeMetrics.commits / DAYS_PER_WEEK,
7495
+ commitsPerDay: calculateActivityFrequency(codeMetrics.commits, query?.period || "week"),
7459
7496
  consistency: 0,
7460
7497
  // TODO: calculate standard deviation
7461
7498
  activeTasksCount: active,
@@ -7465,14 +7502,17 @@ var FileSystemMetricsAdapter = class {
7465
7502
  };
7466
7503
  return UserStatsSchema.parse(rawMetrics);
7467
7504
  }
7468
- async getTeamMetrics(_teamId, _query) {
7469
- const now = /* @__PURE__ */ new Date();
7470
- const weekAgo = new Date(Date.now() - DAYS_PER_WEEK * MILLISECONDS_PER_DAY);
7505
+ async getTeamMetrics(_teamId, query) {
7506
+ const { since, until } = resolvePeriod(query?.period || "week");
7507
+ const now = until;
7508
+ const weekAgo = since;
7471
7509
  const tasks = await this.readTaskFiles();
7472
7510
  const contributors = /* @__PURE__ */ new Map();
7511
+ const normalizeKey = (name) => name.toLowerCase();
7473
7512
  for (const t of tasks) {
7474
7513
  const assignee = t.assignee || "unknown";
7475
- const prev = contributors.get(assignee) || {
7514
+ const key = normalizeKey(assignee);
7515
+ const prev = contributors.get(key) || {
7476
7516
  username: assignee,
7477
7517
  commits: 0,
7478
7518
  tasksCompleted: 0,
@@ -7480,15 +7520,54 @@ var FileSystemMetricsAdapter = class {
7480
7520
  };
7481
7521
  if (t.status === "done")
7482
7522
  prev.tasksCompleted += 1;
7483
- contributors.set(assignee, prev);
7523
+ contributors.set(key, prev);
7524
+ }
7525
+ try {
7526
+ const allUsers = this.userRegistry.getAllUsers?.() || [];
7527
+ for (const u of allUsers) {
7528
+ const username = u.name || u.id;
7529
+ const key = normalizeKey(username);
7530
+ if (!contributors.has(key)) {
7531
+ contributors.set(key, {
7532
+ username,
7533
+ commits: 0,
7534
+ tasksCompleted: 0,
7535
+ codeMetrics: emptyCodeMetrics()
7536
+ });
7537
+ }
7538
+ }
7539
+ } catch (error2) {
7540
+ console.warn("Failed to include registry users in team metrics:", error2);
7541
+ }
7542
+ if (this.gitAnalyzer) {
7543
+ try {
7544
+ const authors = await this.gitAnalyzer.getAuthors({
7545
+ since: weekAgo.toISOString(),
7546
+ until: now.toISOString()
7547
+ });
7548
+ for (const a of authors) {
7549
+ const name = a.name || a.email || "unknown";
7550
+ const key = normalizeKey(name);
7551
+ if (!contributors.has(key)) {
7552
+ contributors.set(key, {
7553
+ username: name,
7554
+ commits: 0,
7555
+ tasksCompleted: 0,
7556
+ codeMetrics: emptyCodeMetrics()
7557
+ });
7558
+ }
7559
+ }
7560
+ } catch (error2) {
7561
+ console.warn("Failed to fetch git authors for team metrics:", error2);
7562
+ }
7484
7563
  }
7485
- for (const [username, data] of contributors.entries()) {
7564
+ for (const [_key, data] of contributors.entries()) {
7486
7565
  try {
7487
- const codeMetrics = await calculateCodeMetrics(this.gitAnalyzer, username, weekAgo, now);
7566
+ const codeMetrics = await calculateCodeMetrics(this.gitAnalyzer, data.username, weekAgo, now);
7488
7567
  data.commits = codeMetrics.commits;
7489
7568
  data.codeMetrics = codeMetrics;
7490
7569
  } catch (error2) {
7491
- console.error(`Failed to calculate metrics for ${username}:`, error2);
7570
+ console.error(`Failed to calculate metrics for ${data.username}:`, error2);
7492
7571
  }
7493
7572
  }
7494
7573
  const totalCommits = Array.from(contributors.values()).reduce((sum, c) => sum + c.commits, 0);
@@ -7502,7 +7581,7 @@ var FileSystemMetricsAdapter = class {
7502
7581
  commits: acc.commits + c.codeMetrics.commits
7503
7582
  }), emptyCodeMetrics());
7504
7583
  const team = {
7505
- period: "week",
7584
+ period: query?.period || "week",
7506
7585
  periodStart: toISOString(weekAgo),
7507
7586
  periodEnd: toISOString(now),
7508
7587
  totalContributors: contributors.size,
@@ -7558,8 +7637,123 @@ var FileSystemMetricsAdapter = class {
7558
7637
  }
7559
7638
  };
7560
7639
 
7561
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/fs-task-provider.js
7640
+ // ../file-system-task-provider/dist/fs-task-provider.js
7641
+ init_esm_shims();
7642
+
7643
+ // ../utils/dist/index.js
7644
+ init_esm_shims();
7645
+
7646
+ // ../utils/dist/security.js
7647
+ init_esm_shims();
7648
+ import { z } from "zod";
7649
+ var HostSchema = z.string().refine(
7650
+ (host) => {
7651
+ if (!host || host.length === 0) return false;
7652
+ if (host === "localhost") return true;
7653
+ const parts = host.split(".");
7654
+ const allNumeric = parts.every((p) => /^\d+$/.test(p));
7655
+ if (allNumeric) {
7656
+ if (parts.length !== 4) return false;
7657
+ return parts.every((part) => {
7658
+ const num = parseInt(part, 10);
7659
+ return !isNaN(num) && num >= 0 && num <= 255 && part === num.toString();
7660
+ });
7661
+ }
7662
+ const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
7663
+ return hostnameRegex.test(host);
7664
+ },
7665
+ {
7666
+ message: "Invalid host. Must be localhost, a valid IPv4 address, or hostname."
7667
+ }
7668
+ );
7669
+ var PortSchema = z.union([
7670
+ z.number().int().min(1).max(65535),
7671
+ z.string().regex(/^\d+$/).transform((val) => parseInt(val, 10)).pipe(z.number().int().min(1).max(65535))
7672
+ ]);
7673
+ var WebSocketUrlSchema = z.string().refine(
7674
+ (url) => {
7675
+ try {
7676
+ const parsed = new URL(url);
7677
+ return parsed.protocol === "ws:" || parsed.protocol === "wss:";
7678
+ } catch {
7679
+ return false;
7680
+ }
7681
+ },
7682
+ { message: "Invalid WebSocket URL. Must use ws:// or wss:// protocol." }
7683
+ );
7684
+ var TaskIdSchema = z.string().min(1).max(100).regex(/^[a-zA-Z0-9_-]+$/, {
7685
+ message: "Task ID must contain only alphanumeric characters, hyphens, and underscores."
7686
+ });
7687
+ var UserIdSchema = z.string().min(1).max(100).regex(/^[a-zA-Z0-9._-]+$/, {
7688
+ message: "User ID must contain only alphanumeric characters, dots, hyphens, and underscores."
7689
+ });
7690
+ var EmailSchema = z.string().email().max(254);
7691
+ var SafePathSchema = z.string().refine(
7692
+ (filePath) => {
7693
+ if (!filePath || filePath.length === 0) return false;
7694
+ const dangerousPatterns = [
7695
+ /\.\./,
7696
+ // Parent directory (..)
7697
+ /~\//,
7698
+ // Home directory
7699
+ /^\//,
7700
+ // Absolute path
7701
+ /^[A-Za-z]:\\/
7702
+ // Windows absolute path
7703
+ ];
7704
+ return !dangerousPatterns.some((pattern) => pattern.test(filePath));
7705
+ },
7706
+ {
7707
+ message: "Invalid path. Must be a relative path without traversal patterns."
7708
+ }
7709
+ );
7710
+ var DashboardOptionsSchema = z.object({
7711
+ host: HostSchema.optional(),
7712
+ port: PortSchema.optional(),
7713
+ wsPort: PortSchema.optional()
7714
+ });
7715
+ function isValidHost(host) {
7716
+ return HostSchema.safeParse(host).success;
7717
+ }
7718
+ function isValidPort(port) {
7719
+ return PortSchema.safeParse(port).success;
7720
+ }
7721
+ function escapeHtml(text) {
7722
+ if (!text || typeof text !== "string") {
7723
+ return "";
7724
+ }
7725
+ const htmlEscapeMap = {
7726
+ "&": "&amp;",
7727
+ "<": "&lt;",
7728
+ ">": "&gt;",
7729
+ '"': "&quot;",
7730
+ "'": "&#x27;",
7731
+ "/": "&#x2F;"
7732
+ };
7733
+ return text.replace(/[&<>"'/]/g, (char) => htmlEscapeMap[char]);
7734
+ }
7735
+
7736
+ // ../utils/dist/string.js
7562
7737
  init_esm_shims();
7738
+ function slugify(text) {
7739
+ return text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
7740
+ }
7741
+
7742
+ // ../utils/dist/ui.js
7743
+ init_esm_shims();
7744
+ import chalk from "chalk";
7745
+ var colors = {
7746
+ primary: chalk.blue,
7747
+ secondary: chalk.gray,
7748
+ success: chalk.green,
7749
+ warning: chalk.yellow,
7750
+ error: chalk.red,
7751
+ info: chalk.cyan,
7752
+ highlight: chalk.magenta,
7753
+ normal: chalk.white
7754
+ };
7755
+
7756
+ // ../file-system-task-provider/dist/fs-task-provider.js
7563
7757
  init_i18n();
7564
7758
  init_task_validator();
7565
7759
  import { promises as fs2 } from "fs";
@@ -7712,7 +7906,7 @@ var FileSystemTaskProvider = class {
7712
7906
  }).filter((num) => !isNaN(num));
7713
7907
  const nextNumber = taskNumbers.length > 0 ? Math.max(...taskNumbers) + 1 : 1;
7714
7908
  const taskId = String(nextNumber).padStart(3, "0");
7715
- const titleSlug = options.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
7909
+ const titleSlug = slugify(options.title);
7716
7910
  const fileName = `task-${taskId}-${titleSlug}.md`;
7717
7911
  const filePath = path3.join(this.tasksDirectory, fileName);
7718
7912
  const fileExists = await fs2.access(filePath).then(() => true).catch(() => false);
@@ -7789,10 +7983,10 @@ ${i18n.notesPlaceholder}
7789
7983
  }
7790
7984
  };
7791
7985
 
7792
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/index.js
7986
+ // ../file-system-task-provider/dist/index.js
7793
7987
  init_i18n();
7794
7988
 
7795
- // ../../node_modules/.pnpm/@opentask+taskin-file-system-provider@2.0.3/node_modules/@opentask/taskin-file-system-provider/dist/user-registry.js
7989
+ // ../file-system-task-provider/dist/user-registry.js
7796
7990
  init_esm_shims();
7797
7991
  import { promises as fs3 } from "fs";
7798
7992
  import path4 from "path";
@@ -8285,108 +8479,6 @@ init_esm_shims();
8285
8479
  // ../../node_modules/.pnpm/@opentask+taskin-task-server-ws@0.1.3/node_modules/@opentask/taskin-task-server-ws/dist/task-server-ws.types.js
8286
8480
  init_esm_shims();
8287
8481
 
8288
- // ../../node_modules/.pnpm/@opentask+taskin-utils@1.0.5/node_modules/@opentask/taskin-utils/dist/index.js
8289
- init_esm_shims();
8290
-
8291
- // ../../node_modules/.pnpm/@opentask+taskin-utils@1.0.5/node_modules/@opentask/taskin-utils/dist/security.js
8292
- init_esm_shims();
8293
- import { z } from "zod";
8294
- var HostSchema = z.string().refine((host) => {
8295
- if (!host || host.length === 0)
8296
- return false;
8297
- if (host === "localhost")
8298
- return true;
8299
- const parts = host.split(".");
8300
- const allNumeric = parts.every((p) => /^\d+$/.test(p));
8301
- if (allNumeric) {
8302
- if (parts.length !== 4)
8303
- return false;
8304
- return parts.every((part) => {
8305
- const num = parseInt(part, 10);
8306
- return !isNaN(num) && num >= 0 && num <= 255 && part === num.toString();
8307
- });
8308
- }
8309
- const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
8310
- return hostnameRegex.test(host);
8311
- }, {
8312
- message: "Invalid host. Must be localhost, a valid IPv4 address, or hostname."
8313
- });
8314
- var PortSchema = z.union([
8315
- z.number().int().min(1).max(65535),
8316
- z.string().regex(/^\d+$/).transform((val) => parseInt(val, 10)).pipe(z.number().int().min(1).max(65535))
8317
- ]);
8318
- var WebSocketUrlSchema = z.string().refine((url) => {
8319
- try {
8320
- const parsed = new URL(url);
8321
- return parsed.protocol === "ws:" || parsed.protocol === "wss:";
8322
- } catch {
8323
- return false;
8324
- }
8325
- }, { message: "Invalid WebSocket URL. Must use ws:// or wss:// protocol." });
8326
- var TaskIdSchema = z.string().min(1).max(100).regex(/^[a-zA-Z0-9_-]+$/, {
8327
- message: "Task ID must contain only alphanumeric characters, hyphens, and underscores."
8328
- });
8329
- var UserIdSchema = z.string().min(1).max(100).regex(/^[a-zA-Z0-9._-]+$/, {
8330
- message: "User ID must contain only alphanumeric characters, dots, hyphens, and underscores."
8331
- });
8332
- var EmailSchema = z.string().email().max(254);
8333
- var SafePathSchema = z.string().refine((filePath) => {
8334
- if (!filePath || filePath.length === 0)
8335
- return false;
8336
- const dangerousPatterns = [
8337
- /\.\./,
8338
- // Parent directory (..)
8339
- /~\//,
8340
- // Home directory
8341
- /^\//,
8342
- // Absolute path
8343
- /^[A-Za-z]:\\/
8344
- // Windows absolute path
8345
- ];
8346
- return !dangerousPatterns.some((pattern) => pattern.test(filePath));
8347
- }, {
8348
- message: "Invalid path. Must be a relative path without traversal patterns."
8349
- });
8350
- var DashboardOptionsSchema = z.object({
8351
- host: HostSchema.optional(),
8352
- port: PortSchema.optional(),
8353
- wsPort: PortSchema.optional()
8354
- });
8355
- function isValidHost(host) {
8356
- return HostSchema.safeParse(host).success;
8357
- }
8358
- function isValidPort(port) {
8359
- return PortSchema.safeParse(port).success;
8360
- }
8361
- function escapeHtml(text) {
8362
- if (!text || typeof text !== "string") {
8363
- return "";
8364
- }
8365
- const htmlEscapeMap = {
8366
- "&": "&amp;",
8367
- "<": "&lt;",
8368
- ">": "&gt;",
8369
- '"': "&quot;",
8370
- "'": "&#x27;",
8371
- "/": "&#x2F;"
8372
- };
8373
- return text.replace(/[&<>"'/]/g, (char) => htmlEscapeMap[char]);
8374
- }
8375
-
8376
- // ../../node_modules/.pnpm/@opentask+taskin-utils@1.0.5/node_modules/@opentask/taskin-utils/dist/ui.js
8377
- init_esm_shims();
8378
- import chalk from "chalk";
8379
- var colors = {
8380
- primary: chalk.blue,
8381
- secondary: chalk.gray,
8382
- success: chalk.green,
8383
- warning: chalk.yellow,
8384
- error: chalk.red,
8385
- info: chalk.cyan,
8386
- highlight: chalk.magenta,
8387
- normal: chalk.white
8388
- };
8389
-
8390
8482
  // src/commands/dashboard.ts
8391
8483
  import chalk3 from "chalk";
8392
8484
  import express from "express";
@@ -8504,6 +8596,14 @@ var dashboardCommand = defineCommand({
8504
8596
  {
8505
8597
  flags: "-o, --open",
8506
8598
  description: "Open browser automatically"
8599
+ },
8600
+ {
8601
+ flags: "--filter-open",
8602
+ description: "Show only open tasks (pending, in-progress, blocked)"
8603
+ },
8604
+ {
8605
+ flags: "--filter-closed",
8606
+ description: "Show only closed tasks (done, canceled)"
8507
8607
  }
8508
8608
  ],
8509
8609
  handler: async (options) => {
@@ -8639,8 +8739,15 @@ async function startDashboard(options) {
8639
8739
  });
8640
8740
  });
8641
8741
  success(`\u2713 Dashboard available at http://${host}:${port}`);
8742
+ const filterParams = new URLSearchParams();
8743
+ if (options.filterOpen) {
8744
+ filterParams.set("filter", "open");
8745
+ } else if (options.filterClosed) {
8746
+ filterParams.set("filter", "closed");
8747
+ }
8748
+ const filterQuery = filterParams.toString() ? `?${filterParams.toString()}` : "";
8642
8749
  if (options.open) {
8643
- const url = `http://${host}:${port}`;
8750
+ const url = `http://${host}:${port}${filterQuery}`;
8644
8751
  await import("child_process").then((cp) => {
8645
8752
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
8646
8753
  cp.exec(`${cmd} ${url}`);
@@ -8648,8 +8755,15 @@ async function startDashboard(options) {
8648
8755
  }
8649
8756
  info("");
8650
8757
  info(chalk3.bold("Dashboard Controls:"));
8651
- info(` \u2022 Dashboard: ${chalk3.cyan(`http://${host}:${port}`)}`);
8758
+ info(
8759
+ ` \u2022 Dashboard: ${chalk3.cyan(`http://${host}:${port}${filterQuery}`)}`
8760
+ );
8652
8761
  info(` \u2022 WebSocket: ${chalk3.cyan(`ws://${host}:${wsPort}`)}`);
8762
+ if (options.filterOpen) {
8763
+ info(` \u2022 Filter: ${chalk3.yellow("Open tasks only")}`);
8764
+ } else if (options.filterClosed) {
8765
+ info(` \u2022 Filter: ${chalk3.yellow("Closed tasks only")}`);
8766
+ }
8653
8767
  info(` \u2022 Press ${chalk3.bold("Ctrl+C")} to stop both servers`);
8654
8768
  info("");
8655
8769
  const cleanup = async () => {
@@ -8675,13 +8789,13 @@ async function startDashboard(options) {
8675
8789
  // src/commands/export.ts
8676
8790
  init_esm_shims();
8677
8791
 
8678
- // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.0.3/node_modules/@opentask/taskin-git-utils/dist/src/index.js
8792
+ // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.1.0/node_modules/@opentask/taskin-git-utils/dist/src/index.js
8679
8793
  init_esm_shims();
8680
8794
 
8681
- // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.0.3/node_modules/@opentask/taskin-git-utils/dist/src/git.js
8795
+ // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.1.0/node_modules/@opentask/taskin-git-utils/dist/src/git.js
8682
8796
  init_esm_shims();
8683
8797
 
8684
- // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.0.3/node_modules/@opentask/taskin-git-utils/dist/src/git-analyzer.js
8798
+ // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.1.0/node_modules/@opentask/taskin-git-utils/dist/src/git-analyzer.js
8685
8799
  init_esm_shims();
8686
8800
  import { exec } from "child_process";
8687
8801
  import { promisify } from "util";
@@ -8694,8 +8808,10 @@ async function executeGit(command, cwd) {
8694
8808
  const { stdout } = await execAsync(`git ${command}`, {
8695
8809
  cwd: cwd || process.cwd(),
8696
8810
  encoding: "utf8",
8697
- maxBuffer: 10 * 1024 * 1024
8811
+ maxBuffer: 10 * 1024 * 1024,
8698
8812
  // 10MB buffer for large repos
8813
+ timeout: 3e4
8814
+ // 30 second timeout
8699
8815
  });
8700
8816
  return stdout.trim();
8701
8817
  } catch (error2) {
@@ -8734,10 +8850,10 @@ var GitAnalyzer = class {
8734
8850
  args.push(`--since="${options.since}"`);
8735
8851
  }
8736
8852
  if (options.until) {
8737
- args.push(`--until="${options.until}"`);
8853
+ args.push(`--until=${options.until}`);
8738
8854
  }
8739
8855
  if (options.author) {
8740
- args.push(`--author="${options.author}"`);
8856
+ args.push(`--author='${options.author}'`);
8741
8857
  }
8742
8858
  if (options.maxCount) {
8743
8859
  args.push(`-n ${options.maxCount}`);
@@ -8767,7 +8883,7 @@ var GitAnalyzer = class {
8767
8883
  }
8768
8884
  if (line.includes("|")) {
8769
8885
  const parts = line.split("|");
8770
- if (parts.length < 4 || !/^[0-9a-f]{40}$/.test(parts[0])) {
8886
+ if (parts.length < 4 || !/^[0-9a-f]{6,40}$/i.test(parts[0])) {
8771
8887
  i++;
8772
8888
  continue;
8773
8889
  }
@@ -8920,7 +9036,7 @@ ${body}` : subject;
8920
9036
  let lineNumber = 0;
8921
9037
  for (let i = 0; i < lines.length; i++) {
8922
9038
  const line = lines[i];
8923
- if (line.match(/^[0-9a-f]{40}/)) {
9039
+ if (line.match(/^[0-9a-f]{6,40}/i)) {
8924
9040
  const parts = line.split(" ");
8925
9041
  currentHash = parts[0];
8926
9042
  lineNumber = parseInt(parts[2], 10);
@@ -8945,10 +9061,10 @@ ${body}` : subject;
8945
9061
  async getAuthors(options = {}) {
8946
9062
  const args = ["shortlog", "-sne"];
8947
9063
  if (options.since) {
8948
- args.push(`--since="${options.since}"`);
9064
+ args.push(`--since=${options.since}`);
8949
9065
  }
8950
9066
  if (options.until) {
8951
- args.push(`--until="${options.until}"`);
9067
+ args.push(`--until=${options.until}`);
8952
9068
  }
8953
9069
  if (!options.includeMerges) {
8954
9070
  args.push("--no-merges");
@@ -8956,7 +9072,8 @@ ${body}` : subject;
8956
9072
  if (options.filePath) {
8957
9073
  args.push("--", options.filePath);
8958
9074
  }
8959
- const output = await executeGit(args.join(" "), this.repositoryPath);
9075
+ const command = args.join(" ");
9076
+ const output = await executeGit(command, this.repositoryPath);
8960
9077
  if (!output) {
8961
9078
  return [];
8962
9079
  }
@@ -8986,10 +9103,10 @@ ${body}` : subject;
8986
9103
  }
8987
9104
  };
8988
9105
 
8989
- // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.0.3/node_modules/@opentask/taskin-git-utils/dist/src/git-analyzer.types.js
9106
+ // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.1.0/node_modules/@opentask/taskin-git-utils/dist/src/git-analyzer.types.js
8990
9107
  init_esm_shims();
8991
9108
 
8992
- // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.0.3/node_modules/@opentask/taskin-git-utils/dist/src/git.types.js
9109
+ // ../../node_modules/.pnpm/@opentask+taskin-git-utils@2.1.0/node_modules/@opentask/taskin-git-utils/dist/src/git.types.js
8993
9110
  init_esm_shims();
8994
9111
 
8995
9112
  // src/commands/export.ts
@@ -9086,6 +9203,9 @@ import path8 from "path";
9086
9203
  import player from "play-sound";
9087
9204
  var soundPlayer = player({});
9088
9205
  function playSound(soundName) {
9206
+ if (process.env.CI === "true" || process.env.NODE_ENV === "test") {
9207
+ return;
9208
+ }
9089
9209
  try {
9090
9210
  const possiblePaths = [
9091
9211
  // In development (from src)
@@ -9158,17 +9278,33 @@ async function finishTask(taskId, options) {
9158
9278
  info("Skipping status update (--skip-update flag)");
9159
9279
  }
9160
9280
  console.log();
9161
- info("Suggested commit message:");
9162
- const commitType = task.type || "feat";
9163
- console.log(
9164
- colors2.highlight(` ${commitType}(task-${normalizedId}): ${task.title}`)
9165
- );
9166
- console.log();
9167
- info("Next steps:");
9168
- console.log(colors2.secondary(" 1. Review your changes"));
9169
- console.log(colors2.secondary(" 2. Commit: git add . && git commit"));
9170
- console.log(colors2.secondary(" 3. Push: git push"));
9171
- console.log(colors2.secondary(" 4. Create a Pull Request"));
9281
+ info("Next steps (suggestions):");
9282
+ if (!options.skipUpdate) {
9283
+ const commitType = task.type || "feat";
9284
+ console.log(
9285
+ colors2.secondary(
9286
+ ` 1. Commit the status change: git add TASKS/task-${normalizedId}-*.md && git commit -m "docs(TASKS): task-${normalizedId} - atualiza status para done [skip-ci]"`
9287
+ )
9288
+ );
9289
+ console.log(colors2.secondary(" 2. Review your changes"));
9290
+ console.log(
9291
+ colors2.secondary(
9292
+ ` 3. Commit your work: git add . && git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`
9293
+ )
9294
+ );
9295
+ console.log(colors2.secondary(" 4. Push: git push"));
9296
+ console.log(colors2.secondary(" 5. Create a Pull Request"));
9297
+ } else {
9298
+ const commitType = task.type || "feat";
9299
+ console.log(colors2.secondary(" 1. Review your changes"));
9300
+ console.log(
9301
+ colors2.secondary(
9302
+ ` 2. Commit your work: git add . && git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`
9303
+ )
9304
+ );
9305
+ console.log(colors2.secondary(" 3. Push: git push"));
9306
+ console.log(colors2.secondary(" 4. Create a Pull Request"));
9307
+ }
9172
9308
  console.log();
9173
9309
  success("Great work! \u{1F680}");
9174
9310
  console.log();
@@ -9648,6 +9784,14 @@ var listCommand = defineCommand({
9648
9784
  {
9649
9785
  flags: "-u, --user <user>",
9650
9786
  description: "Filter by user"
9787
+ },
9788
+ {
9789
+ flags: "--open",
9790
+ description: "Show only open tasks (pending, in-progress, blocked)"
9791
+ },
9792
+ {
9793
+ flags: "--closed",
9794
+ description: "Show only closed tasks (done, canceled)"
9651
9795
  }
9652
9796
  ],
9653
9797
  handler: async (filter, options) => {
@@ -9668,9 +9812,19 @@ async function listTasks(filter, options) {
9668
9812
  console.log(colors2.warning("No tasks found in TASKS/ directory"));
9669
9813
  return;
9670
9814
  }
9815
+ const openStatuses = ["pending", "in-progress", "blocked"];
9816
+ const closedStatuses = ["done", "canceled"];
9671
9817
  let filteredTasks = tasks;
9672
9818
  if (options.status) {
9673
9819
  filteredTasks = filteredTasks.filter((t) => t.status === options.status);
9820
+ } else if (options.open) {
9821
+ filteredTasks = filteredTasks.filter(
9822
+ (t) => t.status && openStatuses.includes(t.status)
9823
+ );
9824
+ } else if (options.closed) {
9825
+ filteredTasks = filteredTasks.filter(
9826
+ (t) => t.status && closedStatuses.includes(t.status)
9827
+ );
9674
9828
  }
9675
9829
  if (options.type) {
9676
9830
  filteredTasks = filteredTasks.filter((t) => t.type === options.type);
@@ -9754,19 +9908,19 @@ function getTypeColor(type) {
9754
9908
  // src/commands/mcp-server.ts
9755
9909
  init_esm_shims();
9756
9910
 
9757
- // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.4_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/index.js
9911
+ // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.5_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/index.js
9758
9912
  init_esm_shims();
9759
9913
 
9760
- // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.4_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.js
9914
+ // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.5_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.js
9761
9915
  init_esm_shims();
9762
9916
 
9763
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
9917
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
9764
9918
  init_esm_shims();
9765
9919
 
9766
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
9920
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
9767
9921
  init_esm_shims();
9768
9922
 
9769
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
9923
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
9770
9924
  init_esm_shims();
9771
9925
  import * as z3rt from "zod/v3";
9772
9926
  import * as z4mini from "zod/v4-mini";
@@ -9832,7 +9986,7 @@ function getLiteralValue(schema) {
9832
9986
  return void 0;
9833
9987
  }
9834
9988
 
9835
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
9989
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
9836
9990
  init_esm_shims();
9837
9991
  import * as z2 from "zod/v4";
9838
9992
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
@@ -11340,138 +11494,138 @@ var UrlElicitationRequiredError = class extends McpError {
11340
11494
  }
11341
11495
  };
11342
11496
 
11343
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
11497
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
11344
11498
  init_esm_shims();
11345
11499
  function isTerminal(status) {
11346
11500
  return status === "completed" || status === "failed" || status === "cancelled";
11347
11501
  }
11348
11502
 
11349
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
11503
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
11350
11504
  init_esm_shims();
11351
11505
  import * as z4mini2 from "zod/v4-mini";
11352
11506
 
11353
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/index.js
11507
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/index.js
11354
11508
  init_esm_shims();
11355
11509
 
11356
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Options.js
11510
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Options.js
11357
11511
  init_esm_shims();
11358
11512
 
11359
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Refs.js
11513
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/Refs.js
11360
11514
  init_esm_shims();
11361
11515
 
11362
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/errorMessages.js
11516
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/errorMessages.js
11363
11517
  init_esm_shims();
11364
11518
 
11365
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js
11519
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js
11366
11520
  init_esm_shims();
11367
11521
 
11368
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parseDef.js
11522
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parseDef.js
11369
11523
  init_esm_shims();
11370
11524
 
11371
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/selectParser.js
11525
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/selectParser.js
11372
11526
  init_esm_shims();
11373
11527
  import { ZodFirstPartyTypeKind as ZodFirstPartyTypeKind3 } from "zod/v3";
11374
11528
 
11375
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/any.js
11529
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/any.js
11376
11530
  init_esm_shims();
11377
11531
 
11378
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/array.js
11532
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/array.js
11379
11533
  init_esm_shims();
11380
11534
  import { ZodFirstPartyTypeKind } from "zod/v3";
11381
11535
 
11382
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js
11536
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js
11383
11537
  init_esm_shims();
11384
11538
 
11385
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js
11539
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js
11386
11540
  init_esm_shims();
11387
11541
 
11388
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js
11542
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js
11389
11543
  init_esm_shims();
11390
11544
 
11391
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js
11545
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js
11392
11546
  init_esm_shims();
11393
11547
 
11394
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/date.js
11548
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/date.js
11395
11549
  init_esm_shims();
11396
11550
 
11397
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/default.js
11551
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/default.js
11398
11552
  init_esm_shims();
11399
11553
 
11400
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js
11554
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js
11401
11555
  init_esm_shims();
11402
11556
 
11403
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js
11557
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js
11404
11558
  init_esm_shims();
11405
11559
 
11406
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js
11560
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js
11407
11561
  init_esm_shims();
11408
11562
 
11409
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js
11563
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js
11410
11564
  init_esm_shims();
11411
11565
 
11412
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/map.js
11566
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/map.js
11413
11567
  init_esm_shims();
11414
11568
 
11415
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/record.js
11569
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/record.js
11416
11570
  init_esm_shims();
11417
11571
  import { ZodFirstPartyTypeKind as ZodFirstPartyTypeKind2 } from "zod/v3";
11418
11572
 
11419
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/string.js
11573
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/string.js
11420
11574
  init_esm_shims();
11421
11575
  var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
11422
11576
 
11423
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js
11577
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js
11424
11578
  init_esm_shims();
11425
11579
 
11426
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/never.js
11580
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/never.js
11427
11581
  init_esm_shims();
11428
11582
 
11429
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/null.js
11583
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/null.js
11430
11584
  init_esm_shims();
11431
11585
 
11432
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js
11586
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js
11433
11587
  init_esm_shims();
11434
11588
 
11435
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/union.js
11589
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/union.js
11436
11590
  init_esm_shims();
11437
11591
 
11438
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/number.js
11592
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/number.js
11439
11593
  init_esm_shims();
11440
11594
 
11441
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/object.js
11595
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/object.js
11442
11596
  init_esm_shims();
11443
11597
 
11444
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js
11598
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js
11445
11599
  init_esm_shims();
11446
11600
 
11447
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js
11601
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js
11448
11602
  init_esm_shims();
11449
11603
 
11450
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js
11604
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js
11451
11605
  init_esm_shims();
11452
11606
 
11453
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/set.js
11607
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/set.js
11454
11608
  init_esm_shims();
11455
11609
 
11456
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js
11610
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js
11457
11611
  init_esm_shims();
11458
11612
 
11459
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js
11613
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js
11460
11614
  init_esm_shims();
11461
11615
 
11462
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js
11616
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js
11463
11617
  init_esm_shims();
11464
11618
 
11465
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js
11619
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js
11466
11620
  init_esm_shims();
11467
11621
 
11468
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parseTypes.js
11622
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parseTypes.js
11469
11623
  init_esm_shims();
11470
11624
 
11471
- // ../../node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js
11625
+ // ../../node_modules/.pnpm/zod-to-json-schema@3.25.1_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js
11472
11626
  init_esm_shims();
11473
11627
 
11474
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
11628
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
11475
11629
  function getMethodLiteral(schema) {
11476
11630
  const shape = getObjectShape(schema);
11477
11631
  const methodSchema = shape?.method;
@@ -11492,7 +11646,7 @@ function parseWithCompat(schema, data) {
11492
11646
  return result.data;
11493
11647
  }
11494
11648
 
11495
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
11649
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
11496
11650
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
11497
11651
  var Protocol = class {
11498
11652
  constructor(_options) {
@@ -12428,7 +12582,7 @@ function mergeCapabilities(base, additional) {
12428
12582
  return result;
12429
12583
  }
12430
12584
 
12431
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
12585
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
12432
12586
  init_esm_shims();
12433
12587
  var import_ajv = __toESM(require_ajv(), 1);
12434
12588
  var import_ajv_formats = __toESM(require_dist(), 1);
@@ -12497,7 +12651,7 @@ var AjvJsonSchemaValidator = class {
12497
12651
  }
12498
12652
  };
12499
12653
 
12500
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
12654
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
12501
12655
  init_esm_shims();
12502
12656
  var ExperimentalServerTasks = class {
12503
12657
  constructor(_server) {
@@ -12570,7 +12724,7 @@ var ExperimentalServerTasks = class {
12570
12724
  }
12571
12725
  };
12572
12726
 
12573
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
12727
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
12574
12728
  init_esm_shims();
12575
12729
  function assertToolsCallTaskCapability(requests, method, entityName) {
12576
12730
  if (!requests) {
@@ -12606,7 +12760,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
12606
12760
  }
12607
12761
  }
12608
12762
 
12609
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
12763
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
12610
12764
  var Server = class extends Protocol {
12611
12765
  /**
12612
12766
  * Initializes this server with the given name and version information.
@@ -12986,11 +13140,11 @@ var Server = class extends Protocol {
12986
13140
  }
12987
13141
  };
12988
13142
 
12989
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
13143
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
12990
13144
  init_esm_shims();
12991
13145
  import process2 from "process";
12992
13146
 
12993
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
13147
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
12994
13148
  init_esm_shims();
12995
13149
  var ReadBuffer = class {
12996
13150
  append(chunk) {
@@ -13019,7 +13173,7 @@ function serializeMessage(message) {
13019
13173
  return JSON.stringify(message) + "\n";
13020
13174
  }
13021
13175
 
13022
- // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.1_hono@4.11.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
13176
+ // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.2_hono@4.11.4_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
13023
13177
  var StdioServerTransport = class {
13024
13178
  constructor(_stdin = process2.stdin, _stdout = process2.stdout) {
13025
13179
  this._stdin = _stdin;
@@ -13080,7 +13234,7 @@ var StdioServerTransport = class {
13080
13234
  }
13081
13235
  };
13082
13236
 
13083
- // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.4_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.js
13237
+ // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.5_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.js
13084
13238
  var TaskMCPServer = class {
13085
13239
  server;
13086
13240
  taskManager;
@@ -13475,7 +13629,7 @@ Let me start by marking the task as done using the finish_task tool.`
13475
13629
  }
13476
13630
  };
13477
13631
 
13478
- // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.4_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.types.js
13632
+ // ../../node_modules/.pnpm/@opentask+taskin-task-server-mcp@0.1.5_zod@3.25.76/node_modules/@opentask/taskin-task-server-mcp/dist/task-server-mcp.types.js
13479
13633
  init_esm_shims();
13480
13634
 
13481
13635
  // src/commands/mcp-server.ts
@@ -13680,7 +13834,7 @@ async function createTask(options) {
13680
13834
  }).filter((num) => !isNaN(num));
13681
13835
  const nextNumber = taskNumbers.length > 0 ? Math.max(...taskNumbers) + 1 : 1;
13682
13836
  const taskId = String(nextNumber).padStart(3, "0");
13683
- const titleSlug = options.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
13837
+ const titleSlug = slugify(options.title);
13684
13838
  const fileName = `task-${taskId}-${titleSlug}.md`;
13685
13839
  const filePath = path12.join(tasksDir, fileName);
13686
13840
  if (existsSync5(filePath)) {
@@ -13871,14 +14025,19 @@ async function startTask(taskId, _options) {
13871
14025
  success(`Task ${updatedTask.id} started successfully!`);
13872
14026
  success(`Status changed to: ${updatedTask.status}`);
13873
14027
  console.log();
13874
- info("Next steps:");
14028
+ info("Next steps (suggestions):");
13875
14029
  console.log(
13876
14030
  colors2.secondary(
13877
- " 1. Create a branch: git checkout -b feat/task-" + normalizedId
14031
+ ` 1. Commit the status change: git add TASKS/task-${normalizedId}-*.md && git commit -m "docs(TASKS): task-${normalizedId} - atualiza status para in-progress [skip ci]"`
13878
14032
  )
13879
14033
  );
13880
- console.log(colors2.secondary(" 2. Start coding! \u{1F4BB}"));
13881
- console.log(colors2.secondary(' 3. Use "taskin pause" to save progress'));
14034
+ console.log(
14035
+ colors2.secondary(
14036
+ " 2. Create a branch: git checkout -b feat/task-" + normalizedId
14037
+ )
14038
+ );
14039
+ console.log(colors2.secondary(" 3. Start coding! \u{1F4BB}"));
14040
+ console.log(colors2.secondary(' 4. Use "taskin pause" to save progress'));
13882
14041
  console.log();
13883
14042
  if (_options.sound !== false) {
13884
14043
  playSound("start");
@@ -14054,7 +14213,7 @@ function displayTeamStats(stats, detailed = false) {
14054
14213
  });
14055
14214
  }
14056
14215
  }
14057
- function displayTaskStats(stats, detailed = false) {
14216
+ function displayTaskStats(stats, _detailed = false) {
14058
14217
  console.log(`${chalk6.dim("Task:")} ${stats.taskId} - ${stats.title}
14059
14218
  `);
14060
14219
  console.log(chalk6.bold("\u{1F4CB} Task Info"));
@@ -14152,7 +14311,7 @@ function showCustomHelp() {
14152
14311
  {
14153
14312
  name: colors2.highlight("taskin start") + colors2.normal(" <task-id>"),
14154
14313
  alias: colors2.secondary("Alias: begin"),
14155
- description: "Start working on a task",
14314
+ description: "Start working on a task (suggests commits)",
14156
14315
  examples: [
14157
14316
  "taskin start 001",
14158
14317
  "taskin start task-001",
@@ -14163,17 +14322,28 @@ function showCustomHelp() {
14163
14322
  {
14164
14323
  name: colors2.highlight("taskin pause") + colors2.normal(" <task-id>"),
14165
14324
  alias: colors2.secondary("Alias: stop"),
14166
- description: "Pause a task (commit without push)",
14325
+ description: "Pause a task (auto-commits work in progress)",
14167
14326
  examples: ["taskin pause 001", 'taskin pause 001 -m "saving progress"'],
14168
14327
  icon: "\u23F8\uFE0F"
14169
14328
  },
14170
14329
  {
14171
14330
  name: colors2.highlight("taskin finish") + colors2.normal(" <task-id>"),
14172
14331
  alias: colors2.secondary("Alias: done"),
14173
- description: "Finish a task",
14332
+ description: "Finish a task (suggests commits)",
14174
14333
  examples: ["taskin finish 001", "taskin done task-001"],
14175
14334
  icon: "\u2705"
14176
14335
  },
14336
+ {
14337
+ name: colors2.highlight("taskin config") + colors2.normal(" [options]"),
14338
+ alias: colors2.secondary("Options: --level <manual|assisted|autopilot>"),
14339
+ description: "Configure automation level",
14340
+ examples: [
14341
+ "taskin config",
14342
+ "taskin config --level assisted",
14343
+ "taskin config --level autopilot"
14344
+ ],
14345
+ icon: "\u2699\uFE0F"
14346
+ },
14177
14347
  {
14178
14348
  name: colors2.highlight("taskin lint") + colors2.normal(" [options]"),
14179
14349
  alias: colors2.secondary("Options: -p, --path <directory>"),
@@ -14187,12 +14357,15 @@ function showCustomHelp() {
14187
14357
  },
14188
14358
  {
14189
14359
  name: colors2.highlight("taskin dashboard") + colors2.normal(" [options]"),
14190
- alias: colors2.secondary("Options: --host, --port"),
14360
+ alias: colors2.secondary(
14361
+ "Options: --host, --port, --filter-open, --filter-closed"
14362
+ ),
14191
14363
  description: "Start the web dashboard",
14192
14364
  examples: [
14193
14365
  "taskin dashboard",
14194
14366
  "taskin dashboard --port 3000",
14195
- "taskin dashboard --host 0.0.0.0"
14367
+ "taskin dashboard --filter-open",
14368
+ "taskin dashboard --filter-closed -o"
14196
14369
  ],
14197
14370
  icon: "\u{1F4CA}"
14198
14371
  },
@@ -14228,6 +14401,11 @@ function showCustomHelp() {
14228
14401
  `${colors2.warning("\u2022")} Use short IDs: ${colors2.highlight("001")}, ${colors2.highlight("task-001")}`
14229
14402
  )
14230
14403
  );
14404
+ console.log(
14405
+ colors2.normal(
14406
+ `${colors2.warning("\u2022")} Configure automation with ${colors2.highlight("taskin config --level <manual|assisted|autopilot>")}`
14407
+ )
14408
+ );
14231
14409
  console.log(
14232
14410
  colors2.normal(
14233
14411
  `${colors2.warning("\u2022")} All commands support ${colors2.highlight("--help")} for more options`
@@ -14644,8 +14822,10 @@ function getTaskin() {
14644
14822
 
14645
14823
  // src/index.ts
14646
14824
  var program = new Command();
14647
- program.name("taskin").description("\u{1F680} Task Management System").version(getVersion()).configureHelp({
14648
- formatHelp: () => showCustomHelp()
14825
+ program.name("taskin").description("\u{1F680} Task Management System").version(getVersion());
14826
+ program.helpOption("-h, --help", "Display help information");
14827
+ program.command("help").description("Show help information").action(() => {
14828
+ showCustomHelp();
14649
14829
  });
14650
14830
  initCommand(program);
14651
14831
  listCommand(program);
@@ -14658,10 +14838,18 @@ registerExportCommand(program);
14658
14838
  lintCommand(program);
14659
14839
  dashboardCommand(program);
14660
14840
  mcpServerCommand(program);
14841
+ program.on("option:help", () => {
14842
+ showCustomHelp();
14843
+ process.exit(0);
14844
+ });
14661
14845
  if (process.argv.length <= 2) {
14662
14846
  showCustomHelp();
14663
14847
  process.exit(0);
14664
14848
  }
14849
+ if (process.argv.length === 3 && (process.argv[2] === "--help" || process.argv[2] === "-h")) {
14850
+ showCustomHelp();
14851
+ process.exit(0);
14852
+ }
14665
14853
  program.parse();
14666
14854
  export {
14667
14855
  Taskin,