@krr2020/taskflow-core 0.1.0-beta.1 → 0.1.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -0
- package/bin/taskflow.js +15 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +352 -0
- package/dist/commands/base.d.ts +41 -0
- package/dist/commands/base.js +86 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.js +143 -0
- package/dist/commands/prd/create.d.ts +8 -0
- package/dist/commands/prd/create.js +268 -0
- package/dist/commands/prd/generate-arch.d.ts +7 -0
- package/dist/commands/prd/generate-arch.js +268 -0
- package/dist/commands/retro/add.d.ts +7 -0
- package/dist/commands/retro/add.js +174 -0
- package/dist/commands/retro/list.d.ts +8 -0
- package/dist/commands/retro/list.js +176 -0
- package/dist/commands/tasks/generate.d.ts +7 -0
- package/dist/commands/tasks/generate.js +373 -0
- package/dist/commands/upgrade.d.ts +20 -0
- package/dist/commands/upgrade.js +250 -0
- package/dist/commands/workflow/check.d.ts +11 -0
- package/dist/commands/workflow/check.js +339 -0
- package/dist/commands/workflow/commit.d.ts +7 -0
- package/dist/commands/workflow/commit.js +154 -0
- package/dist/commands/workflow/do.d.ts +15 -0
- package/dist/commands/workflow/do.js +207 -0
- package/dist/commands/workflow/next.d.ts +7 -0
- package/dist/commands/workflow/next.js +145 -0
- package/dist/commands/workflow/resume.d.ts +7 -0
- package/dist/commands/workflow/resume.js +169 -0
- package/dist/commands/workflow/skip.d.ts +7 -0
- package/dist/commands/workflow/skip.js +172 -0
- package/dist/commands/workflow/start.d.ts +7 -0
- package/dist/commands/workflow/start.js +142 -0
- package/dist/commands/workflow/status.d.ts +11 -0
- package/dist/commands/workflow/status.js +148 -0
- package/dist/config.d.ts +1 -1
- package/dist/git.js +2 -2
- package/dist/index.d.ts +31 -5
- package/dist/index.js +36 -5
- package/dist/lib/config-loader.d.ts +31 -0
- package/dist/lib/config-loader.js +86 -0
- package/dist/lib/config-paths.d.ts +72 -0
- package/dist/lib/config-paths.js +151 -0
- package/dist/lib/data-access.d.ts +42 -0
- package/dist/lib/data-access.js +433 -0
- package/dist/lib/errors.d.ts +74 -0
- package/dist/lib/errors.js +177 -0
- package/dist/lib/git.d.ts +33 -0
- package/dist/lib/git.js +339 -0
- package/dist/lib/output.d.ts +91 -0
- package/dist/lib/output.js +335 -0
- package/dist/lib/package-manager.d.ts +17 -0
- package/dist/lib/package-manager.js +53 -0
- package/dist/lib/retrospective.d.ts +25 -0
- package/dist/lib/retrospective.js +182 -0
- package/dist/lib/types.d.ts +365 -0
- package/dist/lib/types.js +199 -0
- package/dist/lib/validation.d.ts +32 -0
- package/dist/lib/validation.js +165 -0
- package/dist/schemas/config.d.ts +18 -100
- package/dist/schemas/config.js +13 -4
- package/dist/schemas/task.d.ts +37 -55
- package/dist/schemas/task.js +2 -2
- package/dist/state-machine.d.ts +4 -4
- package/dist/state-machine.js +26 -8
- package/package.json +43 -34
- package/templates/prd/prd-generator.md +100 -0
- package/templates/project/architecture-rules.md +160 -0
- package/templates/project/coding-standards.md +137 -0
- package/templates/project/taskflow.config.example.json +23 -0
- package/templates/protocols/ai-protocol.md +100 -0
- package/templates/protocols/task-executor.md +75 -0
- package/templates/protocols/task-generator.md +102 -0
- package/templates/retrospective/retrospective.md +11 -0
- package/templates/skills/backend.md +64 -0
- package/templates/skills/devops.md +64 -0
- package/templates/skills/docs.md +62 -0
- package/templates/skills/frontend.md +64 -0
- package/templates/skills/fullstack.md +62 -0
- package/templates/skills/mobile.md +67 -0
- package/src/config.ts +0 -39
- package/src/git.ts +0 -76
- package/src/index.ts +0 -5
- package/src/schemas/config.ts +0 -31
- package/src/schemas/task.ts +0 -33
- package/src/state-machine.ts +0 -99
- package/tsconfig.json +0 -21
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# @krr2020/taskflow-core
|
|
2
|
+
|
|
3
|
+
Core task management framework for AI-assisted development workflows. This package provides the foundational commands, state management, and configuration handling used by the Taskflow MCP Server and CLI.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @krr2020/taskflow-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 🏗️ Architecture
|
|
12
|
+
|
|
13
|
+
The core package provides a complete task management system with:
|
|
14
|
+
|
|
15
|
+
### Commands Layer
|
|
16
|
+
13 command classes that handle all workflow operations:
|
|
17
|
+
|
|
18
|
+
**Initialization & Setup**
|
|
19
|
+
- `InitCommand` - Initialize Taskflow in a project
|
|
20
|
+
|
|
21
|
+
**Status & Navigation**
|
|
22
|
+
- `StatusCommand` - View project, feature, or story status
|
|
23
|
+
- `NextCommand` - Find next available task
|
|
24
|
+
|
|
25
|
+
**PRD & Task Generation**
|
|
26
|
+
- `PrdCreateCommand` - Create PRD template
|
|
27
|
+
- `PrdGenerateArchCommand` - Generate coding standards and architecture rules from PRD
|
|
28
|
+
- `TasksGenerateCommand` - Generate task breakdown from PRD
|
|
29
|
+
|
|
30
|
+
**Task Workflow**
|
|
31
|
+
- `StartCommand` - Start a task (SETUP phase)
|
|
32
|
+
- `CheckCommand` - Validate and advance task status
|
|
33
|
+
- `CommitCommand` - Commit changes and complete task
|
|
34
|
+
- `ResumeCommand` - Resume blocked/on-hold tasks
|
|
35
|
+
- `SkipCommand` - Mark task as blocked
|
|
36
|
+
|
|
37
|
+
**Retrospective System**
|
|
38
|
+
- `RetroAddCommand` - Add error pattern to retrospective
|
|
39
|
+
- `RetroListCommand` - List retrospective entries
|
|
40
|
+
|
|
41
|
+
### Library Modules
|
|
42
|
+
|
|
43
|
+
**Core Types & Validation**
|
|
44
|
+
- `types.ts` - TypeScript types and Zod schemas for all data structures
|
|
45
|
+
- `errors.ts` - Custom error classes (FileNotFoundError, InvalidFileFormatError, etc.)
|
|
46
|
+
|
|
47
|
+
**Data & Configuration**
|
|
48
|
+
- `config-loader.ts` - Load and validate taskflow.config.json
|
|
49
|
+
- `config-paths.ts` - Path helpers and configuration constants
|
|
50
|
+
- `data-access.ts` - JSON file operations for tasks, features, and project index
|
|
51
|
+
|
|
52
|
+
**Workflow Support**
|
|
53
|
+
- `git.ts` - Git operations (branch switching, commit, push)
|
|
54
|
+
- `validation.ts` - Run configured validation commands
|
|
55
|
+
- `retrospective.ts` - Error pattern tracking and matching
|
|
56
|
+
- `output.ts` - Terminal output formatting utilities
|
|
57
|
+
|
|
58
|
+
### CLI Interface
|
|
59
|
+
|
|
60
|
+
The package includes a CLI via `bin/taskflow.js` using Commander.js:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Initialize project
|
|
64
|
+
taskflow init [project-name]
|
|
65
|
+
|
|
66
|
+
# Status and navigation
|
|
67
|
+
taskflow status [id]
|
|
68
|
+
taskflow next
|
|
69
|
+
|
|
70
|
+
# PRD workflow
|
|
71
|
+
taskflow prd create <feature-name>
|
|
72
|
+
taskflow prd generate-arch <prd-file>
|
|
73
|
+
taskflow tasks generate <prd-file>
|
|
74
|
+
|
|
75
|
+
# Task workflow
|
|
76
|
+
taskflow start <task-id>
|
|
77
|
+
taskflow check
|
|
78
|
+
taskflow commit <message>
|
|
79
|
+
taskflow resume [status]
|
|
80
|
+
taskflow skip <reason>
|
|
81
|
+
|
|
82
|
+
# Retrospective
|
|
83
|
+
taskflow retro add
|
|
84
|
+
taskflow retro list [category]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 📊 Task Status Flow
|
|
88
|
+
|
|
89
|
+
Tasks progress through a state machine:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
not-started → setup → implementing → verifying → validating → committing → completed
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Other states: `blocked`, `on-hold`
|
|
96
|
+
|
|
97
|
+
## 🔧 Programmatic Usage
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import {
|
|
101
|
+
StartCommand,
|
|
102
|
+
CheckCommand,
|
|
103
|
+
CommitCommand,
|
|
104
|
+
type CommandContext
|
|
105
|
+
} from '@krr2020/taskflow-core';
|
|
106
|
+
|
|
107
|
+
const context: CommandContext = {
|
|
108
|
+
projectRoot: process.cwd()
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Start a task
|
|
112
|
+
const startCmd = new StartCommand(context);
|
|
113
|
+
const result = await startCmd.execute('1.1.0');
|
|
114
|
+
|
|
115
|
+
console.log(result.output); // Human-readable output
|
|
116
|
+
console.log(result.nextSteps); // Next action guidance
|
|
117
|
+
console.log(result.aiGuidance); // AI-specific instructions
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 📁 Data Structure
|
|
121
|
+
|
|
122
|
+
### Project Hierarchy
|
|
123
|
+
```
|
|
124
|
+
project-index.json # Top-level project and features index
|
|
125
|
+
tasks/
|
|
126
|
+
└── F1/ # Feature directory
|
|
127
|
+
└── F1.json # Feature file with stories
|
|
128
|
+
└── S1.1/ # Story directory
|
|
129
|
+
└── T1.1.0.json # Individual task files
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Configuration
|
|
133
|
+
|
|
134
|
+
`taskflow.config.json`:
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"project": {
|
|
138
|
+
"name": "my-project",
|
|
139
|
+
"root": "."
|
|
140
|
+
},
|
|
141
|
+
"branching": {
|
|
142
|
+
"strategy": "per-story",
|
|
143
|
+
"base": "main",
|
|
144
|
+
"prefix": "story/"
|
|
145
|
+
},
|
|
146
|
+
"validation": {
|
|
147
|
+
"commands": {
|
|
148
|
+
"format": "echo 'running format'",
|
|
149
|
+
"test": "echo 'running tests'",
|
|
150
|
+
"build": "echo 'building project'"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 🧪 Testing
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Run tests
|
|
160
|
+
pnpm test
|
|
161
|
+
|
|
162
|
+
# Watch mode
|
|
163
|
+
pnpm test --watch
|
|
164
|
+
|
|
165
|
+
# Coverage
|
|
166
|
+
pnpm test --coverage
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## 📚 Integration
|
|
170
|
+
|
|
171
|
+
Most users should use this package via:
|
|
172
|
+
- **[@krr2020/taskflow-mcp-server](https://www.npmjs.com/package/@krr2020/taskflow-mcp-server)** - MCP Server for Claude Desktop
|
|
173
|
+
- **CLI** - Direct command-line usage via `npx @krr2020/taskflow-core`
|
|
174
|
+
|
|
175
|
+
See the main [Taskflow documentation](../../README.md) for complete usage examples.
|
|
176
|
+
|
|
177
|
+
## 📄 License
|
|
178
|
+
|
|
179
|
+
MIT
|
package/bin/taskflow.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TaskFlow CLI Executable
|
|
5
|
+
*
|
|
6
|
+
* This is the entry point for the taskflow command-line tool.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { runCLI } from "../dist/cli/index.js";
|
|
10
|
+
|
|
11
|
+
// Run the CLI
|
|
12
|
+
runCLI().catch((error) => {
|
|
13
|
+
console.error("Fatal error:", error);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
});
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TaskFlow CLI - Command-line interface
|
|
3
|
+
*/
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
// Import commands
|
|
7
|
+
import { InitCommand } from "../commands/init.js";
|
|
8
|
+
import { PrdCreateCommand } from "../commands/prd/create.js";
|
|
9
|
+
import { PrdGenerateArchCommand } from "../commands/prd/generate-arch.js";
|
|
10
|
+
import { RetroAddCommand } from "../commands/retro/add.js";
|
|
11
|
+
import { RetroListCommand } from "../commands/retro/list.js";
|
|
12
|
+
import { TasksGenerateCommand } from "../commands/tasks/generate.js";
|
|
13
|
+
import { UpgradeCommand } from "../commands/upgrade.js";
|
|
14
|
+
import { CheckCommand } from "../commands/workflow/check.js";
|
|
15
|
+
import { CommitCommand } from "../commands/workflow/commit.js";
|
|
16
|
+
import { DoCommand } from "../commands/workflow/do.js";
|
|
17
|
+
import { NextCommand } from "../commands/workflow/next.js";
|
|
18
|
+
import { ResumeCommand } from "../commands/workflow/resume.js";
|
|
19
|
+
import { SkipCommand } from "../commands/workflow/skip.js";
|
|
20
|
+
import { StartCommand } from "../commands/workflow/start.js";
|
|
21
|
+
import { StatusCommand } from "../commands/workflow/status.js";
|
|
22
|
+
// Import errors
|
|
23
|
+
import { formatError, TaskflowError } from "../lib/errors.js";
|
|
24
|
+
import { consoleOutput, formatFailure, formatSuccess, printLine, } from "../lib/output.js";
|
|
25
|
+
export async function runCLI() {
|
|
26
|
+
const program = new Command();
|
|
27
|
+
program
|
|
28
|
+
.name("taskflow")
|
|
29
|
+
.description("AI-first task management and workflow system")
|
|
30
|
+
.version("1.0.0");
|
|
31
|
+
// Create command context
|
|
32
|
+
const context = {
|
|
33
|
+
projectRoot: process.cwd(),
|
|
34
|
+
};
|
|
35
|
+
// ========================================
|
|
36
|
+
// INIT COMMAND
|
|
37
|
+
// ========================================
|
|
38
|
+
program
|
|
39
|
+
.command("init")
|
|
40
|
+
.description("Initialize taskflow in the current project")
|
|
41
|
+
.argument("[project-name]", "Project name (defaults to directory name)")
|
|
42
|
+
.action(async (projectName) => {
|
|
43
|
+
try {
|
|
44
|
+
const cmd = new InitCommand(context);
|
|
45
|
+
const result = await cmd.execute(projectName);
|
|
46
|
+
console.log(formatSuccess(result));
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
handleError(error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// ========================================
|
|
54
|
+
// UPGRADE COMMAND
|
|
55
|
+
// ========================================
|
|
56
|
+
program
|
|
57
|
+
.command("upgrade")
|
|
58
|
+
.description("Upgrade .taskflow reference files to latest version")
|
|
59
|
+
.option("--force", "Force upgrade even if already up to date")
|
|
60
|
+
.option("--auto", "Skip prompts for user-generated files")
|
|
61
|
+
.option("--diff", "Show diff summary without upgrading")
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
try {
|
|
64
|
+
const cmd = new UpgradeCommand(context);
|
|
65
|
+
const result = await cmd.execute(options);
|
|
66
|
+
console.log(formatSuccess(result));
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
handleError(error);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
// ========================================
|
|
74
|
+
// STATUS COMMAND
|
|
75
|
+
// ========================================
|
|
76
|
+
program
|
|
77
|
+
.command("status")
|
|
78
|
+
.description("Show project, feature, or story status")
|
|
79
|
+
.argument("[id]", "Feature ID (N) or Story ID (N.M)")
|
|
80
|
+
.action(async (id) => {
|
|
81
|
+
try {
|
|
82
|
+
const cmd = new StatusCommand(context);
|
|
83
|
+
const result = await cmd.execute(id);
|
|
84
|
+
console.log(formatSuccess(result));
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
handleError(error);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// ========================================
|
|
92
|
+
// NEXT COMMAND
|
|
93
|
+
// ========================================
|
|
94
|
+
program
|
|
95
|
+
.command("next")
|
|
96
|
+
.description("Find the next available task")
|
|
97
|
+
.action(async () => {
|
|
98
|
+
try {
|
|
99
|
+
const cmd = new NextCommand(context);
|
|
100
|
+
const result = await cmd.execute();
|
|
101
|
+
console.log(formatSuccess(result));
|
|
102
|
+
process.exit(0);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
handleError(error);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// ========================================
|
|
109
|
+
// START COMMAND
|
|
110
|
+
// ========================================
|
|
111
|
+
program
|
|
112
|
+
.command("start")
|
|
113
|
+
.description("Start working on a task")
|
|
114
|
+
.argument("<task-id>", "Task ID (e.g., 1.1.0)")
|
|
115
|
+
.action(async (taskId) => {
|
|
116
|
+
try {
|
|
117
|
+
const cmd = new StartCommand(context);
|
|
118
|
+
const result = await cmd.execute(taskId);
|
|
119
|
+
console.log(formatSuccess(result));
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
handleError(error);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
// ========================================
|
|
127
|
+
// CHECK COMMAND
|
|
128
|
+
// ========================================
|
|
129
|
+
program
|
|
130
|
+
.command("check")
|
|
131
|
+
.description("Validate current task and advance to next status")
|
|
132
|
+
.action(async () => {
|
|
133
|
+
try {
|
|
134
|
+
const cmd = new CheckCommand(context);
|
|
135
|
+
const result = await cmd.execute();
|
|
136
|
+
console.log(formatSuccess(result));
|
|
137
|
+
process.exit(0);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
handleError(error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// ========================================
|
|
144
|
+
// COMMIT COMMAND
|
|
145
|
+
// ========================================
|
|
146
|
+
program
|
|
147
|
+
.command("commit")
|
|
148
|
+
.description("Commit changes and complete the task")
|
|
149
|
+
.argument("<message>", 'Bullet points describing changes (e.g., "- Added X\\n- Fixed Y")')
|
|
150
|
+
.action(async (message) => {
|
|
151
|
+
try {
|
|
152
|
+
const cmd = new CommitCommand(context);
|
|
153
|
+
const result = await cmd.execute(message);
|
|
154
|
+
console.log(formatSuccess(result));
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
handleError(error);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
// ========================================
|
|
162
|
+
// DO COMMAND
|
|
163
|
+
// ========================================
|
|
164
|
+
program
|
|
165
|
+
.command("do")
|
|
166
|
+
.description("Execute the next step of the current task")
|
|
167
|
+
.action(async () => {
|
|
168
|
+
try {
|
|
169
|
+
const cmd = new DoCommand(context);
|
|
170
|
+
const result = await cmd.execute();
|
|
171
|
+
if (!result.success) {
|
|
172
|
+
consoleOutput(formatFailure(result));
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// Don't modify output for 'do' command as it has custom formatting
|
|
177
|
+
printLine(result.output);
|
|
178
|
+
if (result.nextSteps) {
|
|
179
|
+
printLine("\nNEXT STEPS:");
|
|
180
|
+
printLine(result.nextSteps);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
process.exit(0);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
handleError(error);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// ========================================
|
|
190
|
+
// RESUME COMMAND
|
|
191
|
+
// ========================================
|
|
192
|
+
program
|
|
193
|
+
.command("resume")
|
|
194
|
+
.description("Resume a blocked or on-hold task")
|
|
195
|
+
.argument("[status]", "Status to resume to (setup, implementing, verifying, validating)")
|
|
196
|
+
.action(async (status) => {
|
|
197
|
+
try {
|
|
198
|
+
const cmd = new ResumeCommand(context);
|
|
199
|
+
const result = await cmd.execute(status);
|
|
200
|
+
console.log(formatSuccess(result));
|
|
201
|
+
process.exit(0);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
handleError(error);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
// ========================================
|
|
208
|
+
// SKIP COMMAND
|
|
209
|
+
// ========================================
|
|
210
|
+
program
|
|
211
|
+
.command("skip")
|
|
212
|
+
.description("Mark current task as blocked")
|
|
213
|
+
.argument("<reason>", "Reason for blocking the task")
|
|
214
|
+
.action(async (reason) => {
|
|
215
|
+
try {
|
|
216
|
+
const cmd = new SkipCommand(context);
|
|
217
|
+
const result = await cmd.execute(reason);
|
|
218
|
+
console.log(formatSuccess(result));
|
|
219
|
+
process.exit(0);
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
handleError(error);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
// ========================================
|
|
226
|
+
// PRD COMMANDS
|
|
227
|
+
// ========================================
|
|
228
|
+
const prdCommand = program
|
|
229
|
+
.command("prd")
|
|
230
|
+
.description("PRD (Product Requirements Document) commands");
|
|
231
|
+
prdCommand
|
|
232
|
+
.command("create")
|
|
233
|
+
.description("Create a new PRD")
|
|
234
|
+
.argument("<feature-name>", "Name of the feature")
|
|
235
|
+
.action(async (featureName) => {
|
|
236
|
+
try {
|
|
237
|
+
const cmd = new PrdCreateCommand(context);
|
|
238
|
+
const result = await cmd.execute(featureName);
|
|
239
|
+
console.log(formatSuccess(result));
|
|
240
|
+
process.exit(0);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
handleError(error);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
prdCommand
|
|
247
|
+
.command("generate-arch")
|
|
248
|
+
.description("Generate CODING-STANDARDS.md and ARCHITECTURE-RULES.md from PRD")
|
|
249
|
+
.argument("<prd-file>", "PRD filename")
|
|
250
|
+
.action(async (prdFile) => {
|
|
251
|
+
try {
|
|
252
|
+
const cmd = new PrdGenerateArchCommand(context);
|
|
253
|
+
const result = await cmd.execute(prdFile);
|
|
254
|
+
console.log(formatSuccess(result));
|
|
255
|
+
process.exit(0);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
handleError(error);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
// ========================================
|
|
262
|
+
// TASKS COMMANDS
|
|
263
|
+
// ========================================
|
|
264
|
+
const tasksCommand = program
|
|
265
|
+
.command("tasks")
|
|
266
|
+
.description("Task generation commands");
|
|
267
|
+
tasksCommand
|
|
268
|
+
.command("generate")
|
|
269
|
+
.description("Generate task breakdown from PRD")
|
|
270
|
+
.argument("<prd-file>", "PRD filename")
|
|
271
|
+
.action(async (prdFile) => {
|
|
272
|
+
try {
|
|
273
|
+
const cmd = new TasksGenerateCommand(context);
|
|
274
|
+
const result = await cmd.execute(prdFile);
|
|
275
|
+
console.log(formatSuccess(result));
|
|
276
|
+
process.exit(0);
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
handleError(error);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
// ========================================
|
|
283
|
+
// RETRO COMMANDS
|
|
284
|
+
// ========================================
|
|
285
|
+
const retroCommand = program
|
|
286
|
+
.command("retro")
|
|
287
|
+
.description("Retrospective commands");
|
|
288
|
+
retroCommand
|
|
289
|
+
.command("add")
|
|
290
|
+
.description("Add a retrospective entry for a known error pattern")
|
|
291
|
+
.argument("<category>", "Error category")
|
|
292
|
+
.argument("<pattern>", "Error pattern to match")
|
|
293
|
+
.argument("<solution>", "Solution to the error")
|
|
294
|
+
.argument("[criticality]", "Criticality level (low, medium, high) - defaults to medium")
|
|
295
|
+
.action(async (category, pattern, solution, criticality) => {
|
|
296
|
+
try {
|
|
297
|
+
const cmd = new RetroAddCommand(context);
|
|
298
|
+
const result = await cmd.execute(category, pattern, solution, criticality || "medium");
|
|
299
|
+
console.log(formatSuccess(result));
|
|
300
|
+
process.exit(0);
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
handleError(error);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
retroCommand
|
|
307
|
+
.command("list")
|
|
308
|
+
.description("List all retrospective entries")
|
|
309
|
+
.argument("[category]", "Filter by category")
|
|
310
|
+
.action(async (category) => {
|
|
311
|
+
try {
|
|
312
|
+
const cmd = new RetroListCommand(context);
|
|
313
|
+
const result = await cmd.execute(category);
|
|
314
|
+
console.log(formatSuccess(result));
|
|
315
|
+
process.exit(0);
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
handleError(error);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
// Parse command line arguments
|
|
322
|
+
await program.parseAsync(process.argv);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Handle errors with proper formatting
|
|
326
|
+
*/
|
|
327
|
+
function handleError(error) {
|
|
328
|
+
// Check if it's a failed CommandResult
|
|
329
|
+
if (typeof error === "object" &&
|
|
330
|
+
error !== null &&
|
|
331
|
+
"success" in error &&
|
|
332
|
+
error.success === false) {
|
|
333
|
+
console.error(formatFailure(error));
|
|
334
|
+
process.exit(1);
|
|
335
|
+
}
|
|
336
|
+
if (error instanceof TaskflowError) {
|
|
337
|
+
// Custom TaskFlow errors
|
|
338
|
+
console.error(formatError(error));
|
|
339
|
+
process.exit(1);
|
|
340
|
+
}
|
|
341
|
+
if (error instanceof Error) {
|
|
342
|
+
// Generic errors
|
|
343
|
+
console.error(formatError(error));
|
|
344
|
+
console.error("\nStack trace:");
|
|
345
|
+
console.error(error.stack);
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
348
|
+
// Unknown error type
|
|
349
|
+
console.error("An unknown error occurred:");
|
|
350
|
+
console.error(error);
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base command infrastructure for AI-first command design
|
|
3
|
+
* Every command returns structured guidance for AI agents
|
|
4
|
+
*/
|
|
5
|
+
export interface CommandContext {
|
|
6
|
+
projectRoot: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CommandResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
output: string;
|
|
11
|
+
nextSteps: string;
|
|
12
|
+
aiGuidance?: string;
|
|
13
|
+
contextFiles?: string[];
|
|
14
|
+
warnings?: string[];
|
|
15
|
+
errors?: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare abstract class BaseCommand {
|
|
18
|
+
protected context: CommandContext;
|
|
19
|
+
constructor(context: CommandContext);
|
|
20
|
+
abstract execute(...args: unknown[]): Promise<CommandResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Format command result for terminal output
|
|
23
|
+
* Returns formatted string with sections: OUTPUT, CONTEXT FILES, NEXT STEPS, AI GUIDANCE, WARNINGS
|
|
24
|
+
*/
|
|
25
|
+
protected formatOutput(result: CommandResult): string;
|
|
26
|
+
/**
|
|
27
|
+
* Create a successful command result
|
|
28
|
+
*/
|
|
29
|
+
protected success(output: string, nextSteps: string, options?: {
|
|
30
|
+
aiGuidance?: string;
|
|
31
|
+
contextFiles?: string[];
|
|
32
|
+
warnings?: string[];
|
|
33
|
+
}): CommandResult;
|
|
34
|
+
/**
|
|
35
|
+
* Create a failed command result
|
|
36
|
+
*/
|
|
37
|
+
protected failure(output: string, errors: string[], nextSteps: string, options?: {
|
|
38
|
+
aiGuidance?: string;
|
|
39
|
+
warnings?: string[];
|
|
40
|
+
}): CommandResult;
|
|
41
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base command infrastructure for AI-first command design
|
|
3
|
+
* Every command returns structured guidance for AI agents
|
|
4
|
+
*/
|
|
5
|
+
export class BaseCommand {
|
|
6
|
+
context;
|
|
7
|
+
constructor(context) {
|
|
8
|
+
this.context = context;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Format command result for terminal output
|
|
12
|
+
* Returns formatted string with sections: OUTPUT, CONTEXT FILES, NEXT STEPS, AI GUIDANCE, WARNINGS
|
|
13
|
+
*/
|
|
14
|
+
formatOutput(result) {
|
|
15
|
+
const sections = [];
|
|
16
|
+
const separator = "─".repeat(60);
|
|
17
|
+
// OUTPUT section
|
|
18
|
+
sections.push("OUTPUT:");
|
|
19
|
+
sections.push(separator);
|
|
20
|
+
sections.push(result.output);
|
|
21
|
+
sections.push("");
|
|
22
|
+
// CONTEXT FILES section (if any)
|
|
23
|
+
if (result.contextFiles && result.contextFiles.length > 0) {
|
|
24
|
+
sections.push("CONTEXT FILES (Read these before proceeding):");
|
|
25
|
+
sections.push(separator);
|
|
26
|
+
for (const [index, file] of result.contextFiles.entries()) {
|
|
27
|
+
sections.push(`${index + 1}. ${file}`);
|
|
28
|
+
}
|
|
29
|
+
sections.push("");
|
|
30
|
+
}
|
|
31
|
+
// NEXT STEPS section
|
|
32
|
+
sections.push("NEXT STEPS:");
|
|
33
|
+
sections.push(separator);
|
|
34
|
+
sections.push(result.nextSteps);
|
|
35
|
+
sections.push("");
|
|
36
|
+
// AI GUIDANCE section (if any)
|
|
37
|
+
if (result.aiGuidance) {
|
|
38
|
+
sections.push("AI GUIDANCE:");
|
|
39
|
+
sections.push(separator);
|
|
40
|
+
sections.push(result.aiGuidance);
|
|
41
|
+
sections.push("");
|
|
42
|
+
}
|
|
43
|
+
// WARNINGS section (if any)
|
|
44
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
45
|
+
sections.push("WARNINGS:");
|
|
46
|
+
sections.push(separator);
|
|
47
|
+
for (const warning of result.warnings) {
|
|
48
|
+
sections.push(`⚠ ${warning}`);
|
|
49
|
+
}
|
|
50
|
+
sections.push("");
|
|
51
|
+
}
|
|
52
|
+
// ERRORS section (if any)
|
|
53
|
+
if (result.errors && result.errors.length > 0) {
|
|
54
|
+
sections.push("ERRORS:");
|
|
55
|
+
sections.push(separator);
|
|
56
|
+
for (const error of result.errors) {
|
|
57
|
+
sections.push(`✗ ${error}`);
|
|
58
|
+
}
|
|
59
|
+
sections.push("");
|
|
60
|
+
}
|
|
61
|
+
return sections.join("\n");
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create a successful command result
|
|
65
|
+
*/
|
|
66
|
+
success(output, nextSteps, options) {
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
output,
|
|
70
|
+
nextSteps,
|
|
71
|
+
...options,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create a failed command result
|
|
76
|
+
*/
|
|
77
|
+
failure(output, errors, nextSteps, options) {
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
output,
|
|
81
|
+
nextSteps,
|
|
82
|
+
errors,
|
|
83
|
+
...options,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|