@tmddev/tmd 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +424 -0
  3. package/bin/tmd.js +3 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.js +92 -0
  6. package/dist/commands/act.d.ts +3 -0
  7. package/dist/commands/act.js +210 -0
  8. package/dist/commands/check.d.ts +3 -0
  9. package/dist/commands/check.js +183 -0
  10. package/dist/commands/do.d.ts +3 -0
  11. package/dist/commands/do.js +310 -0
  12. package/dist/commands/list.d.ts +3 -0
  13. package/dist/commands/list.js +56 -0
  14. package/dist/commands/plan.d.ts +3 -0
  15. package/dist/commands/plan.js +89 -0
  16. package/dist/commands/show.d.ts +2 -0
  17. package/dist/commands/show.js +69 -0
  18. package/dist/commands/skills.d.ts +3 -0
  19. package/dist/commands/skills.js +243 -0
  20. package/dist/types.d.ts +79 -0
  21. package/dist/types.js +5 -0
  22. package/dist/utils/act-processing.d.ts +64 -0
  23. package/dist/utils/act-processing.js +222 -0
  24. package/dist/utils/analysis.d.ts +34 -0
  25. package/dist/utils/analysis.js +159 -0
  26. package/dist/utils/comparison.d.ts +34 -0
  27. package/dist/utils/comparison.js +217 -0
  28. package/dist/utils/language-validator.d.ts +11 -0
  29. package/dist/utils/language-validator.js +39 -0
  30. package/dist/utils/openspec.d.ts +5 -0
  31. package/dist/utils/openspec.js +91 -0
  32. package/dist/utils/paths.d.ts +10 -0
  33. package/dist/utils/paths.js +33 -0
  34. package/dist/utils/skills.d.ts +3 -0
  35. package/dist/utils/skills.js +248 -0
  36. package/dist/utils/skillssh.d.ts +12 -0
  37. package/dist/utils/skillssh.js +135 -0
  38. package/dist/utils/standardization.d.ts +26 -0
  39. package/dist/utils/standardization.js +106 -0
  40. package/dist/utils/task-chain.d.ts +35 -0
  41. package/dist/utils/task-chain.js +146 -0
  42. package/dist/utils/task-id.d.ts +5 -0
  43. package/dist/utils/task-id.js +15 -0
  44. package/dist/utils/task-status.d.ts +6 -0
  45. package/dist/utils/task-status.js +61 -0
  46. package/dist/utils/task-validator.d.ts +42 -0
  47. package/dist/utils/task-validator.js +178 -0
  48. package/dist/utils/tasks.d.ts +27 -0
  49. package/dist/utils/tasks.js +125 -0
  50. package/dist/utils/templates.d.ts +12 -0
  51. package/dist/utils/templates.js +143 -0
  52. package/package.json +84 -0
  53. package/scripts/postinstall.js +92 -0
@@ -0,0 +1,248 @@
1
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { getSkillsDir, getSkillDir } from './paths.js';
4
+ import { generateTaskId } from './task-id.js';
5
+ import yaml from 'js-yaml';
6
+ import chalk from 'chalk';
7
+ export function createSkill(description, taskId) {
8
+ const skillsDir = getSkillsDir();
9
+ ensureDir(skillsDir);
10
+ // Generate skill name from description
11
+ const skillName = generateTaskId(description).replace(/^\d+-/, '');
12
+ const skillDir = getSkillDir(skillName);
13
+ if (existsSync(skillDir)) {
14
+ console.log(chalk.yellow(` Skill already exists: ${skillName}`));
15
+ return skillName;
16
+ }
17
+ mkdirSync(skillDir, { recursive: true });
18
+ // Create skill.md with user story template
19
+ const skillContent = `# Skill: ${description}
20
+
21
+ ## User Story
22
+ As a [role], I want to [action], so as to [benefit]
23
+
24
+ ## Description
25
+ ${description}
26
+
27
+ ## Prerequisites
28
+ <!-- List prerequisites -->
29
+
30
+ ## Skill Steps
31
+ <!-- Define executable steps -->
32
+ 1.
33
+ 2.
34
+ 3.
35
+
36
+ ## Expected Outcomes
37
+ <!-- Define expected results -->
38
+
39
+ ## Validation Criteria
40
+ <!-- Define how to validate success -->
41
+ `;
42
+ writeFileSync(join(skillDir, 'skill.md'), skillContent);
43
+ // Create steps.yaml
44
+ const stepsContent = {
45
+ steps: [
46
+ {
47
+ type: 'example',
48
+ description: 'Example step',
49
+ // Add step configuration
50
+ }
51
+ ]
52
+ };
53
+ writeFileSync(join(skillDir, 'steps.yaml'), yaml.dump(stepsContent));
54
+ // Create config.yaml
55
+ const configContent = {
56
+ // Configuration for skill execution
57
+ };
58
+ writeFileSync(join(skillDir, 'config.yaml'), yaml.dump(configContent));
59
+ // Create metadata.yaml
60
+ const metadataContent = {
61
+ name: skillName,
62
+ version: '1.0.0',
63
+ description: description,
64
+ tags: [],
65
+ createdFrom: taskId,
66
+ interface: {
67
+ input: [],
68
+ output: {}
69
+ }
70
+ };
71
+ writeFileSync(join(skillDir, 'metadata.yaml'), yaml.dump(metadataContent));
72
+ return skillName;
73
+ }
74
+ function executeStep(step, stepIndex) {
75
+ return new Promise((resolve) => {
76
+ const startTime = Date.now();
77
+ try {
78
+ // Basic step execution based on type
79
+ switch (step.type) {
80
+ case 'database':
81
+ console.log(chalk.yellow(` Database operation: ${step.operation ?? 'query'}`));
82
+ // TODO: Implement database operations
83
+ break;
84
+ case 'file':
85
+ console.log(chalk.yellow(` File operation: ${step.operation ?? 'read'}`));
86
+ // TODO: Implement file operations
87
+ break;
88
+ case 'script':
89
+ console.log(chalk.yellow(` Script execution: ${step.script ?? 'unknown'}`));
90
+ // TODO: Implement script execution
91
+ break;
92
+ case 'api':
93
+ console.log(chalk.yellow(` API call: ${step.endpoint ?? 'unknown'}`));
94
+ // TODO: Implement API calls
95
+ break;
96
+ case 'image':
97
+ console.log(chalk.yellow(` Image processing: ${step.operation ?? 'process'}`));
98
+ // TODO: Implement image processing
99
+ break;
100
+ default:
101
+ console.log(chalk.yellow(` Unknown step type: ${step.type ?? 'undefined'}`));
102
+ }
103
+ const duration = Date.now() - startTime;
104
+ resolve({
105
+ stepIndex,
106
+ success: true,
107
+ duration
108
+ });
109
+ }
110
+ catch (error) {
111
+ const duration = Date.now() - startTime;
112
+ const errorMessage = error instanceof Error ? error.message : String(error);
113
+ resolve({
114
+ stepIndex,
115
+ success: false,
116
+ error: errorMessage,
117
+ duration
118
+ });
119
+ }
120
+ });
121
+ }
122
+ async function executeStepsConcurrently(steps, maxConcurrency = Infinity) {
123
+ const results = [];
124
+ const executing = [];
125
+ for (let i = 0; i < steps.length; i++) {
126
+ const step = steps[i];
127
+ if (!step)
128
+ continue;
129
+ const stepDeps = step.depends ?? [];
130
+ // Check if dependencies are satisfied (simplified - assumes sequential if dependencies exist)
131
+ const hasDependencies = Array.isArray(stepDeps) && stepDeps.length > 0;
132
+ if (hasDependencies) {
133
+ // Wait for dependencies to complete before executing
134
+ // For now, execute sequentially if dependencies exist
135
+ // TODO: Implement proper dependency resolution
136
+ await Promise.all(executing);
137
+ executing.length = 0;
138
+ }
139
+ const promise = executeStep(step, i);
140
+ executing.push(promise);
141
+ if (executing.length >= maxConcurrency) {
142
+ const completed = await Promise.race(executing);
143
+ results.push(completed);
144
+ // Remove one promise from executing (the one that completed)
145
+ // We can't reliably identify which one, so remove the first
146
+ // The promise is already resolved by Promise.race, so we can safely remove it
147
+ const removedPromise = executing.shift();
148
+ // Explicitly mark as handled to satisfy ESLint
149
+ void removedPromise;
150
+ }
151
+ }
152
+ // Wait for remaining steps
153
+ if (executing.length > 0) {
154
+ const remainingResults = await Promise.allSettled(executing);
155
+ for (const result of remainingResults) {
156
+ if (result.status === 'fulfilled') {
157
+ results.push(result.value);
158
+ }
159
+ else {
160
+ // Handle rejected promise - reason can be any type
161
+ const reason = result.reason;
162
+ let errorMessage;
163
+ if (reason instanceof Error) {
164
+ errorMessage = reason.message;
165
+ }
166
+ else if (typeof reason === 'string') {
167
+ errorMessage = reason;
168
+ }
169
+ else if (reason === null || reason === undefined) {
170
+ errorMessage = 'Unknown error';
171
+ }
172
+ else {
173
+ // For other types, use JSON.stringify if possible, otherwise fallback
174
+ try {
175
+ errorMessage = JSON.stringify(reason);
176
+ }
177
+ catch {
178
+ errorMessage = 'Unknown error';
179
+ }
180
+ }
181
+ results.push({
182
+ stepIndex: -1,
183
+ success: false,
184
+ error: errorMessage,
185
+ duration: 0
186
+ });
187
+ }
188
+ }
189
+ }
190
+ return results.sort((a, b) => a.stepIndex - b.stepIndex);
191
+ }
192
+ export async function executeSkill(skillName, _taskId, parallel = false, maxConcurrency = Infinity) {
193
+ const skillDir = getSkillDir(skillName);
194
+ if (!existsSync(skillDir)) {
195
+ console.error(chalk.red(`✗ Skill not found: ${skillName}`));
196
+ return;
197
+ }
198
+ const stepsPath = join(skillDir, 'steps.yaml');
199
+ if (!existsSync(stepsPath)) {
200
+ console.error(chalk.red(`✗ Skill steps not found: ${skillName}`));
201
+ return;
202
+ }
203
+ try {
204
+ const steps = yaml.load(readFileSync(stepsPath, 'utf-8'));
205
+ console.log(chalk.blue(` Executing skill: ${skillName}`));
206
+ console.log(chalk.gray(` Steps: ${String(steps.steps?.length ?? 0)}`));
207
+ console.log(chalk.gray(` Mode: ${parallel ? 'concurrent' : 'sequential'}`));
208
+ if (steps.steps && Array.isArray(steps.steps)) {
209
+ if (parallel) {
210
+ // Execute steps concurrently
211
+ const results = await executeStepsConcurrently(steps.steps, maxConcurrency);
212
+ const successCount = results.filter(r => r.success).length;
213
+ const failCount = results.length - successCount;
214
+ console.log(chalk.blue(` Execution Summary: ${String(successCount)} successful, ${String(failCount)} failed`));
215
+ if (failCount > 0) {
216
+ const failedSteps = results.filter(r => !r.success);
217
+ throw new Error(`Skill execution failed: ${String(failedSteps.length)} step(s) failed`);
218
+ }
219
+ }
220
+ else {
221
+ // Execute steps sequentially (original behavior)
222
+ for (let i = 0; i < steps.steps.length; i++) {
223
+ const step = steps.steps[i];
224
+ if (!step)
225
+ continue;
226
+ console.log(chalk.gray(` Step ${String(i + 1)}/${String(steps.steps.length)}: ${step.type ?? 'unknown'}`));
227
+ const result = await executeStep(step, i);
228
+ if (!result.success) {
229
+ const errorMsg = result.error ?? 'Unknown error';
230
+ throw new Error(`Step ${String(i + 1)} failed: ${errorMsg}`);
231
+ }
232
+ }
233
+ }
234
+ }
235
+ console.log(chalk.green(` ✓ Skill execution completed: ${skillName}`));
236
+ }
237
+ catch (e) {
238
+ const errorMessage = e instanceof Error ? e.message : String(e);
239
+ console.error(chalk.red(`✗ Error executing skill: ${errorMessage}`));
240
+ throw e;
241
+ }
242
+ }
243
+ function ensureDir(path) {
244
+ if (!existsSync(path)) {
245
+ mkdirSync(path, { recursive: true });
246
+ }
247
+ }
248
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1,12 @@
1
+ interface SkillsshResult {
2
+ success: boolean;
3
+ skillName?: string;
4
+ skillDir?: string;
5
+ error?: string;
6
+ }
7
+ /**
8
+ * Fetches and converts a skill from skills.sh to TMD format
9
+ */
10
+ export declare function addSkillFromSkillssh(ownerRepo: string): Promise<SkillsshResult>;
11
+ export {};
12
+ //# sourceMappingURL=skillssh.d.ts.map
@@ -0,0 +1,135 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { getSkillsDir, getSkillDir } from './paths.js';
4
+ import yaml from 'js-yaml';
5
+ /**
6
+ * Fetches and converts a skill from skills.sh to TMD format
7
+ */
8
+ export async function addSkillFromSkillssh(ownerRepo) {
9
+ // Validate owner/repo format
10
+ const parts = ownerRepo.split('/');
11
+ if (parts.length !== 2 || !parts[0] || !parts[1]) {
12
+ return {
13
+ success: false,
14
+ error: `Invalid format: "${ownerRepo}". Expected: <owner>/<repo>`
15
+ };
16
+ }
17
+ const [owner, repo] = parts;
18
+ const skillName = repo;
19
+ // Check if skill already exists
20
+ const skillDir = getSkillDir(skillName);
21
+ if (existsSync(skillDir)) {
22
+ return {
23
+ success: false,
24
+ error: `Skill already exists: ${skillName}`
25
+ };
26
+ }
27
+ // Fetch skill content from GitHub
28
+ const skillContent = await fetchSkillContent(owner, repo);
29
+ if (!skillContent.success) {
30
+ return {
31
+ success: false,
32
+ error: skillContent.error ?? 'Unknown error'
33
+ };
34
+ }
35
+ // Create skill directory
36
+ const skillsDir = getSkillsDir();
37
+ if (!existsSync(skillsDir)) {
38
+ mkdirSync(skillsDir, { recursive: true });
39
+ }
40
+ mkdirSync(skillDir, { recursive: true });
41
+ // Convert and save skill files
42
+ saveSkillFiles(skillDir, skillName, ownerRepo, skillContent.content ?? '');
43
+ return {
44
+ success: true,
45
+ skillName,
46
+ skillDir
47
+ };
48
+ }
49
+ async function fetchSkillContent(owner, repo) {
50
+ // Try common skill file locations
51
+ const possiblePaths = [
52
+ `https://raw.githubusercontent.com/${owner}/${repo}/main/README.md`,
53
+ `https://raw.githubusercontent.com/${owner}/${repo}/master/README.md`,
54
+ `https://raw.githubusercontent.com/${owner}/${repo}/main/skill.md`,
55
+ `https://raw.githubusercontent.com/${owner}/${repo}/master/skill.md`,
56
+ ];
57
+ for (const url of possiblePaths) {
58
+ try {
59
+ const response = await fetch(url);
60
+ if (response.ok) {
61
+ const content = await response.text();
62
+ return { success: true, content };
63
+ }
64
+ }
65
+ catch {
66
+ // Continue to next URL
67
+ }
68
+ }
69
+ return {
70
+ success: false,
71
+ error: `Could not fetch skill from ${owner}/${repo}. Check that the repository exists and is public.`
72
+ };
73
+ }
74
+ function saveSkillFiles(skillDir, skillName, ownerRepo, content) {
75
+ // Parse frontmatter if present
76
+ const { frontmatter, body } = parseFrontmatter(content);
77
+ // Create skill.md
78
+ const skillMd = `# Skill: ${skillName}
79
+
80
+ ## Source
81
+ Imported from [skills.sh](https://skills.sh): \`${ownerRepo}\`
82
+
83
+ ## Description
84
+ ${body || 'No description available.'}
85
+ `;
86
+ writeFileSync(join(skillDir, 'skill.md'), skillMd);
87
+ // Create metadata.yaml with source attribution
88
+ const version = typeof frontmatter['version'] === 'string' ? frontmatter['version'] : '1.0.0';
89
+ const description = typeof frontmatter['description'] === 'string' ? frontmatter['description'] : `Skill imported from skills.sh: ${ownerRepo}`;
90
+ const tags = Array.isArray(frontmatter['tags']) ? frontmatter['tags'] : [];
91
+ const metadata = {
92
+ name: skillName,
93
+ version,
94
+ description,
95
+ tags,
96
+ source: 'skillssh',
97
+ repo: ownerRepo,
98
+ importedAt: new Date().toISOString(),
99
+ interface: {
100
+ input: [],
101
+ output: {}
102
+ }
103
+ };
104
+ writeFileSync(join(skillDir, 'metadata.yaml'), yaml.dump(metadata));
105
+ // Create config.yaml
106
+ const config = {
107
+ // Default configuration
108
+ };
109
+ writeFileSync(join(skillDir, 'config.yaml'), yaml.dump(config));
110
+ // Create steps.yaml placeholder
111
+ const steps = {
112
+ steps: [
113
+ {
114
+ type: 'procedural',
115
+ description: 'This skill contains procedural knowledge. See skill.md for details.'
116
+ }
117
+ ]
118
+ };
119
+ writeFileSync(join(skillDir, 'steps.yaml'), yaml.dump(steps));
120
+ }
121
+ function parseFrontmatter(content) {
122
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
123
+ const match = content.match(frontmatterRegex);
124
+ if (match?.[1] && match[2]) {
125
+ try {
126
+ const frontmatter = yaml.load(match[1]);
127
+ return { frontmatter: frontmatter ?? {}, body: match[2].trim() };
128
+ }
129
+ catch {
130
+ return { frontmatter: {}, body: content };
131
+ }
132
+ }
133
+ return { frontmatter: {}, body: content };
134
+ }
135
+ //# sourceMappingURL=skillssh.js.map
@@ -0,0 +1,26 @@
1
+ import type { Success } from './act-processing.js';
2
+ export interface SuccessfulPractice {
3
+ description: string;
4
+ context: string;
5
+ category: 'process' | 'tool' | 'approach' | 'pattern';
6
+ applicability: string;
7
+ steps: string[];
8
+ }
9
+ export interface StandardizationRecommendation {
10
+ practice: SuccessfulPractice;
11
+ recommendation: string;
12
+ priority: 'high' | 'medium' | 'low';
13
+ }
14
+ /**
15
+ * Extract successful practices from successes
16
+ */
17
+ export declare function extractSuccessfulPractices(successes: Success[]): SuccessfulPractice[];
18
+ /**
19
+ * Generate standardization recommendations
20
+ */
21
+ export declare function generateStandardizationRecommendations(practices: SuccessfulPractice[]): StandardizationRecommendation[];
22
+ /**
23
+ * Format standardization document content
24
+ */
25
+ export declare function formatStandardizationDocument(practices: SuccessfulPractice[], recommendations: StandardizationRecommendation[]): string;
26
+ //# sourceMappingURL=standardization.d.ts.map
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Extract successful practices from successes
3
+ */
4
+ export function extractSuccessfulPractices(successes) {
5
+ const practices = [];
6
+ for (const success of successes) {
7
+ // Determine category based on goal description
8
+ const goalLower = success.goal.toLowerCase();
9
+ let category = 'process';
10
+ if (goalLower.includes('tool') || goalLower.includes('system') || goalLower.includes('platform')) {
11
+ category = 'tool';
12
+ }
13
+ else if (goalLower.includes('approach') || goalLower.includes('method') || goalLower.includes('strategy')) {
14
+ category = 'approach';
15
+ }
16
+ else if (goalLower.includes('pattern') || goalLower.includes('template') || goalLower.includes('standard')) {
17
+ category = 'pattern';
18
+ }
19
+ practices.push({
20
+ description: success.goal,
21
+ context: `Successfully achieved in current PDCA cycle`,
22
+ category,
23
+ applicability: `Applicable when similar goals or contexts are encountered`,
24
+ steps: [
25
+ `Review the approach used to achieve: ${success.goal}`,
26
+ `Document the key factors that contributed to success`,
27
+ `Identify conditions where this practice can be applied`,
28
+ `Create reusable template or checklist if applicable`
29
+ ]
30
+ });
31
+ }
32
+ return practices;
33
+ }
34
+ /**
35
+ * Generate standardization recommendations
36
+ */
37
+ export function generateStandardizationRecommendations(practices) {
38
+ const recommendations = [];
39
+ for (const practice of practices) {
40
+ let priority = 'medium';
41
+ // Higher priority for over-achieved goals
42
+ if (practice.description.toLowerCase().includes('exceed') ||
43
+ practice.description.toLowerCase().includes('over-achieved')) {
44
+ priority = 'high';
45
+ }
46
+ // Higher priority for process and pattern practices
47
+ if (practice.category === 'process' || practice.category === 'pattern') {
48
+ priority = 'high';
49
+ }
50
+ recommendations.push({
51
+ practice,
52
+ recommendation: `Standardize the practice: ${practice.description}. This practice was successful and can be reused in similar contexts.`,
53
+ priority
54
+ });
55
+ }
56
+ return recommendations;
57
+ }
58
+ /**
59
+ * Format standardization document content
60
+ */
61
+ export function formatStandardizationDocument(practices, recommendations) {
62
+ let content = '# Standardization: Successful Practices\n\n';
63
+ content += 'This document identifies successful practices from the current PDCA cycle that should be standardized for future use.\n\n';
64
+ if (practices.length === 0) {
65
+ content += 'No successful practices identified for standardization.\n';
66
+ return content;
67
+ }
68
+ content += '## Successful Practices Identified\n\n';
69
+ content += `Total practices: ${String(practices.length)}\n\n`;
70
+ // Group by category
71
+ const byCategory = {};
72
+ for (const practice of practices) {
73
+ const category = practice.category;
74
+ byCategory[category] ??= [];
75
+ byCategory[category].push(practice);
76
+ }
77
+ for (const [category, categoryPractices] of Object.entries(byCategory)) {
78
+ content += `### ${category.charAt(0).toUpperCase() + category.slice(1)} Practices\n\n`;
79
+ for (const practice of categoryPractices) {
80
+ content += `#### ${practice.description}\n\n`;
81
+ content += `**Context**: ${practice.context}\n\n`;
82
+ content += `**Applicability**: ${practice.applicability}\n\n`;
83
+ content += `**Steps to Implement**:\n`;
84
+ for (const step of practice.steps) {
85
+ content += `- ${step}\n`;
86
+ }
87
+ content += '\n';
88
+ }
89
+ }
90
+ content += '## Standardization Recommendations\n\n';
91
+ for (const rec of recommendations) {
92
+ const priorityEmoji = rec.priority === 'high' ? '🔴' : rec.priority === 'medium' ? '🟡' : '🟢';
93
+ content += `### ${priorityEmoji} ${rec.priority.toUpperCase()} Priority: ${rec.practice.description}\n\n`;
94
+ content += `${rec.recommendation}\n\n`;
95
+ }
96
+ const patternPractices = practices.filter(p => p.category === 'pattern');
97
+ if (patternPractices.length > 0) {
98
+ content += '## Reusable Patterns\n\n';
99
+ content += 'The following patterns can be reused in future PDCA cycles:\n\n';
100
+ for (const practice of patternPractices) {
101
+ content += `- **${practice.description}**: ${practice.applicability}\n`;
102
+ }
103
+ }
104
+ return content;
105
+ }
106
+ //# sourceMappingURL=standardization.js.map
@@ -0,0 +1,35 @@
1
+ import type { Task } from './tasks.js';
2
+ export interface TaskExecutionResult {
3
+ taskIndex: number;
4
+ success: boolean;
5
+ error?: string;
6
+ duration: number;
7
+ }
8
+ export interface TaskChain {
9
+ tasks: Task[];
10
+ dependencyGraph: Map<number, number[]>;
11
+ executionOrder: number[][];
12
+ }
13
+ /**
14
+ * Build dependency graph from tasks
15
+ * Returns a map of task index to array of dependency indices
16
+ */
17
+ export declare function buildDependencyGraph(tasks: Task[]): Map<number, number[]>;
18
+ /**
19
+ * Detect cycles in dependency graph using DFS
20
+ */
21
+ export declare function detectCycles(graph: Map<number, number[]>): number[] | null;
22
+ /**
23
+ * Topological sort to determine execution order
24
+ * Returns array of arrays, where each inner array contains tasks that can run concurrently
25
+ */
26
+ export declare function topologicalSort(tasks: Task[], graph: Map<number, number[]>): number[][];
27
+ /**
28
+ * Execute tasks concurrently with dependency management
29
+ * @param tasks Array of tasks to execute
30
+ * @param executeTask Function to execute a single task
31
+ * @param maxConcurrency Maximum number of concurrent executions
32
+ * @returns Array of execution results
33
+ */
34
+ export declare function executeConcurrently(tasks: Task[], executeTask: (task: Task) => Promise<TaskExecutionResult>, maxConcurrency?: number): Promise<TaskExecutionResult[]>;
35
+ //# sourceMappingURL=task-chain.d.ts.map