taskin 2.2.1 → 2.3.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.
Files changed (2) hide show
  1. package/dist/index.js +102 -70
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -7291,11 +7291,15 @@ ${result.error.message}`);
7291
7291
  }
7292
7292
  /**
7293
7293
  * Get automation level from config
7294
- * Returns 'assisted' as default if not configured
7294
+ * Returns 'assisted' as default if not configured or if config loading fails
7295
7295
  */
7296
7296
  getAutomationLevel() {
7297
- const config = this.loadConfig();
7298
- return config.automation?.level ?? "assisted";
7297
+ try {
7298
+ const config = this.loadConfig();
7299
+ return config.automation?.level ?? "assisted";
7300
+ } catch {
7301
+ return "assisted";
7302
+ }
7299
7303
  }
7300
7304
  /**
7301
7305
  * Set automation level in config
@@ -7312,8 +7316,12 @@ ${result.error.message}`);
7312
7316
  * Get automation configuration
7313
7317
  */
7314
7318
  getAutomationConfig() {
7315
- const config = this.loadConfig();
7316
- return config.automation ?? { level: "assisted" };
7319
+ try {
7320
+ const config = this.loadConfig();
7321
+ return config.automation ?? { level: "assisted" };
7322
+ } catch {
7323
+ return { level: "assisted" };
7324
+ }
7317
7325
  }
7318
7326
  /**
7319
7327
  * Set automation configuration
@@ -8147,9 +8155,7 @@ var FileSystemTaskProvider = class {
8147
8155
  }
8148
8156
  async findTask(taskId) {
8149
8157
  const files = await fs2.readdir(this.tasksDirectory);
8150
- const taskFile = files.find(
8151
- (file) => file.startsWith(`task-${taskId}-`) && file.endsWith(".md")
8152
- );
8158
+ const taskFile = files.find((file) => file.startsWith(`task-${taskId}-`) && file.endsWith(".md"));
8153
8159
  if (!taskFile) {
8154
8160
  return void 0;
8155
8161
  }
@@ -8165,7 +8171,8 @@ var FileSystemTaskProvider = class {
8165
8171
  const escapedName = n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8166
8172
  const rx = new RegExp(`^${escapedName}:\\s*(.+)$`, "im");
8167
8173
  const m = content.match(rx);
8168
- if (m) return m[1].trim();
8174
+ if (m)
8175
+ return m[1].trim();
8169
8176
  }
8170
8177
  return null;
8171
8178
  };
@@ -8177,9 +8184,7 @@ var FileSystemTaskProvider = class {
8177
8184
  const assigneeValue = assigneeMatch.trim();
8178
8185
  assignee = this.userRegistry.resolveUser(assigneeValue);
8179
8186
  if (!assignee) {
8180
- console.warn(
8181
- `[FS Provider] User "${assigneeValue}" not found in registry, creating temporary user`
8182
- );
8187
+ console.warn(`[FS Provider] User "${assigneeValue}" not found in registry, creating temporary user`);
8183
8188
  assignee = this.userRegistry.createTemporaryUser(assigneeValue);
8184
8189
  }
8185
8190
  }
@@ -8197,9 +8202,7 @@ var FileSystemTaskProvider = class {
8197
8202
  }
8198
8203
  async updateTask(task) {
8199
8204
  const currentContent = await fs2.readFile(task.filePath, "utf-8");
8200
- const hasSectionMetadata = /##\s*(Status|Type|Assignee)/i.test(
8201
- currentContent
8202
- );
8205
+ const hasSectionMetadata = /##\s*(Status|Type|Assignee)/i.test(currentContent);
8203
8206
  if (hasSectionMetadata) {
8204
8207
  const { fixTaskFile: fixTaskFile2 } = await Promise.resolve().then(() => (init_task_validator(), task_validator_exports));
8205
8208
  await fixTaskFile2(task.filePath);
@@ -8207,24 +8210,16 @@ var FileSystemTaskProvider = class {
8207
8210
  const content = await fs2.readFile(task.filePath, "utf-8");
8208
8211
  let updatedContent;
8209
8212
  if (/^Status:\s*.+$/im.test(content)) {
8210
- updatedContent = content.replace(
8211
- /^Status:\s*.+$/im,
8212
- `Status: ${task.status}`
8213
- );
8213
+ updatedContent = content.replace(/^Status:\s*.+$/im, `Status: ${task.status}`);
8214
8214
  } else {
8215
- updatedContent = content.replace(
8216
- /(^#.*\n)/,
8217
- `$1Status: ${task.status}
8218
- `
8219
- );
8215
+ updatedContent = content.replace(/(^#.*\n)/, `$1Status: ${task.status}
8216
+ `);
8220
8217
  }
8221
8218
  await fs2.writeFile(task.filePath, updatedContent, "utf-8");
8222
8219
  }
8223
8220
  async getAllTasks() {
8224
8221
  const files = await fs2.readdir(this.tasksDirectory);
8225
- const taskFiles = files.filter(
8226
- (file) => file.startsWith("task-") && file.endsWith(".md")
8227
- );
8222
+ const taskFiles = files.filter((file) => file.startsWith("task-") && file.endsWith(".md"));
8228
8223
  const tasks = [];
8229
8224
  for (const file of taskFiles) {
8230
8225
  const filePath = path4.join(this.tasksDirectory, file);
@@ -8241,7 +8236,8 @@ var FileSystemTaskProvider = class {
8241
8236
  const escapedName = n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8242
8237
  const rx = new RegExp(`^${escapedName}:\\s*(.+)$`, "im");
8243
8238
  const m = content.match(rx);
8244
- if (m) return m[1].trim();
8239
+ if (m)
8240
+ return m[1].trim();
8245
8241
  }
8246
8242
  return null;
8247
8243
  };
@@ -8390,9 +8386,7 @@ var UserRegistry = class {
8390
8386
  console.log(`[UserRegistry] Loaded ${this.users.size} users`);
8391
8387
  } catch (error2) {
8392
8388
  if (error2.code === "ENOENT") {
8393
- console.warn(
8394
- "[UserRegistry] users.json not found, starting with empty registry"
8395
- );
8389
+ console.warn("[UserRegistry] users.json not found, starting with empty registry");
8396
8390
  this.users.clear();
8397
8391
  } else {
8398
8392
  throw error2;
@@ -8411,10 +8405,12 @@ var UserRegistry = class {
8411
8405
  */
8412
8406
  resolveUser(nameOrId) {
8413
8407
  const byId = this.users.get(nameOrId);
8414
- if (byId) return byId;
8408
+ if (byId)
8409
+ return byId;
8415
8410
  const slug = nameOrId.toLowerCase().replace(/\s+/g, "-");
8416
8411
  const bySlug = this.users.get(slug);
8417
- if (bySlug) return bySlug;
8412
+ if (bySlug)
8413
+ return bySlug;
8418
8414
  for (const user of this.users.values()) {
8419
8415
  if (user.name.toLowerCase() === nameOrId.toLowerCase()) {
8420
8416
  return user;
@@ -8454,11 +8450,7 @@ var UserRegistry = class {
8454
8450
  const data = {
8455
8451
  users: Object.fromEntries(this.users.entries())
8456
8452
  };
8457
- await fs3.writeFile(
8458
- this.usersFilePath,
8459
- JSON.stringify(data, null, 2),
8460
- "utf-8"
8461
- );
8453
+ await fs3.writeFile(this.usersFilePath, JSON.stringify(data, null, 2), "utf-8");
8462
8454
  }
8463
8455
  };
8464
8456
 
@@ -9486,6 +9478,7 @@ function registerExportCommand(program2) {
9486
9478
 
9487
9479
  // src/commands/finish.ts
9488
9480
  init_esm_shims();
9481
+ import { execSync } from "child_process";
9489
9482
  import path9 from "path";
9490
9483
 
9491
9484
  // src/lib/sound-player.ts
@@ -9561,43 +9554,75 @@ async function finishTask(taskId, options) {
9561
9554
  error("Task is already done");
9562
9555
  process.exit(1);
9563
9556
  }
9557
+ const configManager = new ConfigManager(monorepoRoot);
9558
+ const behavior = configManager.getAutomationBehavior();
9564
9559
  if (!options.skipUpdate) {
9565
9560
  info("Marking task as done...");
9566
9561
  const updatedTask = await taskManager.finishTask(task.id);
9567
9562
  success(`Task ${updatedTask.id} completed successfully! \u{1F389}`);
9568
9563
  success(`Status changed to: ${updatedTask.status}`);
9564
+ if (behavior.autoCommitStatusChange) {
9565
+ try {
9566
+ execSync(
9567
+ `git add TASKS/task-${normalizedId}-*.md && git commit -m "docs(TASKS): task-${normalizedId} - atualiza status para done [skip-ci]"`,
9568
+ { cwd: process.cwd(), stdio: "ignore" }
9569
+ );
9570
+ success("\u2713 Auto-committed status change");
9571
+ } catch {
9572
+ }
9573
+ }
9574
+ if (behavior.autoCommitFinish) {
9575
+ const commitType = task.type || "feat";
9576
+ try {
9577
+ execSync("git add .", { cwd: process.cwd(), stdio: "ignore" });
9578
+ execSync(
9579
+ `git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`,
9580
+ { cwd: process.cwd(), stdio: "ignore" }
9581
+ );
9582
+ success("\u2713 Auto-committed completed work");
9583
+ } catch {
9584
+ }
9585
+ }
9569
9586
  } else {
9570
9587
  info("Skipping status update (--skip-update flag)");
9571
9588
  }
9572
9589
  console.log();
9573
- info("Next steps (suggestions):");
9574
- if (!options.skipUpdate) {
9575
- const commitType = task.type || "feat";
9576
- console.log(
9577
- colors.secondary(
9578
- ` 1. Commit the status change: git add TASKS/task-${normalizedId}-*.md && git commit -m "docs(TASKS): task-${normalizedId} - atualiza status para done [skip-ci]"`
9579
- )
9580
- );
9581
- console.log(colors.secondary(" 2. Review your changes"));
9582
- console.log(
9583
- colors.secondary(
9584
- ` 3. Commit your work: git add . && git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`
9585
- )
9586
- );
9587
- console.log(colors.secondary(" 4. Push: git push"));
9588
- console.log(colors.secondary(" 5. Create a Pull Request"));
9590
+ if (!behavior.autoCommitFinish || options.skipUpdate) {
9591
+ info("Next steps (suggestions):");
9592
+ if (!options.skipUpdate) {
9593
+ const commitType = task.type || "feat";
9594
+ console.log(
9595
+ colors.secondary(
9596
+ ` 1. Commit the status change: git add TASKS/task-${normalizedId}-*.md && git commit -m "docs(TASKS): task-${normalizedId} - atualiza status para done [skip-ci]"`
9597
+ )
9598
+ );
9599
+ console.log(colors.secondary(" 2. Review your changes"));
9600
+ console.log(
9601
+ colors.secondary(
9602
+ ` 3. Commit your work: git add . && git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`
9603
+ )
9604
+ );
9605
+ console.log(colors.secondary(" 4. Push: git push"));
9606
+ console.log(colors.secondary(" 5. Create a Pull Request"));
9607
+ } else {
9608
+ const commitType = task.type || "feat";
9609
+ console.log(colors.secondary(" 1. Review your changes"));
9610
+ console.log(
9611
+ colors.secondary(
9612
+ ` 2. Commit your work: git add . && git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`
9613
+ )
9614
+ );
9615
+ console.log(colors.secondary(" 3. Push: git push"));
9616
+ console.log(colors.secondary(" 4. Create a Pull Request"));
9617
+ }
9618
+ console.log();
9589
9619
  } else {
9590
- const commitType = task.type || "feat";
9591
- console.log(colors.secondary(" 1. Review your changes"));
9592
- console.log(
9593
- colors.secondary(
9594
- ` 2. Commit your work: git add . && git commit -m "${commitType}(task-${normalizedId}): ${task.title}"`
9595
- )
9596
- );
9597
- console.log(colors.secondary(" 3. Push: git push"));
9598
- console.log(colors.secondary(" 4. Create a Pull Request"));
9620
+ info("All commits done automatically (autopilot mode)");
9621
+ info("Next steps:");
9622
+ console.log(colors.secondary(" 1. Push: git push"));
9623
+ console.log(colors.secondary(" 2. Create a Pull Request"));
9624
+ console.log();
9599
9625
  }
9600
- console.log();
9601
9626
  success("Great work! \u{1F680}");
9602
9627
  console.log();
9603
9628
  if (options.sound !== false) {
@@ -9622,7 +9647,7 @@ init_esm_shims();
9622
9647
 
9623
9648
  // src/lib/provider-installer/provider-installer.ts
9624
9649
  init_esm_shims();
9625
- import { execSync } from "child_process";
9650
+ import { execSync as execSync2 } from "child_process";
9626
9651
  import { existsSync as existsSync4 } from "fs";
9627
9652
  function detectPackageManager() {
9628
9653
  if (existsSync4("pnpm-lock.yaml")) {
@@ -9671,7 +9696,7 @@ function installProvider(provider) {
9671
9696
  default:
9672
9697
  command = `npm install ${packageName}`;
9673
9698
  }
9674
- execSync(command, { stdio: "inherit" });
9699
+ execSync2(command, { stdio: "inherit" });
9675
9700
  console.log(`\u2705 ${packageName} installed successfully!
9676
9701
  `);
9677
9702
  } catch (error2) {
@@ -14180,7 +14205,7 @@ Add any relevant notes or links here.
14180
14205
 
14181
14206
  // src/commands/pause.ts
14182
14207
  init_esm_shims();
14183
- import { execSync as execSync2 } from "child_process";
14208
+ import { execSync as execSync3 } from "child_process";
14184
14209
  import path13 from "path";
14185
14210
  var pauseCommand = defineCommand({
14186
14211
  name: "pause <task-id>",
@@ -14226,18 +14251,25 @@ async function pauseTask(taskId, options) {
14226
14251
  process.exit(1);
14227
14252
  }
14228
14253
  const commitMessage = options.message || `WIP: task-${normalizedId} - ${task.title}`;
14254
+ const configManager = new ConfigManager(monorepoRoot);
14255
+ const behavior = configManager.getAutomationBehavior();
14229
14256
  if (options.skipCommit) {
14230
14257
  info("Would create commit with message:");
14231
14258
  console.log(colors.highlight(` "${commitMessage}"`));
14232
14259
  console.log();
14233
14260
  info("Use without --skip-commit to actually commit");
14261
+ } else if (!behavior.autoCommitPause) {
14262
+ info("Commit suggestion (manual mode):");
14263
+ console.log(colors.secondary(` git add -A && git commit -m "${commitMessage}"`));
14264
+ console.log();
14265
+ info("Status will be updated to pending");
14234
14266
  } else {
14235
14267
  info("Creating commit...");
14236
14268
  console.log(colors.secondary(` Message: "${commitMessage}"`));
14237
14269
  console.log();
14238
14270
  try {
14239
- execSync2("git add -A", { cwd: process.cwd(), stdio: "ignore" });
14240
- execSync2(`git commit -m "${commitMessage}"`, {
14271
+ execSync3("git add -A", { cwd: process.cwd(), stdio: "ignore" });
14272
+ execSync3(`git commit -m "${commitMessage}"`, {
14241
14273
  cwd: process.cwd(),
14242
14274
  stdio: "ignore"
14243
14275
  });
@@ -14246,7 +14278,7 @@ async function pauseTask(taskId, options) {
14246
14278
  const updatedTask = { ...task, status: "pending" };
14247
14279
  await taskProvider.updateTask(updatedTask);
14248
14280
  success("Task paused successfully!");
14249
- info("Commit created (not pushed)");
14281
+ success("\u2713 Auto-committed work in progress");
14250
14282
  info("Status updated to pending");
14251
14283
  console.log();
14252
14284
  info("Next steps:");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskin",
3
- "version": "2.2.1",
3
+ "version": "2.3.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",
@@ -68,10 +68,10 @@
68
68
  "LICENSE"
69
69
  ],
70
70
  "dependencies": {
71
- "@opentask/taskin-git-utils": "^2.0.3",
72
- "@opentask/taskin-task-manager": "^1.0.8",
73
- "@opentask/taskin-task-server-mcp": "^0.1.6",
74
- "@opentask/taskin-task-server-ws": "^0.1.3",
71
+ "@opentask/taskin-git-utils": "^2.1.1",
72
+ "@opentask/taskin-task-manager": "^1.0.9",
73
+ "@opentask/taskin-task-server-mcp": "^0.1.7",
74
+ "@opentask/taskin-task-server-ws": "^0.1.4",
75
75
  "@types/express": "^5.0.5",
76
76
  "@types/inquirer": "^9.0.9",
77
77
  "@types/play-sound": "^1.1.2",
@@ -82,9 +82,9 @@
82
82
  "play-sound": "^1.1.6",
83
83
  "ws": "^8.18.3",
84
84
  "zod": "^3.25.76",
85
- "@opentask/taskin-file-system-provider": "2.2.0",
85
+ "@opentask/taskin-file-system-provider": "2.2.1",
86
86
  "@opentask/taskin-utils": "1.1.0",
87
- "@opentask/taskin-types": "1.0.5"
87
+ "@opentask/taskin-types": "1.0.6"
88
88
  },
89
89
  "devDependencies": {
90
90
  "@types/node": "^20.19.24",