taskin 0.1.0-beta.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 (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/dist/commands/commands.types.d.ts +13 -0
  4. package/dist/commands/commands.types.js +6 -0
  5. package/dist/commands/commands.types.js.map +1 -0
  6. package/dist/commands/define-command/define-command.d.ts +6 -0
  7. package/dist/commands/define-command/define-command.js +27 -0
  8. package/dist/commands/define-command/define-command.js.map +1 -0
  9. package/dist/commands/define-command/define-command.test.d.ts +4 -0
  10. package/dist/commands/define-command/define-command.test.js +125 -0
  11. package/dist/commands/define-command/define-command.test.js.map +1 -0
  12. package/dist/commands/define-command/define-command.types.d.ts +49 -0
  13. package/dist/commands/define-command/define-command.types.js +5 -0
  14. package/dist/commands/define-command/define-command.types.js.map +1 -0
  15. package/dist/commands/define-command/index.d.ts +5 -0
  16. package/dist/commands/define-command/index.js +6 -0
  17. package/dist/commands/define-command/index.js.map +1 -0
  18. package/dist/commands/finish.d.ts +4 -0
  19. package/dist/commands/finish.js +69 -0
  20. package/dist/commands/finish.js.map +1 -0
  21. package/dist/commands/index.d.ts +9 -0
  22. package/dist/commands/index.js +10 -0
  23. package/dist/commands/index.js.map +1 -0
  24. package/dist/commands/init.d.ts +4 -0
  25. package/dist/commands/init.js +192 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/lint.d.ts +4 -0
  28. package/dist/commands/lint.js +31 -0
  29. package/dist/commands/lint.js.map +1 -0
  30. package/dist/commands/list.d.ts +4 -0
  31. package/dist/commands/list.js +132 -0
  32. package/dist/commands/list.js.map +1 -0
  33. package/dist/commands/pause.d.ts +4 -0
  34. package/dist/commands/pause.js +69 -0
  35. package/dist/commands/pause.js.map +1 -0
  36. package/dist/commands/start.d.ts +4 -0
  37. package/dist/commands/start.js +70 -0
  38. package/dist/commands/start.js.map +1 -0
  39. package/dist/index.d.ts +8 -0
  40. package/dist/index.js +38 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/lib/colors.d.ts +26 -0
  43. package/dist/lib/colors.js +42 -0
  44. package/dist/lib/colors.js.map +1 -0
  45. package/dist/lib/file-system-task-linter/file-system-task-linter.d.ts +36 -0
  46. package/dist/lib/file-system-task-linter/file-system-task-linter.js +219 -0
  47. package/dist/lib/file-system-task-linter/file-system-task-linter.js.map +1 -0
  48. package/dist/lib/file-system-task-linter/file-system-task-linter.mock.d.ts +81 -0
  49. package/dist/lib/file-system-task-linter/file-system-task-linter.mock.js +152 -0
  50. package/dist/lib/file-system-task-linter/file-system-task-linter.mock.js.map +1 -0
  51. package/dist/lib/file-system-task-linter/file-system-task-linter.test.d.ts +4 -0
  52. package/dist/lib/file-system-task-linter/file-system-task-linter.test.js +146 -0
  53. package/dist/lib/file-system-task-linter/file-system-task-linter.test.js.map +1 -0
  54. package/dist/lib/file-system-task-linter/file-system-task-linter.types.d.ts +52 -0
  55. package/dist/lib/file-system-task-linter/file-system-task-linter.types.js +6 -0
  56. package/dist/lib/file-system-task-linter/file-system-task-linter.types.js.map +1 -0
  57. package/dist/lib/file-system-task-linter/index.d.ts +6 -0
  58. package/dist/lib/file-system-task-linter/index.js +7 -0
  59. package/dist/lib/file-system-task-linter/index.js.map +1 -0
  60. package/dist/lib/help.d.ts +4 -0
  61. package/dist/lib/help.js +104 -0
  62. package/dist/lib/help.js.map +1 -0
  63. package/dist/lib/index.d.ts +6 -0
  64. package/dist/lib/index.js +7 -0
  65. package/dist/lib/index.js.map +1 -0
  66. package/dist/lib/provider-installer/index.d.ts +5 -0
  67. package/dist/lib/provider-installer/index.js +6 -0
  68. package/dist/lib/provider-installer/index.js.map +1 -0
  69. package/dist/lib/provider-installer/provider-installer.d.ts +28 -0
  70. package/dist/lib/provider-installer/provider-installer.js +86 -0
  71. package/dist/lib/provider-installer/provider-installer.js.map +1 -0
  72. package/dist/lib/provider-installer/provider-installer.types.d.ts +4 -0
  73. package/dist/lib/provider-installer/provider-installer.types.js +5 -0
  74. package/dist/lib/provider-installer/provider-installer.types.js.map +1 -0
  75. package/dist/lib/provider-installer.d.ts +27 -0
  76. package/dist/lib/provider-installer.js +86 -0
  77. package/dist/lib/provider-installer.js.map +1 -0
  78. package/dist/lib/provider-registry/index.d.ts +5 -0
  79. package/dist/lib/provider-registry/index.js +6 -0
  80. package/dist/lib/provider-registry/index.js.map +1 -0
  81. package/dist/lib/provider-registry/provider-registry.d.ts +9 -0
  82. package/dist/lib/provider-registry/provider-registry.js +111 -0
  83. package/dist/lib/provider-registry/provider-registry.js.map +1 -0
  84. package/dist/lib/provider-registry/provider-registry.types.d.ts +5 -0
  85. package/dist/lib/provider-registry/provider-registry.types.js +6 -0
  86. package/dist/lib/provider-registry/provider-registry.types.js.map +1 -0
  87. package/dist/lib/provider-registry.d.ts +26 -0
  88. package/dist/lib/provider-registry.js +111 -0
  89. package/dist/lib/provider-registry.js.map +1 -0
  90. package/dist/lib/task-linter/index.d.ts +5 -0
  91. package/dist/lib/task-linter/index.js +6 -0
  92. package/dist/lib/task-linter/index.js.map +1 -0
  93. package/dist/lib/task-linter/task-linter.d.ts +36 -0
  94. package/dist/lib/task-linter/task-linter.js +219 -0
  95. package/dist/lib/task-linter/task-linter.js.map +1 -0
  96. package/dist/lib/task-linter/task-linter.types.d.ts +52 -0
  97. package/dist/lib/task-linter/task-linter.types.js +6 -0
  98. package/dist/lib/task-linter/task-linter.types.js.map +1 -0
  99. package/dist/lib/task-linter.d.ts +29 -0
  100. package/dist/lib/task-linter.js +215 -0
  101. package/dist/lib/task-linter.js.map +1 -0
  102. package/dist/lib/task-linter.types.d.ts +38 -0
  103. package/dist/lib/task-linter.types.js +5 -0
  104. package/dist/lib/task-linter.types.js.map +1 -0
  105. package/dist/main.d.ts +14 -0
  106. package/dist/main.js +29 -0
  107. package/dist/main.js.map +1 -0
  108. package/dist/taskin.d.ts +33 -0
  109. package/dist/taskin.js +101 -0
  110. package/dist/taskin.js.map +1 -0
  111. package/package.json +81 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 OpenTask (https://opentask.com.br)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Taskin
2
+
3
+ > Task management system integrated with Git workflows
4
+
5
+ Taskin is a command-line tool that helps you manage tasks directly from your terminal, with seamless Git integration and **dynamic provider loading**.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/taskin.svg)](https://www.npmjs.com/package/taskin)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ## ✨ Features
11
+
12
+ - 🎯 **Multiple Task Providers** - File System, Redmine, Jira, GitHub Issues (and more!)
13
+ - 🔌 **Dynamic Provider Installation** - Automatically installs providers when needed
14
+ - 📦 **Lightweight CLI** - Only installs what you use
15
+ - 🔒 **Secure Configuration** - API keys protected in `.gitignore`
16
+ - 🎨 **Beautiful CLI** - Colorful, interactive, and user-friendly
17
+ - ⚡ **Fast & Efficient** - Built with performance in mind
18
+ - 🧪 **Well Tested** - Comprehensive test coverage
19
+
20
+ ## 🚀 Installation
21
+
22
+ \`\`\`bash
23
+ # Using npx (recommended - no installation needed!)
24
+ npx taskin init
25
+
26
+ # Or install globally
27
+ npm install -g taskin
28
+
29
+ # Or with pnpm
30
+ pnpm add -g taskin
31
+
32
+ # Or with yarn
33
+ yarn global add taskin
34
+ \`\`\`
35
+
36
+ > **Note:** This is a beta version. Please report any issues on [GitHub](https://github.com/opentask-app/taskin/issues).
37
+
38
+ ## Quick Start
39
+
40
+ 1. **Initialize Taskin in your project:**
41
+ \`\`\`bash
42
+ npx taskin init
43
+ \`\`\`
44
+
45
+ Select your preferred task provider:
46
+ - 📁 **File System** - Store tasks as Markdown files locally
47
+ - 🔴 **Redmine** - Sync with Redmine issues (coming soon)
48
+ - 🔵 **Jira** - Sync with Jira issues (coming soon)
49
+ - 🐙 **GitHub Issues** - Sync with GitHub (coming soon)
50
+
51
+ 2. **List all tasks:**
52
+ \`\`\`bash
53
+ taskin list
54
+ \`\`\`
55
+
56
+ 3. **Start working on a task:**
57
+ \`\`\`bash
58
+ taskin start task-001
59
+ \`\`\`
60
+
61
+ ## Commands
62
+
63
+ - \`taskin init\` - Initialize Taskin in your project with interactive setup
64
+ - \`taskin list\` - List all tasks
65
+ - \`taskin start <id>\` - Start working on a task
66
+ - \`taskin pause <id>\` - Pause work on a task
67
+ - \`taskin finish <id>\` - Complete a task
68
+ - \`taskin lint\` - Validate task files
69
+
70
+ ## 🏗️ Architecture
71
+
72
+ Taskin uses a **plugin-based architecture** with dynamic provider loading:
73
+
74
+ - Providers are loaded on-demand (only when selected)
75
+ - Automatic installation via npm/pnpm/yarn
76
+ - Easy to extend with custom providers
77
+
78
+ 📚 See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed technical documentation.
79
+
80
+ ## 📖 Examples
81
+
82
+ See [EXAMPLES.md](./EXAMPLES.md) for detailed usage examples and workflows.
83
+
84
+ ## 🔌 Available Providers
85
+
86
+ | Provider | Status | Package |
87
+ | ---------------- | -------------- | --------------------------------- |
88
+ | 📁 File System | ✅ Stable | \`@taskin/fs-task-provider\` |
89
+ | 🔴 Redmine | 🚧 Coming Soon | \`@taskin/redmine-task-provider\` |
90
+ | 🔵 Jira | 🚧 Coming Soon | \`@taskin/jira-task-provider\` |
91
+ | 🐙 GitHub Issues | 🚧 Coming Soon | \`@taskin/github-task-provider\` |
92
+
93
+ Want to create your own provider? See [ARCHITECTURE.md](./ARCHITECTURE.md#-criando-um-novo-provider).
94
+
95
+ ## 🤝 Contributing
96
+
97
+ Contributions are welcome! Please feel free to submit a Pull Request.
98
+
99
+ ## 📝 Requirements
100
+
101
+ - Node.js >= 20.0.0
102
+ - npm/pnpm/yarn
103
+
104
+ ## 🐛 Issues
105
+
106
+ Found a bug? Have a feature request? Please [open an issue](https://github.com/opentask-app/taskin/issues).
107
+
108
+ ## � Team
109
+
110
+ **OpenTask**
111
+ - Website: [opentask.com.br](https://opentask.com.br)
112
+ - Email: contato@opentask.com.br
113
+
114
+ **Contributors:**
115
+ - Sidarta Veloso ([@sidartaveloso](https://github.com/sidartaveloso))
116
+
117
+ ## 📄 License
118
+
119
+ MIT © [OpenTask](https://opentask.com.br)
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CLI commands types
3
+ * Re-exports from @taskin/types-ts for convenience
4
+ */
5
+ export type {
6
+ FinishTaskOptions,
7
+ ListTasksOptions,
8
+ PauseTaskOptions,
9
+ StartTaskOptions,
10
+ } from '@taskin/types-ts';
11
+ export interface LintOptions {
12
+ path?: string;
13
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * CLI commands types
3
+ * Re-exports from @taskin/types-ts for convenience
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=commands.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.types.js","sourceRoot":"","sources":["../../src/commands/commands.types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Command definition helper
3
+ * Provides a declarative way to define CLI commands
4
+ */
5
+ import type { DefineCommandFunction } from './define-command.types.js';
6
+ export declare const defineCommand: DefineCommandFunction;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Command definition helper
3
+ * Provides a declarative way to define CLI commands
4
+ */
5
+ import { error } from '../../lib/colors.js';
6
+ export const defineCommand = (config) => {
7
+ return (program) => {
8
+ const cmd = program.command(config.name).description(config.description);
9
+ if (config.alias) {
10
+ cmd.alias(config.alias);
11
+ }
12
+ config.options?.forEach((opt) => {
13
+ cmd.option(opt.flags, opt.description, opt.defaultValue);
14
+ });
15
+ cmd.action(async (...args) => {
16
+ try {
17
+ await config.handler(...args);
18
+ } catch (err) {
19
+ error(
20
+ `Failed to execute command: ${err instanceof Error ? err.message : String(err)}`,
21
+ );
22
+ process.exit(1);
23
+ }
24
+ });
25
+ };
26
+ };
27
+ //# sourceMappingURL=define-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-command.js","sourceRoot":"","sources":["../../../src/commands/define-command/define-command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,MAAM,CAAC,MAAM,aAAa,GAA0B,CAAC,MAAM,EAAE,EAAE;IAC7D,OAAO,CAAC,OAAgB,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAEzE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE;YAC3B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YAChC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CACH,8BAA8B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACjF,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Tests for defineCommand
3
+ */
4
+ export {};
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Tests for defineCommand
3
+ */
4
+ import { Command } from 'commander';
5
+ import { describe, expect, it, vi } from 'vitest';
6
+ import { defineCommand } from './define-command.js';
7
+ describe('defineCommand', () => {
8
+ it('should create a command registration function', () => {
9
+ const handler = vi.fn();
10
+ const commandReg = defineCommand({
11
+ name: 'test',
12
+ description: 'Test command',
13
+ handler,
14
+ });
15
+ expect(commandReg).toBeTypeOf('function');
16
+ });
17
+ it('should register a command with the program', () => {
18
+ const program = new Command();
19
+ const handler = vi.fn();
20
+ const commandReg = defineCommand({
21
+ name: 'test',
22
+ description: 'Test command',
23
+ handler,
24
+ });
25
+ commandReg(program);
26
+ const commands = program.commands;
27
+ expect(commands).toHaveLength(1);
28
+ expect(commands[0]?.name()).toBe('test');
29
+ });
30
+ it('should register command with alias', () => {
31
+ const program = new Command();
32
+ const handler = vi.fn();
33
+ const commandReg = defineCommand({
34
+ name: 'test',
35
+ description: 'Test command',
36
+ alias: 't',
37
+ handler,
38
+ });
39
+ commandReg(program);
40
+ const command = program.commands[0];
41
+ expect(command?.alias()).toBe('t');
42
+ });
43
+ it('should register command with options', () => {
44
+ const program = new Command();
45
+ const handler = vi.fn();
46
+ const commandReg = defineCommand({
47
+ name: 'test',
48
+ description: 'Test command',
49
+ options: [
50
+ {
51
+ flags: '-f, --force',
52
+ description: 'Force flag',
53
+ },
54
+ {
55
+ flags: '-n, --name <name>',
56
+ description: 'Name option',
57
+ defaultValue: 'default',
58
+ },
59
+ ],
60
+ handler,
61
+ });
62
+ commandReg(program);
63
+ const command = program.commands[0];
64
+ const options = command?.options;
65
+ expect(options).toHaveLength(2);
66
+ expect(options?.[0]?.flags).toBe('-f, --force');
67
+ expect(options?.[1]?.flags).toBe('-n, --name <name>');
68
+ });
69
+ it('should call handler when command is executed', async () => {
70
+ const program = new Command();
71
+ const handler = vi.fn().mockResolvedValue(undefined);
72
+ const commandReg = defineCommand({
73
+ name: 'test <arg>',
74
+ description: 'Test command',
75
+ handler,
76
+ });
77
+ commandReg(program);
78
+ // Simulate command execution
79
+ await program.parseAsync(['node', 'test', 'test', 'myarg']);
80
+ expect(handler).toHaveBeenCalledWith(
81
+ 'myarg',
82
+ expect.any(Object),
83
+ expect.any(Object),
84
+ );
85
+ });
86
+ it('should handle async handler errors', async () => {
87
+ const program = new Command();
88
+ const error = new Error('Test error');
89
+ const handler = vi.fn().mockRejectedValue(error);
90
+ const exitSpy = vi
91
+ .spyOn(process, 'exit')
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ .mockImplementation(() => {});
94
+ const commandReg = defineCommand({
95
+ name: 'test',
96
+ description: 'Test command',
97
+ handler,
98
+ });
99
+ commandReg(program);
100
+ await program.parseAsync(['node', 'test', 'test']);
101
+ expect(exitSpy).toHaveBeenCalledWith(1);
102
+ exitSpy.mockRestore();
103
+ });
104
+ it('should handle sync handler errors', async () => {
105
+ const program = new Command();
106
+ const error = new Error('Test error');
107
+ const handler = vi.fn().mockImplementation(() => {
108
+ throw error;
109
+ });
110
+ const exitSpy = vi
111
+ .spyOn(process, 'exit')
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ .mockImplementation(() => {});
114
+ const commandReg = defineCommand({
115
+ name: 'test',
116
+ description: 'Test command',
117
+ handler,
118
+ });
119
+ commandReg(program);
120
+ await program.parseAsync(['node', 'test', 'test']);
121
+ expect(exitSpy).toHaveBeenCalledWith(1);
122
+ exitSpy.mockRestore();
123
+ });
124
+ });
125
+ //# sourceMappingURL=define-command.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-command.test.js","sourceRoot":"","sources":["../../../src/commands/define-command/define-command.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Command definition types
3
+ */
4
+ import type { Command } from 'commander';
5
+ export interface CommandOption {
6
+ description: string;
7
+ flags: string;
8
+ defaultValue?: string | boolean | string[];
9
+ }
10
+ export interface CommandConfig {
11
+ description: string;
12
+ handler: (...args: any[]) => Promise<void> | void;
13
+ name: string;
14
+ alias?: string;
15
+ options?: CommandOption[];
16
+ }
17
+ /**
18
+ * Type for a command registration function
19
+ * Takes a Commander program and registers a command with it
20
+ */
21
+ export type CommandRegistration = (program: Command) => void;
22
+ /**
23
+ * Type for the defineCommand function.
24
+ *
25
+ * Define a CLI command with declarative configuration.
26
+ * This function takes a command configuration object and returns a function
27
+ * that registers the command with a Commander program.
28
+ *
29
+ * @param config - Command configuration object containing name, description, options, and handler
30
+ * @returns Function that registers the command with a Commander program
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * export const listCommand = defineCommand({
35
+ * name: 'list [filter]',
36
+ * description: '📊 List all tasks',
37
+ * alias: 'ls',
38
+ * options: [
39
+ * { flags: '-s, --status <status>', description: 'Filter by status' }
40
+ * ],
41
+ * handler: async (filter, options) => {
42
+ * // Implementation
43
+ * }
44
+ * });
45
+ * ```
46
+ */
47
+ export type DefineCommandFunction = (
48
+ config: CommandConfig,
49
+ ) => CommandRegistration;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Command definition types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=define-command.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-command.types.js","sourceRoot":"","sources":["../../../src/commands/define-command/define-command.types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Command definition exports
3
+ */
4
+ export * from './define-command.js';
5
+ export * from './define-command.types.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Command definition exports
3
+ */
4
+ export * from './define-command.js';
5
+ export * from './define-command.types.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/define-command/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Finish command - Complete a task
3
+ */
4
+ export declare const finishCommand: import('./define-command/define-command.types.js').CommandRegistration;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Finish command - Complete a task
3
+ */
4
+ import { FileSystemTaskProvider } from '@taskin/fs-task-provider';
5
+ import { TaskManager } from '@taskin/task-manager';
6
+ import path from 'path';
7
+ import { colors, error, info, printHeader, success } from '../lib/colors.js';
8
+ import { defineCommand } from './define-command/index.js';
9
+ export const finishCommand = defineCommand({
10
+ name: 'finish <task-id>',
11
+ description: '✅ Complete a task',
12
+ alias: 'done',
13
+ options: [
14
+ {
15
+ flags: '-s, --skip-update',
16
+ description: 'Skip updating task status',
17
+ },
18
+ ],
19
+ handler: async (taskId, options) => {
20
+ await finishTask(taskId, options);
21
+ },
22
+ });
23
+ async function finishTask(taskId, options) {
24
+ printHeader(`Finishing Task ${taskId}`, '✅');
25
+ // Normalize task ID
26
+ const normalizedId = taskId.replace(/^task-/, '').padStart(3, '0');
27
+ // Find TASKS directory
28
+ const tasksDir = path.join(process.cwd(), 'TASKS');
29
+ // Initialize task manager
30
+ const taskProvider = new FileSystemTaskProvider(tasksDir);
31
+ const taskManager = new TaskManager(taskProvider);
32
+ // Find task
33
+ const task = await taskProvider.findTask(normalizedId);
34
+ if (!task) {
35
+ error(`Task ${normalizedId} not found in TASKS/ directory`);
36
+ process.exit(1);
37
+ }
38
+ info(`Found task: ${task.title}`);
39
+ info(`Current status: ${task.status}`);
40
+ // Check if task is already done
41
+ if (task.status === 'done') {
42
+ error('Task is already done');
43
+ process.exit(1);
44
+ }
45
+ if (!options.skipUpdate) {
46
+ info('Marking task as done...');
47
+ const updatedTask = await taskManager.finishTask(task.id);
48
+ success(`Task ${updatedTask.id} completed successfully! 🎉`);
49
+ success(`Status changed to: ${updatedTask.status}`);
50
+ } else {
51
+ info('Skipping status update (--skip-update flag)');
52
+ }
53
+ console.log();
54
+ info('Suggested commit message:');
55
+ const commitType = task.type || 'feat';
56
+ console.log(
57
+ colors.highlight(` ${commitType}(task-${normalizedId}): ${task.title}`),
58
+ );
59
+ console.log();
60
+ info('Next steps:');
61
+ console.log(colors.secondary(' 1. Review your changes'));
62
+ console.log(colors.secondary(' 2. Commit: git add . && git commit'));
63
+ console.log(colors.secondary(' 3. Push: git push'));
64
+ console.log(colors.secondary(' 4. Create a Pull Request'));
65
+ console.log();
66
+ success('Great work! 🚀');
67
+ console.log();
68
+ }
69
+ //# sourceMappingURL=finish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finish.js","sourceRoot":"","sources":["../../src/commands/finish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * CLI commands exports
3
+ */
4
+ export * from './finish.js';
5
+ export * from './init.js';
6
+ export * from './lint.js';
7
+ export * from './list.js';
8
+ export * from './pause.js';
9
+ export * from './start.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CLI commands exports
3
+ */
4
+ export * from './finish.js';
5
+ export * from './init.js';
6
+ export * from './lint.js';
7
+ export * from './list.js';
8
+ export * from './pause.js';
9
+ export * from './start.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Init command - Initialize Taskin in the current project
3
+ */
4
+ export declare const initCommand: import('./define-command/define-command.types.js').CommandRegistration;