@krr2020/taskflow-core 0.1.0-beta.3 → 0.1.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/index.js +42 -4
- package/dist/commands/base.d.ts +41 -0
- package/dist/commands/base.js +141 -0
- package/dist/commands/configure.d.ts +29 -0
- package/dist/commands/configure.js +187 -0
- package/dist/commands/init.js +21 -7
- package/dist/commands/prd/create.d.ts +1 -1
- package/dist/commands/prd/create.js +29 -11
- package/dist/commands/prd/generate-arch.d.ts +1 -1
- package/dist/commands/prd/generate-arch.js +6 -5
- package/dist/commands/retro/list.js +6 -5
- package/dist/commands/tasks/generate.d.ts +1 -1
- package/dist/commands/tasks/generate.js +83 -56
- package/dist/commands/upgrade.js +49 -16
- package/dist/commands/workflow/check.d.ts +17 -0
- package/dist/commands/workflow/check.js +482 -35
- package/dist/commands/workflow/commit.js +117 -60
- package/dist/commands/workflow/do.d.ts +1 -0
- package/dist/commands/workflow/do.js +206 -13
- package/dist/commands/workflow/next.js +4 -4
- package/dist/commands/workflow/resume.js +9 -6
- package/dist/commands/workflow/start.js +11 -11
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/lib/config-paths.d.ts +15 -15
- package/dist/lib/config-paths.js +20 -15
- package/dist/lib/file-validator.d.ts +119 -0
- package/dist/lib/file-validator.js +291 -0
- package/dist/lib/git.js +4 -2
- package/dist/lib/log-parser.d.ts +91 -0
- package/dist/lib/log-parser.js +178 -0
- package/dist/lib/retrospective.d.ts +27 -0
- package/dist/lib/retrospective.js +111 -1
- package/dist/lib/types.d.ts +19 -6
- package/dist/lib/types.js +20 -1
- package/dist/lib/validation.d.ts +0 -3
- package/dist/lib/validation.js +1 -15
- package/dist/llm/base.d.ts +52 -0
- package/dist/llm/base.js +35 -0
- package/dist/llm/factory.d.ts +39 -0
- package/dist/llm/factory.js +102 -0
- package/dist/llm/index.d.ts +7 -0
- package/dist/llm/index.js +7 -0
- package/dist/llm/model-selector.d.ts +71 -0
- package/dist/llm/model-selector.js +139 -0
- package/dist/llm/providers/anthropic.d.ts +31 -0
- package/dist/llm/providers/anthropic.js +116 -0
- package/dist/llm/providers/index.d.ts +6 -0
- package/dist/llm/providers/index.js +6 -0
- package/dist/llm/providers/ollama.d.ts +28 -0
- package/dist/llm/providers/ollama.js +91 -0
- package/dist/llm/providers/openai-compatible.d.ts +30 -0
- package/dist/llm/providers/openai-compatible.js +93 -0
- package/dist/schemas/config.d.ts +82 -0
- package/dist/schemas/config.js +35 -0
- package/dist/schemas/task.d.ts +2 -2
- package/dist/state-machine.d.ts +12 -0
- package/dist/state-machine.js +2 -2
- package/package.json +1 -1
- package/dist/lib/package-manager.d.ts +0 -17
- package/dist/lib/package-manager.js +0 -53
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log Parser
|
|
3
|
+
* Extracts errors and diagnostic information from build/test logs
|
|
4
|
+
*/
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
/**
|
|
7
|
+
* Log Parser class
|
|
8
|
+
* Parses build/test logs to extract errors and diagnostics
|
|
9
|
+
*/
|
|
10
|
+
export class LogParser {
|
|
11
|
+
patterns = [
|
|
12
|
+
{
|
|
13
|
+
name: "TypeScript error",
|
|
14
|
+
regex: /([^:\n]+?):(\d+):(\d+) - error (TS\d+): (.+)/g,
|
|
15
|
+
severity: "error",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: "TypeScript warning",
|
|
19
|
+
regex: /([^:\n]+?):(\d+):(\d+) - warning (TS\d+): (.+)/g,
|
|
20
|
+
severity: "warning",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "ESLint error",
|
|
24
|
+
regex: /([^:\n]+?):(\d+):(\d+) error (.+)/g,
|
|
25
|
+
severity: "error",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "ESLint warning",
|
|
29
|
+
regex: /([^:\n]+?):(\d+):(\d+) warning (.+)/g,
|
|
30
|
+
severity: "warning",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "Test failure",
|
|
34
|
+
regex: /FAIL\s+([^\s]+?)(?:\n|$)/g,
|
|
35
|
+
severity: "error",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "Build error",
|
|
39
|
+
regex: /error\s+(.+?)(?:\n|$)/g,
|
|
40
|
+
severity: "error",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "Compilation error",
|
|
44
|
+
regex: /([^:\n]+?):(\d+): error: (.+)/g,
|
|
45
|
+
severity: "error",
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Parse log string
|
|
50
|
+
*/
|
|
51
|
+
parse(logContent) {
|
|
52
|
+
const errors = [];
|
|
53
|
+
for (const pattern of this.patterns) {
|
|
54
|
+
let match = pattern.regex.exec(logContent);
|
|
55
|
+
while (match !== null) {
|
|
56
|
+
const error = this.createErrorFromMatch(match, pattern);
|
|
57
|
+
if (error) {
|
|
58
|
+
errors.push(error);
|
|
59
|
+
}
|
|
60
|
+
match = pattern.regex.exec(logContent);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const errorCount = errors.filter((e) => e.severity === "error").length;
|
|
64
|
+
const warningCount = errors.filter((e) => e.severity === "warning").length;
|
|
65
|
+
return {
|
|
66
|
+
errors,
|
|
67
|
+
errorCount,
|
|
68
|
+
warningCount,
|
|
69
|
+
success: errorCount === 0,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Parse log file
|
|
74
|
+
*/
|
|
75
|
+
async parseFile(filePath) {
|
|
76
|
+
const content = await readFile(filePath, "utf-8");
|
|
77
|
+
return this.parse(content);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create error from regex match
|
|
81
|
+
*/
|
|
82
|
+
createErrorFromMatch(match, pattern) {
|
|
83
|
+
const raw = match[0];
|
|
84
|
+
// Try to extract file, line, column, message, code
|
|
85
|
+
let file = "";
|
|
86
|
+
let line = 0;
|
|
87
|
+
let column = 0;
|
|
88
|
+
let message = raw;
|
|
89
|
+
let code = "";
|
|
90
|
+
switch (pattern.name) {
|
|
91
|
+
case "TypeScript error":
|
|
92
|
+
case "TypeScript warning":
|
|
93
|
+
file = match[1] || "";
|
|
94
|
+
line = Number.parseInt(match[2] || "0", 10);
|
|
95
|
+
column = Number.parseInt(match[3] || "0", 10);
|
|
96
|
+
code = match[4]?.split(":")[0] || "";
|
|
97
|
+
message = match[4] || raw;
|
|
98
|
+
break;
|
|
99
|
+
case "ESLint error":
|
|
100
|
+
case "ESLint warning":
|
|
101
|
+
file = match[1] || "";
|
|
102
|
+
line = Number.parseInt(match[2] || "0", 10);
|
|
103
|
+
column = Number.parseInt(match[3] || "0", 10);
|
|
104
|
+
message = match[4] || raw;
|
|
105
|
+
break;
|
|
106
|
+
case "Test failure":
|
|
107
|
+
file = match[1] || "";
|
|
108
|
+
message = `Test failed: ${match[1]}`;
|
|
109
|
+
break;
|
|
110
|
+
case "Build error":
|
|
111
|
+
message = match[1] || raw;
|
|
112
|
+
break;
|
|
113
|
+
case "Compilation error":
|
|
114
|
+
file = match[1] || "";
|
|
115
|
+
line = Number.parseInt(match[2] || "0", 10);
|
|
116
|
+
message = match[3] || raw;
|
|
117
|
+
break;
|
|
118
|
+
default:
|
|
119
|
+
message = raw;
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
file,
|
|
123
|
+
line,
|
|
124
|
+
column,
|
|
125
|
+
message,
|
|
126
|
+
code,
|
|
127
|
+
severity: pattern.severity,
|
|
128
|
+
raw,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Group errors by file
|
|
133
|
+
*/
|
|
134
|
+
groupErrorsByFile(errors) {
|
|
135
|
+
const grouped = new Map();
|
|
136
|
+
for (const error of errors) {
|
|
137
|
+
if (error.file) {
|
|
138
|
+
const existing = grouped.get(error.file) || [];
|
|
139
|
+
existing.push(error);
|
|
140
|
+
grouped.set(error.file, existing);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return grouped;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Filter errors by severity
|
|
147
|
+
*/
|
|
148
|
+
filterBySeverity(errors, severity) {
|
|
149
|
+
return errors.filter((e) => e.severity === severity);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Filter errors by file
|
|
153
|
+
*/
|
|
154
|
+
filterByFile(errors, filePattern) {
|
|
155
|
+
const regex = new RegExp(filePattern);
|
|
156
|
+
return errors.filter((e) => regex.test(e.file));
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Format error for display
|
|
160
|
+
*/
|
|
161
|
+
formatError(error) {
|
|
162
|
+
const parts = [];
|
|
163
|
+
if (error.file) {
|
|
164
|
+
parts.push(error.file);
|
|
165
|
+
if (error.line) {
|
|
166
|
+
parts.push(`:${error.line}`);
|
|
167
|
+
if (error.column) {
|
|
168
|
+
parts.push(`:${error.column}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (error.code) {
|
|
173
|
+
parts.push(`[${error.code}]`);
|
|
174
|
+
}
|
|
175
|
+
parts.push(`- ${error.message}`);
|
|
176
|
+
return parts.join(" ");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Retrospective module for error pattern management
|
|
3
3
|
*/
|
|
4
|
+
import type { ParsedError } from "./log-parser.js";
|
|
4
5
|
import type { Criticality, ErrorCategory, RetrospectiveItem } from "./types.js";
|
|
6
|
+
export interface NewPattern {
|
|
7
|
+
category: ErrorCategory | string;
|
|
8
|
+
pattern: string;
|
|
9
|
+
solution: string;
|
|
10
|
+
criticality: Criticality | string;
|
|
11
|
+
errorCode?: string;
|
|
12
|
+
affectedFiles: string[];
|
|
13
|
+
}
|
|
5
14
|
export declare function getRetrospectiveFilePath(refDir: string): string;
|
|
6
15
|
export declare function loadRetrospective(refDir: string): RetrospectiveItem[];
|
|
7
16
|
export declare function parseRetrospectiveContent(content: string): RetrospectiveItem[];
|
|
@@ -23,3 +32,21 @@ export declare const VALID_CRITICALITIES: Criticality[];
|
|
|
23
32
|
export declare function isValidCategory(category: string): category is ErrorCategory;
|
|
24
33
|
export declare function isValidCriticality(criticality: string): criticality is Criticality;
|
|
25
34
|
export declare function printRetroAddUsage(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Read retrospective file content
|
|
37
|
+
*/
|
|
38
|
+
export declare function readRetrospectiveBeforeWork(refDir: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Extract NEW error patterns from parsed errors
|
|
41
|
+
* Compares against existing retrospective to avoid duplicates
|
|
42
|
+
*/
|
|
43
|
+
export declare function extractNewPatterns(errors: ParsedError[], refDir: string): NewPattern[];
|
|
44
|
+
/**
|
|
45
|
+
* Append new patterns to retrospective file
|
|
46
|
+
* Uses existing addRetrospectiveEntry for each pattern
|
|
47
|
+
*/
|
|
48
|
+
export declare function appendNewPatternsToRetrospective(refDir: string, patterns: NewPattern[]): number[];
|
|
49
|
+
/**
|
|
50
|
+
* Format a new pattern for display (before adding to retrospective)
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatNewPatternForDisplay(pattern: NewPattern): string;
|
|
@@ -124,7 +124,7 @@ export function incrementErrorCount(refDir, id) {
|
|
|
124
124
|
export function addRetrospectiveEntry(refDir, category, pattern, solution, criticality) {
|
|
125
125
|
const retroFile = getRetrospectiveFilePath(refDir);
|
|
126
126
|
if (!fs.existsSync(retroFile)) {
|
|
127
|
-
throw new Error("
|
|
127
|
+
throw new Error("retrospective.md not found");
|
|
128
128
|
}
|
|
129
129
|
const items = loadRetrospective(refDir);
|
|
130
130
|
const nextId = items.length > 0
|
|
@@ -180,3 +180,113 @@ export function printRetroAddUsage() {
|
|
|
180
180
|
console.log(`\n${colors.highlight("Example:")}`);
|
|
181
181
|
console.log(`${colors.muted('taskflow retro add --category "Type Error" --pattern "Cannot find module" --solution "Check import path exists" --criticality "High"')}`);
|
|
182
182
|
}
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// Auto-Update Functions
|
|
185
|
+
// ============================================================================
|
|
186
|
+
/**
|
|
187
|
+
* Read retrospective file content
|
|
188
|
+
*/
|
|
189
|
+
export function readRetrospectiveBeforeWork(refDir) {
|
|
190
|
+
const retroFile = getRetrospectiveFilePath(refDir);
|
|
191
|
+
if (!fs.existsSync(retroFile)) {
|
|
192
|
+
return "";
|
|
193
|
+
}
|
|
194
|
+
return fs.readFileSync(retroFile, "utf-8");
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Extract NEW error patterns from parsed errors
|
|
198
|
+
* Compares against existing retrospective to avoid duplicates
|
|
199
|
+
*/
|
|
200
|
+
export function extractNewPatterns(errors, refDir) {
|
|
201
|
+
const existingItems = loadRetrospective(refDir);
|
|
202
|
+
const newPatterns = [];
|
|
203
|
+
// Group errors by error code and message pattern
|
|
204
|
+
const errorGroups = new Map();
|
|
205
|
+
for (const error of errors) {
|
|
206
|
+
const key = error.code || error.message.substring(0, 50);
|
|
207
|
+
if (!errorGroups.has(key)) {
|
|
208
|
+
errorGroups.set(key, []);
|
|
209
|
+
}
|
|
210
|
+
errorGroups.get(key)?.push(error);
|
|
211
|
+
}
|
|
212
|
+
// For each group, check if it's a new pattern
|
|
213
|
+
for (const [, groupErrors] of errorGroups) {
|
|
214
|
+
const firstError = groupErrors[0];
|
|
215
|
+
if (!firstError)
|
|
216
|
+
continue;
|
|
217
|
+
// Create pattern from error message
|
|
218
|
+
const pattern = firstError.code || firstError.message;
|
|
219
|
+
// Check if this pattern already exists in retrospective
|
|
220
|
+
const alreadyExists = existingItems.some((item) => {
|
|
221
|
+
try {
|
|
222
|
+
const itemPattern = item.pattern.replace(/\\\|/g, "|");
|
|
223
|
+
const regex = new RegExp(itemPattern, "i");
|
|
224
|
+
return regex.test(pattern);
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return item.pattern.toLowerCase().includes(pattern.toLowerCase());
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
if (!alreadyExists) {
|
|
231
|
+
// Determine category from error
|
|
232
|
+
let category = "Runtime";
|
|
233
|
+
if (firstError.code?.startsWith("TS")) {
|
|
234
|
+
category = "Type Error";
|
|
235
|
+
}
|
|
236
|
+
else if (firstError.message.includes("eslint") ||
|
|
237
|
+
firstError.message.includes("lint")) {
|
|
238
|
+
category = "Lint";
|
|
239
|
+
}
|
|
240
|
+
else if (firstError.message.includes("test")) {
|
|
241
|
+
category = "Test";
|
|
242
|
+
}
|
|
243
|
+
// Determine criticality based on severity
|
|
244
|
+
let criticality = "Medium";
|
|
245
|
+
if (firstError.severity === "error") {
|
|
246
|
+
criticality = "High";
|
|
247
|
+
}
|
|
248
|
+
else if (firstError.severity === "warning") {
|
|
249
|
+
criticality = "Low";
|
|
250
|
+
}
|
|
251
|
+
newPatterns.push({
|
|
252
|
+
category,
|
|
253
|
+
pattern,
|
|
254
|
+
solution: "Review error message and fix the underlying issue",
|
|
255
|
+
criticality,
|
|
256
|
+
errorCode: firstError.code,
|
|
257
|
+
affectedFiles: groupErrors.map((e) => e.file).filter(Boolean),
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return newPatterns;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Append new patterns to retrospective file
|
|
265
|
+
* Uses existing addRetrospectiveEntry for each pattern
|
|
266
|
+
*/
|
|
267
|
+
export function appendNewPatternsToRetrospective(refDir, patterns) {
|
|
268
|
+
const addedIds = [];
|
|
269
|
+
for (const pattern of patterns) {
|
|
270
|
+
const id = addRetrospectiveEntry(refDir, pattern.category, pattern.pattern, pattern.solution, pattern.criticality);
|
|
271
|
+
addedIds.push(id);
|
|
272
|
+
}
|
|
273
|
+
return addedIds;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Format a new pattern for display (before adding to retrospective)
|
|
277
|
+
*/
|
|
278
|
+
export function formatNewPatternForDisplay(pattern) {
|
|
279
|
+
const lines = [];
|
|
280
|
+
lines.push(`${colors.highlight("New Error Pattern Detected:")}`);
|
|
281
|
+
lines.push(` Category: ${colors.muted(pattern.category)}`);
|
|
282
|
+
lines.push(` Pattern: ${colors.warning(pattern.pattern)}`);
|
|
283
|
+
if (pattern.errorCode) {
|
|
284
|
+
lines.push(` Code: ${colors.error(pattern.errorCode)}`);
|
|
285
|
+
}
|
|
286
|
+
lines.push(` Suggested Solution: ${colors.success(pattern.solution)}`);
|
|
287
|
+
lines.push(` Criticality: ${colors.state(pattern.criticality)}`);
|
|
288
|
+
if (pattern.affectedFiles.length > 0) {
|
|
289
|
+
lines.push(` Affected Files: ${colors.muted(pattern.affectedFiles.slice(0, 3).join(", "))}${pattern.affectedFiles.length > 3 ? "..." : ""}`);
|
|
290
|
+
}
|
|
291
|
+
return lines.join("\n");
|
|
292
|
+
}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { z } from "zod";
|
|
|
10
10
|
export declare const TaskStatusSchema: z.ZodEnum<{
|
|
11
11
|
"not-started": "not-started";
|
|
12
12
|
setup: "setup";
|
|
13
|
+
planning: "planning";
|
|
13
14
|
implementing: "implementing";
|
|
14
15
|
verifying: "verifying";
|
|
15
16
|
validating: "validating";
|
|
@@ -20,7 +21,7 @@ export declare const TaskStatusSchema: z.ZodEnum<{
|
|
|
20
21
|
}>;
|
|
21
22
|
export type TaskStatus = z.infer<typeof TaskStatusSchema>;
|
|
22
23
|
/** Status values that indicate a task is actively being worked on */
|
|
23
|
-
export declare const ACTIVE_STATUSES: readonly ["setup", "implementing", "verifying", "validating", "committing"];
|
|
24
|
+
export declare const ACTIVE_STATUSES: readonly ["setup", "planning", "implementing", "verifying", "validating", "committing"];
|
|
24
25
|
export type ActiveStatus = (typeof ACTIVE_STATUSES)[number];
|
|
25
26
|
/** Check if a status is an active (in-progress) status */
|
|
26
27
|
export declare function isActiveStatus(status: string): status is ActiveStatus;
|
|
@@ -84,6 +85,7 @@ export declare const TaskFileContentSchema: z.ZodObject<{
|
|
|
84
85
|
status: z.ZodEnum<{
|
|
85
86
|
"not-started": "not-started";
|
|
86
87
|
setup: "setup";
|
|
88
|
+
planning: "planning";
|
|
87
89
|
implementing: "implementing";
|
|
88
90
|
verifying: "verifying";
|
|
89
91
|
validating: "validating";
|
|
@@ -113,6 +115,7 @@ export declare const TaskFileContentSchema: z.ZodObject<{
|
|
|
113
115
|
previousStatus: z.ZodOptional<z.ZodEnum<{
|
|
114
116
|
"not-started": "not-started";
|
|
115
117
|
setup: "setup";
|
|
118
|
+
planning: "planning";
|
|
116
119
|
implementing: "implementing";
|
|
117
120
|
verifying: "verifying";
|
|
118
121
|
validating: "validating";
|
|
@@ -149,6 +152,7 @@ export declare const TaskRefSchema: z.ZodObject<{
|
|
|
149
152
|
status: z.ZodEnum<{
|
|
150
153
|
"not-started": "not-started";
|
|
151
154
|
setup: "setup";
|
|
155
|
+
planning: "planning";
|
|
152
156
|
implementing: "implementing";
|
|
153
157
|
verifying: "verifying";
|
|
154
158
|
validating: "validating";
|
|
@@ -176,6 +180,7 @@ export declare const StorySchema: z.ZodObject<{
|
|
|
176
180
|
status: z.ZodEnum<{
|
|
177
181
|
"not-started": "not-started";
|
|
178
182
|
setup: "setup";
|
|
183
|
+
planning: "planning";
|
|
179
184
|
implementing: "implementing";
|
|
180
185
|
verifying: "verifying";
|
|
181
186
|
validating: "validating";
|
|
@@ -215,6 +220,7 @@ export declare const FeatureSchema: z.ZodObject<{
|
|
|
215
220
|
status: z.ZodEnum<{
|
|
216
221
|
"not-started": "not-started";
|
|
217
222
|
setup: "setup";
|
|
223
|
+
planning: "planning";
|
|
218
224
|
implementing: "implementing";
|
|
219
225
|
verifying: "verifying";
|
|
220
226
|
validating: "validating";
|
|
@@ -274,6 +280,18 @@ export declare const TaskflowConfigSchema: z.ZodObject<{
|
|
|
274
280
|
validation: z.ZodOptional<z.ZodObject<{
|
|
275
281
|
commands: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
276
282
|
}, z.core.$strip>>;
|
|
283
|
+
ai: z.ZodOptional<z.ZodObject<{
|
|
284
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
285
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
286
|
+
models: z.ZodOptional<z.ZodObject<{
|
|
287
|
+
planning: z.ZodOptional<z.ZodString>;
|
|
288
|
+
execution: z.ZodOptional<z.ZodString>;
|
|
289
|
+
analysis: z.ZodOptional<z.ZodString>;
|
|
290
|
+
default: z.ZodOptional<z.ZodString>;
|
|
291
|
+
}, z.core.$strip>>;
|
|
292
|
+
autoContinueTask: z.ZodDefault<z.ZodBoolean>;
|
|
293
|
+
clearContextOnComplete: z.ZodDefault<z.ZodBoolean>;
|
|
294
|
+
}, z.core.$strip>>;
|
|
277
295
|
}, z.core.$strip>;
|
|
278
296
|
export type TaskflowConfig = z.infer<typeof TaskflowConfigSchema>;
|
|
279
297
|
export interface TasksProgress {
|
|
@@ -319,11 +337,6 @@ export interface RetrospectiveItem {
|
|
|
319
337
|
count: number;
|
|
320
338
|
criticality: string;
|
|
321
339
|
}
|
|
322
|
-
export interface CommandResult {
|
|
323
|
-
success: boolean;
|
|
324
|
-
message?: string;
|
|
325
|
-
data?: unknown;
|
|
326
|
-
}
|
|
327
340
|
export interface ValidationResult {
|
|
328
341
|
command: string;
|
|
329
342
|
label: string;
|
package/dist/lib/types.js
CHANGED
|
@@ -13,6 +13,7 @@ import { z } from "zod";
|
|
|
13
13
|
export const TaskStatusSchema = z.enum([
|
|
14
14
|
"not-started",
|
|
15
15
|
"setup",
|
|
16
|
+
"planning",
|
|
16
17
|
"implementing",
|
|
17
18
|
"verifying",
|
|
18
19
|
"validating",
|
|
@@ -24,6 +25,7 @@ export const TaskStatusSchema = z.enum([
|
|
|
24
25
|
/** Status values that indicate a task is actively being worked on */
|
|
25
26
|
export const ACTIVE_STATUSES = [
|
|
26
27
|
"setup",
|
|
28
|
+
"planning",
|
|
27
29
|
"implementing",
|
|
28
30
|
"verifying",
|
|
29
31
|
"validating",
|
|
@@ -35,7 +37,8 @@ export function isActiveStatus(status) {
|
|
|
35
37
|
}
|
|
36
38
|
/** Status transitions for workflow progression */
|
|
37
39
|
export const STATUS_TRANSITIONS = {
|
|
38
|
-
setup: "
|
|
40
|
+
setup: "planning",
|
|
41
|
+
planning: "implementing",
|
|
39
42
|
implementing: "verifying",
|
|
40
43
|
verifying: "validating",
|
|
41
44
|
validating: "committing",
|
|
@@ -149,6 +152,22 @@ export const TaskflowConfigSchema = z.object({
|
|
|
149
152
|
commands: z.record(z.string(), z.string()).optional(),
|
|
150
153
|
})
|
|
151
154
|
.optional(),
|
|
155
|
+
ai: z
|
|
156
|
+
.object({
|
|
157
|
+
enabled: z.boolean().default(false),
|
|
158
|
+
provider: z.string().optional(),
|
|
159
|
+
models: z
|
|
160
|
+
.object({
|
|
161
|
+
planning: z.string().optional(),
|
|
162
|
+
execution: z.string().optional(),
|
|
163
|
+
analysis: z.string().optional(),
|
|
164
|
+
default: z.string().optional(),
|
|
165
|
+
})
|
|
166
|
+
.optional(),
|
|
167
|
+
autoContinueTask: z.boolean().default(false),
|
|
168
|
+
clearContextOnComplete: z.boolean().default(true),
|
|
169
|
+
})
|
|
170
|
+
.optional(),
|
|
152
171
|
});
|
|
153
172
|
// ============================================================================
|
|
154
173
|
// Retrospective Types
|
package/dist/lib/validation.d.ts
CHANGED
|
@@ -27,6 +27,3 @@ export interface ValidationSummary {
|
|
|
27
27
|
}
|
|
28
28
|
export declare function runValidations(logsDir: string, taskId: string, commands?: Record<string, string>): ValidationSummary;
|
|
29
29
|
export declare function assertValidationPassed(summary: ValidationSummary, logsDir: string): void;
|
|
30
|
-
export declare function quickTypeCheck(): boolean;
|
|
31
|
-
export declare function quickLintCheck(cwd?: string): boolean;
|
|
32
|
-
export declare function quickAllChecks(cwd?: string): boolean;
|
package/dist/lib/validation.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import { execaSync } from "execa";
|
|
6
|
-
import { getLogFilePath, MAX_OUTPUT_BUFFER
|
|
6
|
+
import { getLogFilePath, MAX_OUTPUT_BUFFER } from "./config-paths.js";
|
|
7
7
|
import { saveLogFile } from "./data-access.js";
|
|
8
8
|
import { ValidationFailedError } from "./errors.js";
|
|
9
9
|
import { colors, extractErrorSummary } from "./output.js";
|
|
@@ -149,17 +149,3 @@ export function assertValidationPassed(summary, logsDir) {
|
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
// ============================================================================
|
|
152
|
-
// Quick Checks (without logging)
|
|
153
|
-
// ============================================================================
|
|
154
|
-
export function quickTypeCheck() {
|
|
155
|
-
// Without configuration, we cannot perform quick checks
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
export function quickLintCheck(cwd = process.cwd()) {
|
|
159
|
-
// Without configuration, we cannot perform quick checks
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
export function quickAllChecks(cwd = process.cwd()) {
|
|
163
|
-
// Without configuration, we cannot perform quick checks
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base LLM Provider interface
|
|
3
|
+
* All LLM providers must implement this interface
|
|
4
|
+
*/
|
|
5
|
+
export interface LLMMessage {
|
|
6
|
+
role: "system" | "user" | "assistant";
|
|
7
|
+
content: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LLMGenerationOptions {
|
|
10
|
+
maxTokens?: number;
|
|
11
|
+
temperature?: number;
|
|
12
|
+
topP?: number;
|
|
13
|
+
topK?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface LLMGenerationResult {
|
|
16
|
+
content: string;
|
|
17
|
+
model: string;
|
|
18
|
+
tokensUsed?: number;
|
|
19
|
+
finishReason?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare enum LLMProviderType {
|
|
22
|
+
OpenAICompatible = "openai-compatible",
|
|
23
|
+
Anthropic = "anthropic",
|
|
24
|
+
Ollama = "ollama"
|
|
25
|
+
}
|
|
26
|
+
export declare enum Phase {
|
|
27
|
+
Planning = "planning",
|
|
28
|
+
Execution = "execution",
|
|
29
|
+
Analysis = "analysis"
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* LLM Provider interface
|
|
33
|
+
* Defines the contract for all LLM provider implementations
|
|
34
|
+
*/
|
|
35
|
+
export declare abstract class LLMProvider {
|
|
36
|
+
readonly type: LLMProviderType;
|
|
37
|
+
readonly model: string;
|
|
38
|
+
constructor(type: LLMProviderType, model: string);
|
|
39
|
+
/**
|
|
40
|
+
* Generate text from the LLM
|
|
41
|
+
*/
|
|
42
|
+
abstract generate(messages: LLMMessage[], options?: LLMGenerationOptions): Promise<LLMGenerationResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if the provider is properly configured
|
|
45
|
+
*/
|
|
46
|
+
abstract isConfigured(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Get the model name for the specified phase
|
|
49
|
+
* Override if provider has phase-specific models
|
|
50
|
+
*/
|
|
51
|
+
getModelForPhase(_phase: Phase): string;
|
|
52
|
+
}
|
package/dist/llm/base.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base LLM Provider interface
|
|
3
|
+
* All LLM providers must implement this interface
|
|
4
|
+
*/
|
|
5
|
+
export var LLMProviderType;
|
|
6
|
+
(function (LLMProviderType) {
|
|
7
|
+
LLMProviderType["OpenAICompatible"] = "openai-compatible";
|
|
8
|
+
LLMProviderType["Anthropic"] = "anthropic";
|
|
9
|
+
LLMProviderType["Ollama"] = "ollama";
|
|
10
|
+
})(LLMProviderType || (LLMProviderType = {}));
|
|
11
|
+
export var Phase;
|
|
12
|
+
(function (Phase) {
|
|
13
|
+
Phase["Planning"] = "planning";
|
|
14
|
+
Phase["Execution"] = "execution";
|
|
15
|
+
Phase["Analysis"] = "analysis";
|
|
16
|
+
})(Phase || (Phase = {}));
|
|
17
|
+
/**
|
|
18
|
+
* LLM Provider interface
|
|
19
|
+
* Defines the contract for all LLM provider implementations
|
|
20
|
+
*/
|
|
21
|
+
export class LLMProvider {
|
|
22
|
+
type;
|
|
23
|
+
model;
|
|
24
|
+
constructor(type, model) {
|
|
25
|
+
this.type = type;
|
|
26
|
+
this.model = model;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the model name for the specified phase
|
|
30
|
+
* Override if provider has phase-specific models
|
|
31
|
+
*/
|
|
32
|
+
getModelForPhase(_phase) {
|
|
33
|
+
return this.model;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Provider Factory
|
|
3
|
+
* Factory for creating LLM providers and model selectors
|
|
4
|
+
*/
|
|
5
|
+
import { type LLMGenerationOptions, type LLMGenerationResult, type LLMMessage, type LLMProvider, LLMProviderType } from "./base.js";
|
|
6
|
+
import { type AIConfig, ModelSelector } from "./model-selector.js";
|
|
7
|
+
export type { LLMMessage, LLMGenerationOptions, LLMGenerationResult };
|
|
8
|
+
export { LLMProvider, LLMProviderType } from "./base.js";
|
|
9
|
+
export { type AIConfig, ModelSelector } from "./model-selector.js";
|
|
10
|
+
export { AnthropicProvider, OllamaProvider, OpenAICompatibleProvider, } from "./providers/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Provider factory namespace
|
|
13
|
+
* Functions for creating LLM providers and model selectors
|
|
14
|
+
*/
|
|
15
|
+
export declare const ProviderFactory: {
|
|
16
|
+
/**
|
|
17
|
+
* Create a model selector from configuration
|
|
18
|
+
*/
|
|
19
|
+
createSelector(config: AIConfig): ModelSelector;
|
|
20
|
+
/**
|
|
21
|
+
* Create a single provider (backward compatible)
|
|
22
|
+
*/
|
|
23
|
+
createProvider(type: LLMProviderType, model: string, apiKey?: string, baseUrl?: string): LLMProvider;
|
|
24
|
+
/**
|
|
25
|
+
* Test if a provider is configured and working
|
|
26
|
+
*/
|
|
27
|
+
testProvider(provider: LLMProvider): Promise<{
|
|
28
|
+
success: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Get available providers
|
|
33
|
+
*/
|
|
34
|
+
getAvailableProviders(): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Get default model for provider
|
|
37
|
+
*/
|
|
38
|
+
getDefaultModel(providerType: LLMProviderType): string;
|
|
39
|
+
};
|