task-pipeliner 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.
- package/LICENSE +21 -0
- package/README.ko.md +1034 -0
- package/README.md +1031 -0
- package/dist/cli/index.d.ts +19 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +147 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +48 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +75 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/cli/ui.d.ts +39 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +84 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/core/__tests__/actual-execution.test.d.ts +2 -0
- package/dist/core/__tests__/actual-execution.test.d.ts.map +1 -0
- package/dist/core/__tests__/actual-execution.test.js +140 -0
- package/dist/core/__tests__/actual-execution.test.js.map +1 -0
- package/dist/core/__tests__/base-dir.test.d.ts +2 -0
- package/dist/core/__tests__/base-dir.test.d.ts.map +1 -0
- package/dist/core/__tests__/base-dir.test.js +146 -0
- package/dist/core/__tests__/base-dir.test.js.map +1 -0
- package/dist/core/__tests__/built-code-execution.test.d.ts +2 -0
- package/dist/core/__tests__/built-code-execution.test.d.ts.map +1 -0
- package/dist/core/__tests__/built-code-execution.test.js +48 -0
- package/dist/core/__tests__/built-code-execution.test.js.map +1 -0
- package/dist/core/__tests__/choose-as-var-condition.test.d.ts +2 -0
- package/dist/core/__tests__/choose-as-var-condition.test.d.ts.map +1 -0
- package/dist/core/__tests__/choose-as-var-condition.test.js +308 -0
- package/dist/core/__tests__/choose-as-var-condition.test.js.map +1 -0
- package/dist/core/__tests__/cli-integration.test.d.ts +2 -0
- package/dist/core/__tests__/cli-integration.test.d.ts.map +1 -0
- package/dist/core/__tests__/cli-integration.test.js +83 -0
- package/dist/core/__tests__/cli-integration.test.js.map +1 -0
- package/dist/core/__tests__/comprehensive-basic-yaml.test.d.ts +2 -0
- package/dist/core/__tests__/comprehensive-basic-yaml.test.d.ts.map +1 -0
- package/dist/core/__tests__/comprehensive-basic-yaml.test.js +111 -0
- package/dist/core/__tests__/comprehensive-basic-yaml.test.js.map +1 -0
- package/dist/core/__tests__/condition-evaluator.test.d.ts +2 -0
- package/dist/core/__tests__/condition-evaluator.test.d.ts.map +1 -0
- package/dist/core/__tests__/condition-evaluator.test.js +170 -0
- package/dist/core/__tests__/condition-evaluator.test.js.map +1 -0
- package/dist/core/__tests__/debug-basic-yaml.test.d.ts +2 -0
- package/dist/core/__tests__/debug-basic-yaml.test.d.ts.map +1 -0
- package/dist/core/__tests__/debug-basic-yaml.test.js +128 -0
- package/dist/core/__tests__/debug-basic-yaml.test.js.map +1 -0
- package/dist/core/__tests__/example-files.test.d.ts +2 -0
- package/dist/core/__tests__/example-files.test.d.ts.map +1 -0
- package/dist/core/__tests__/example-files.test.js +200 -0
- package/dist/core/__tests__/example-files.test.js.map +1 -0
- package/dist/core/__tests__/executor-choice-integration.test.d.ts +2 -0
- package/dist/core/__tests__/executor-choice-integration.test.d.ts.map +1 -0
- package/dist/core/__tests__/executor-choice-integration.test.js +171 -0
- package/dist/core/__tests__/executor-choice-integration.test.js.map +1 -0
- package/dist/core/__tests__/executor-choice.test.d.ts +2 -0
- package/dist/core/__tests__/executor-choice.test.d.ts.map +1 -0
- package/dist/core/__tests__/executor-choice.test.js +174 -0
- package/dist/core/__tests__/executor-choice.test.js.map +1 -0
- package/dist/core/__tests__/executor-parallel.test.d.ts +2 -0
- package/dist/core/__tests__/executor-parallel.test.d.ts.map +1 -0
- package/dist/core/__tests__/executor-parallel.test.js +136 -0
- package/dist/core/__tests__/executor-parallel.test.js.map +1 -0
- package/dist/core/__tests__/executor-prompt.test.d.ts +2 -0
- package/dist/core/__tests__/executor-prompt.test.d.ts.map +1 -0
- package/dist/core/__tests__/executor-prompt.test.js +149 -0
- package/dist/core/__tests__/executor-prompt.test.js.map +1 -0
- package/dist/core/__tests__/executor-real-scenario.test.d.ts +2 -0
- package/dist/core/__tests__/executor-real-scenario.test.d.ts.map +1 -0
- package/dist/core/__tests__/executor-real-scenario.test.js +169 -0
- package/dist/core/__tests__/executor-real-scenario.test.js.map +1 -0
- package/dist/core/__tests__/file-condition.test.d.ts +2 -0
- package/dist/core/__tests__/file-condition.test.d.ts.map +1 -0
- package/dist/core/__tests__/file-condition.test.js +182 -0
- package/dist/core/__tests__/file-condition.test.js.map +1 -0
- package/dist/core/__tests__/final-verification.test.d.ts +2 -0
- package/dist/core/__tests__/final-verification.test.d.ts.map +1 -0
- package/dist/core/__tests__/final-verification.test.js +59 -0
- package/dist/core/__tests__/final-verification.test.js.map +1 -0
- package/dist/core/__tests__/parallel-when-condition.test.d.ts +2 -0
- package/dist/core/__tests__/parallel-when-condition.test.d.ts.map +1 -0
- package/dist/core/__tests__/parallel-when-condition.test.js +155 -0
- package/dist/core/__tests__/parallel-when-condition.test.js.map +1 -0
- package/dist/core/__tests__/parser.test.d.ts +2 -0
- package/dist/core/__tests__/parser.test.d.ts.map +1 -0
- package/dist/core/__tests__/parser.test.js +94 -0
- package/dist/core/__tests__/parser.test.js.map +1 -0
- package/dist/core/__tests__/real-inquirer-test.test.d.ts +2 -0
- package/dist/core/__tests__/real-inquirer-test.test.d.ts.map +1 -0
- package/dist/core/__tests__/real-inquirer-test.test.js +20 -0
- package/dist/core/__tests__/real-inquirer-test.test.js.map +1 -0
- package/dist/core/__tests__/reproduce-bug.test.d.ts +2 -0
- package/dist/core/__tests__/reproduce-bug.test.d.ts.map +1 -0
- package/dist/core/__tests__/reproduce-bug.test.js +84 -0
- package/dist/core/__tests__/reproduce-bug.test.js.map +1 -0
- package/dist/core/__tests__/timeout-retry.test.d.ts +2 -0
- package/dist/core/__tests__/timeout-retry.test.d.ts.map +1 -0
- package/dist/core/__tests__/timeout-retry.test.js +184 -0
- package/dist/core/__tests__/timeout-retry.test.js.map +1 -0
- package/dist/core/__tests__/workflow-validation.test.d.ts +2 -0
- package/dist/core/__tests__/workflow-validation.test.d.ts.map +1 -0
- package/dist/core/__tests__/workflow-validation.test.js +120 -0
- package/dist/core/__tests__/workflow-validation.test.js.map +1 -0
- package/dist/core/__tests__/workspace.test.d.ts +2 -0
- package/dist/core/__tests__/workspace.test.d.ts.map +1 -0
- package/dist/core/__tests__/workspace.test.js +29 -0
- package/dist/core/__tests__/workspace.test.js.map +1 -0
- package/dist/core/__tests__/yaml-integration.test.d.ts +2 -0
- package/dist/core/__tests__/yaml-integration.test.d.ts.map +1 -0
- package/dist/core/__tests__/yaml-integration.test.js +114 -0
- package/dist/core/__tests__/yaml-integration.test.js.map +1 -0
- package/dist/core/__tests__/yaml-scenarios.test.d.ts +2 -0
- package/dist/core/__tests__/yaml-scenarios.test.d.ts.map +1 -0
- package/dist/core/__tests__/yaml-scenarios.test.js +199 -0
- package/dist/core/__tests__/yaml-scenarios.test.js.map +1 -0
- package/dist/core/condition-evaluator.d.ts +44 -0
- package/dist/core/condition-evaluator.d.ts.map +1 -0
- package/dist/core/condition-evaluator.js +121 -0
- package/dist/core/condition-evaluator.js.map +1 -0
- package/dist/core/executor.d.ts +172 -0
- package/dist/core/executor.d.ts.map +1 -0
- package/dist/core/executor.js +579 -0
- package/dist/core/executor.js.map +1 -0
- package/dist/core/parser.d.ts +41 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +202 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/rust-task-runner.d.ts +14 -0
- package/dist/core/rust-task-runner.d.ts.map +1 -0
- package/dist/core/rust-task-runner.js +34 -0
- package/dist/core/rust-task-runner.js.map +1 -0
- package/dist/core/task-runner.d.ts +63 -0
- package/dist/core/task-runner.d.ts.map +1 -0
- package/dist/core/task-runner.js +252 -0
- package/dist/core/task-runner.js.map +1 -0
- package/dist/core/template.d.ts +11 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +36 -0
- package/dist/core/template.js.map +1 -0
- package/dist/core/workflow-schema.d.ts +31 -0
- package/dist/core/workflow-schema.d.ts.map +1 -0
- package/dist/core/workflow-schema.js +125 -0
- package/dist/core/workflow-schema.js.map +1 -0
- package/dist/core/workspace.d.ts +90 -0
- package/dist/core/workspace.d.ts.map +1 -0
- package/dist/core/workspace.js +143 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/task-pipeliner-rs.node +0 -0
- package/dist/types/condition.d.ts +62 -0
- package/dist/types/condition.d.ts.map +1 -0
- package/dist/types/condition.js +6 -0
- package/dist/types/condition.js.map +1 -0
- package/dist/types/workflow.d.ts +69 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Parser
|
|
3
|
+
*
|
|
4
|
+
* Supports both YAML and JSON format workflow files.
|
|
5
|
+
* Uses polymorphism to handle different file formats.
|
|
6
|
+
* Validates parsed data using Zod schemas for type safety.
|
|
7
|
+
*/
|
|
8
|
+
import { parse } from 'yaml';
|
|
9
|
+
import { ZodError } from 'zod';
|
|
10
|
+
import { validateWorkflow } from './workflow-schema.js';
|
|
11
|
+
/**
|
|
12
|
+
* Fix malformed step (YAML indentation issue)
|
|
13
|
+
* When choose/prompt is null but properties exist at step level
|
|
14
|
+
* This happens when YAML is incorrectly indented
|
|
15
|
+
*/
|
|
16
|
+
function fixMalformedStep(step) {
|
|
17
|
+
const stepAsRecord = step;
|
|
18
|
+
// Fix malformed choose structure
|
|
19
|
+
if ('choose' in stepAsRecord &&
|
|
20
|
+
(stepAsRecord.choose === null || stepAsRecord.choose === undefined) &&
|
|
21
|
+
'message' in stepAsRecord &&
|
|
22
|
+
'options' in stepAsRecord) {
|
|
23
|
+
return {
|
|
24
|
+
choose: {
|
|
25
|
+
message: stepAsRecord.message,
|
|
26
|
+
options: stepAsRecord.options,
|
|
27
|
+
as: stepAsRecord.as,
|
|
28
|
+
},
|
|
29
|
+
when: stepAsRecord.when,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// Fix malformed prompt structure
|
|
33
|
+
if ('prompt' in stepAsRecord &&
|
|
34
|
+
(stepAsRecord.prompt === null || stepAsRecord.prompt === undefined) &&
|
|
35
|
+
'message' in stepAsRecord &&
|
|
36
|
+
'as' in stepAsRecord) {
|
|
37
|
+
return {
|
|
38
|
+
prompt: {
|
|
39
|
+
message: stepAsRecord.message,
|
|
40
|
+
as: stepAsRecord.as,
|
|
41
|
+
default: stepAsRecord.default,
|
|
42
|
+
validate: stepAsRecord.validate,
|
|
43
|
+
},
|
|
44
|
+
when: stepAsRecord.when,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// Fix malformed parallel steps
|
|
48
|
+
if ('parallel' in stepAsRecord && Array.isArray(stepAsRecord.parallel)) {
|
|
49
|
+
return {
|
|
50
|
+
...stepAsRecord,
|
|
51
|
+
parallel: stepAsRecord.parallel.map((subStep) => fixMalformedStep(subStep)),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return step;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* YAML Parser
|
|
58
|
+
*/
|
|
59
|
+
export class YAMLParser {
|
|
60
|
+
parse(content) {
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = parse(content);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new Error(`Invalid YAML format: ${error instanceof Error ? error.message : String(error)}`);
|
|
67
|
+
}
|
|
68
|
+
// Fix malformed steps before validation
|
|
69
|
+
if (parsed && typeof parsed === 'object' && 'steps' in parsed) {
|
|
70
|
+
const workflow = parsed;
|
|
71
|
+
if (Array.isArray(workflow.steps)) {
|
|
72
|
+
workflow.steps = workflow.steps.map(step => fixMalformedStep(step));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Validate using Zod schema
|
|
76
|
+
try {
|
|
77
|
+
const validated = validateWorkflow(parsed);
|
|
78
|
+
return validated;
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (error instanceof ZodError) {
|
|
82
|
+
// Zod validation error
|
|
83
|
+
const issues = error.issues.map((issue) => {
|
|
84
|
+
const path = issue.path.length > 0 ? ` at ${issue.path.join('.')}` : '';
|
|
85
|
+
return ` - ${issue.message}${path}`;
|
|
86
|
+
}).join('\n');
|
|
87
|
+
throw new Error(`Invalid workflow structure:\n${issues}`);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
extractStepLineNumbers(content) {
|
|
93
|
+
const lineNumbers = new Map();
|
|
94
|
+
const lines = content.split('\n');
|
|
95
|
+
let stepIndex = 0;
|
|
96
|
+
let inSteps = false; // Track if we're inside the "steps:" section
|
|
97
|
+
for (let i = 0; i < lines.length; i++) {
|
|
98
|
+
const trimmed = lines[i].trim();
|
|
99
|
+
// Found the "steps:" section
|
|
100
|
+
if (trimmed === 'steps:' || trimmed.startsWith('steps:')) {
|
|
101
|
+
inSteps = true;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Found a step (line starting with "-")
|
|
105
|
+
if (inSteps && trimmed.startsWith('-')) {
|
|
106
|
+
lineNumbers.set(stepIndex++, i + 1); // i+1 because line numbers are 1-based
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return lineNumbers;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* JSON Parser
|
|
114
|
+
*/
|
|
115
|
+
export class JSONParser {
|
|
116
|
+
parse(content) {
|
|
117
|
+
let parsed;
|
|
118
|
+
try {
|
|
119
|
+
parsed = JSON.parse(content);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
throw new Error(`Invalid JSON format: ${error instanceof Error ? error.message : String(error)}`);
|
|
123
|
+
}
|
|
124
|
+
// Fix malformed steps before validation
|
|
125
|
+
if (parsed && typeof parsed === 'object' && 'steps' in parsed) {
|
|
126
|
+
const workflow = parsed;
|
|
127
|
+
if (Array.isArray(workflow.steps)) {
|
|
128
|
+
workflow.steps = workflow.steps.map(step => fixMalformedStep(step));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Validate using Zod schema
|
|
132
|
+
try {
|
|
133
|
+
const validated = validateWorkflow(parsed);
|
|
134
|
+
return validated;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (error instanceof ZodError) {
|
|
138
|
+
// Zod validation error
|
|
139
|
+
const issues = error.issues.map((issue) => {
|
|
140
|
+
const path = issue.path.length > 0 ? ` at ${issue.path.join('.')}` : '';
|
|
141
|
+
return ` - ${issue.message}${path}`;
|
|
142
|
+
}).join('\n');
|
|
143
|
+
throw new Error(`Invalid workflow structure:\n${issues}`);
|
|
144
|
+
}
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
extractStepLineNumbers(content) {
|
|
149
|
+
const lineNumbers = new Map();
|
|
150
|
+
const lines = content.split('\n');
|
|
151
|
+
let stepIndex = 0;
|
|
152
|
+
let inSteps = false;
|
|
153
|
+
let inStepsArray = false;
|
|
154
|
+
for (let i = 0; i < lines.length; i++) {
|
|
155
|
+
const line = lines[i];
|
|
156
|
+
const trimmed = line.trim();
|
|
157
|
+
// Found "steps" property
|
|
158
|
+
if (trimmed.startsWith('"steps"') || trimmed.startsWith("'steps'")) {
|
|
159
|
+
inSteps = true;
|
|
160
|
+
// Check if it's an array start on the same line
|
|
161
|
+
if (trimmed.includes('[')) {
|
|
162
|
+
inStepsArray = true;
|
|
163
|
+
}
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// Found array start after "steps"
|
|
167
|
+
if (inSteps && trimmed === '[') {
|
|
168
|
+
inStepsArray = true;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
// Found array end
|
|
172
|
+
if (inStepsArray && trimmed === ']') {
|
|
173
|
+
inStepsArray = false;
|
|
174
|
+
inSteps = false;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
// Found a step object (starts with "{" and we're in steps array)
|
|
178
|
+
if (inStepsArray && trimmed.startsWith('{')) {
|
|
179
|
+
lineNumbers.set(stepIndex++, i + 1);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return lineNumbers;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get appropriate parser based on file extension
|
|
187
|
+
*/
|
|
188
|
+
export function getParser(filePath) {
|
|
189
|
+
const ext = filePath.toLowerCase().split('.').pop();
|
|
190
|
+
switch (ext) {
|
|
191
|
+
case 'yaml':
|
|
192
|
+
case 'yml':
|
|
193
|
+
return new YAMLParser();
|
|
194
|
+
case 'json':
|
|
195
|
+
return new JSONParser();
|
|
196
|
+
default:
|
|
197
|
+
// Default to YAML if extension is not recognized
|
|
198
|
+
// This maintains backward compatibility
|
|
199
|
+
return new YAMLParser();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust Task Runner Module
|
|
3
|
+
* Directly imports Rust NAPI module (auto-generated by @napi-rs/cli)
|
|
4
|
+
*/
|
|
5
|
+
interface RustTaskRunnerModule {
|
|
6
|
+
runTask(command: string): Promise<boolean>;
|
|
7
|
+
runTaskSync(command: string): boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Load Rust module (dynamically require .node file in ESM)
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadRustModule(): Promise<RustTaskRunnerModule | null>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=rust-task-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust-task-runner.d.ts","sourceRoot":"","sources":["../../src/core/rust-task-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,UAAU,oBAAoB;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACvC;AAID;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CA4B3E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust Task Runner Module
|
|
3
|
+
* Directly imports Rust NAPI module (auto-generated by @napi-rs/cli)
|
|
4
|
+
*/
|
|
5
|
+
let rustModule = null;
|
|
6
|
+
/**
|
|
7
|
+
* Load Rust module (dynamically require .node file in ESM)
|
|
8
|
+
*/
|
|
9
|
+
export async function loadRustModule() {
|
|
10
|
+
if (rustModule) {
|
|
11
|
+
return rustModule;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const path = await import('path');
|
|
15
|
+
const { fileURLToPath } = await import('url');
|
|
16
|
+
const { createRequire } = await import('module');
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = path.dirname(__filename);
|
|
19
|
+
const nodePath = path.resolve(__dirname, '../task-pipeliner-rs.node');
|
|
20
|
+
// Use require to load .node file in ESM
|
|
21
|
+
const require = createRequire(import.meta.url);
|
|
22
|
+
const module = require(nodePath);
|
|
23
|
+
if (module && 'runTask' in module) {
|
|
24
|
+
rustModule = module;
|
|
25
|
+
return rustModule;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (_error) {
|
|
29
|
+
// Return null if Rust module not found (use fallback)
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=rust-task-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust-task-runner.js","sourceRoot":"","sources":["../../src/core/rust-task-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,IAAI,UAAU,GAAgC,IAAI,CAAC;AAEnD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEjD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,2BAA2B,CAAC,CAAC;QAEtE,wCAAwC;QACxC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEjC,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;YAClC,UAAU,GAAG,MAA8B,CAAC;YAC5C,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,sDAAsD;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface TaskRunResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
stdout: string[];
|
|
4
|
+
stderr: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare class TaskRunner {
|
|
7
|
+
/**
|
|
8
|
+
* Run a task command with box-style output streaming
|
|
9
|
+
*
|
|
10
|
+
* @param command - Shell command to execute
|
|
11
|
+
* @param stepIndex - Step index in workflow (for tracking)
|
|
12
|
+
* @param stepName - Display name for the step
|
|
13
|
+
* @param branchIndex - Branch index for parallel execution
|
|
14
|
+
* @param bufferOutput - If true, collect output instead of displaying immediately
|
|
15
|
+
* @param hasCondition - If true, step has a condition (affects border color)
|
|
16
|
+
* @param lineNumber - Line number in YAML file (for error reporting)
|
|
17
|
+
* @param fileName - YAML file name (for error reporting)
|
|
18
|
+
* @param cwd - Working directory for command execution
|
|
19
|
+
* @param timeout - Timeout in seconds (optional)
|
|
20
|
+
*/
|
|
21
|
+
run(command: string, stepIndex?: number, stepName?: string, branchIndex?: number, bufferOutput?: boolean, hasCondition?: boolean, lineNumber?: number, fileName?: string, cwd?: string, timeout?: number): Promise<boolean | TaskRunResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Run command in buffered mode (collect all output for later display)
|
|
24
|
+
* Used for parallel execution where we need to collect output first
|
|
25
|
+
*/
|
|
26
|
+
private runBuffered;
|
|
27
|
+
/**
|
|
28
|
+
* Run command in real-time mode (output immediately as it happens)
|
|
29
|
+
*/
|
|
30
|
+
private runRealtime;
|
|
31
|
+
/**
|
|
32
|
+
* Parse command string into command and arguments
|
|
33
|
+
*/
|
|
34
|
+
private parseCommand;
|
|
35
|
+
/**
|
|
36
|
+
* Create spawn options with optional working directory
|
|
37
|
+
*/
|
|
38
|
+
private createSpawnOptions;
|
|
39
|
+
/**
|
|
40
|
+
* Process stream buffer and extract complete lines
|
|
41
|
+
*
|
|
42
|
+
* Command output comes in chunks, not necessarily line-by-line.
|
|
43
|
+
* This function:
|
|
44
|
+
* 1. Combines new chunk with existing buffer
|
|
45
|
+
* 2. Extracts all complete lines (ending with \n)
|
|
46
|
+
* 3. Keeps incomplete line in buffer for next chunk
|
|
47
|
+
*
|
|
48
|
+
* Example:
|
|
49
|
+
* - Buffer: "Hello "
|
|
50
|
+
* - Chunk: "World\nHow are"
|
|
51
|
+
* - Result: lines=["Hello World"], remaining="How are"
|
|
52
|
+
*/
|
|
53
|
+
private processStreamBuffer;
|
|
54
|
+
/**
|
|
55
|
+
* Format nested output (add | prefix for nested display)
|
|
56
|
+
*/
|
|
57
|
+
private formatNestedOutput;
|
|
58
|
+
/**
|
|
59
|
+
* Display buffered output in box format (for parallel execution, nested display)
|
|
60
|
+
*/
|
|
61
|
+
displayBufferedOutput(result: TaskRunResult, stepName: string, isNested?: boolean, lineNumber?: number, fileName?: string): void;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=task-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-runner.d.ts","sourceRoot":"","sources":["../../src/core/task-runner.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAQD,qBAAa,UAAU;IACrB;;;;;;;;;;;;;OAaG;IACG,GAAG,CACP,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,GAAE,OAAe,EAC7B,YAAY,GAAE,OAAe,EAC7B,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,GAAG,aAAa,CAAC;IAWnC;;;OAGG;YACW,WAAW;IAgEzB;;OAEG;YACW,WAAW;IAkFzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,qBAAqB,CACnB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,OAAe,EACzB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI;CAgBR"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task Runner
|
|
3
|
+
*
|
|
4
|
+
* Executes shell commands and displays output in a nice box format.
|
|
5
|
+
*
|
|
6
|
+
* Two modes:
|
|
7
|
+
* 1. Real-time mode: Output appears immediately as command runs (normal execution)
|
|
8
|
+
* 2. Buffered mode: Collect all output first, display later (parallel execution)
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Box-style output with borders
|
|
12
|
+
* - Line-by-line streaming
|
|
13
|
+
* - Error handling
|
|
14
|
+
* - Working directory support (baseDir)
|
|
15
|
+
*/
|
|
16
|
+
import { createStepHeaderBox, createStepFooterMessage, createErrorBox, formatNestedLine, } from '../cli/ui.js';
|
|
17
|
+
export class TaskRunner {
|
|
18
|
+
/**
|
|
19
|
+
* Run a task command with box-style output streaming
|
|
20
|
+
*
|
|
21
|
+
* @param command - Shell command to execute
|
|
22
|
+
* @param stepIndex - Step index in workflow (for tracking)
|
|
23
|
+
* @param stepName - Display name for the step
|
|
24
|
+
* @param branchIndex - Branch index for parallel execution
|
|
25
|
+
* @param bufferOutput - If true, collect output instead of displaying immediately
|
|
26
|
+
* @param hasCondition - If true, step has a condition (affects border color)
|
|
27
|
+
* @param lineNumber - Line number in YAML file (for error reporting)
|
|
28
|
+
* @param fileName - YAML file name (for error reporting)
|
|
29
|
+
* @param cwd - Working directory for command execution
|
|
30
|
+
* @param timeout - Timeout in seconds (optional)
|
|
31
|
+
*/
|
|
32
|
+
async run(command, stepIndex, stepName, branchIndex, bufferOutput = false, hasCondition = false, lineNumber, fileName, cwd, timeout) {
|
|
33
|
+
// Choose mode based on bufferOutput flag
|
|
34
|
+
if (bufferOutput) {
|
|
35
|
+
// Collect output for later display (parallel execution)
|
|
36
|
+
return this.runBuffered(command, cwd, timeout);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Display output immediately (normal execution)
|
|
40
|
+
return this.runRealtime(command, stepName || command, hasCondition, lineNumber, fileName, cwd, timeout);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Run command in buffered mode (collect all output for later display)
|
|
45
|
+
* Used for parallel execution where we need to collect output first
|
|
46
|
+
*/
|
|
47
|
+
async runBuffered(command, workingDirectory, timeoutSeconds) {
|
|
48
|
+
const { spawn } = await import('child_process');
|
|
49
|
+
const [commandName, ...commandArgs] = this.parseCommand(command);
|
|
50
|
+
const spawnOptions = this.createSpawnOptions(workingDirectory);
|
|
51
|
+
return new Promise((resolve, _reject) => {
|
|
52
|
+
const child = spawn(commandName, commandArgs, spawnOptions);
|
|
53
|
+
const allStdoutLines = [];
|
|
54
|
+
const allStderrLines = [];
|
|
55
|
+
let incompleteStdoutLine = '';
|
|
56
|
+
let incompleteStderrLine = '';
|
|
57
|
+
let timeoutId = null;
|
|
58
|
+
// Set up timeout if specified
|
|
59
|
+
if (timeoutSeconds && timeoutSeconds > 0) {
|
|
60
|
+
timeoutId = setTimeout(() => {
|
|
61
|
+
child.kill('SIGTERM');
|
|
62
|
+
const timeoutMessage = `Command timed out after ${timeoutSeconds} seconds`;
|
|
63
|
+
allStderrLines.push(timeoutMessage);
|
|
64
|
+
resolve({ success: false, stdout: allStdoutLines, stderr: allStderrLines });
|
|
65
|
+
}, timeoutSeconds * 1000);
|
|
66
|
+
}
|
|
67
|
+
// Collect stdout lines
|
|
68
|
+
child.stdout?.on('data', (data) => {
|
|
69
|
+
const dataChunk = data.toString();
|
|
70
|
+
const { lines: completeLines, remaining: incompleteLine } = this.processStreamBuffer(dataChunk, incompleteStdoutLine);
|
|
71
|
+
allStdoutLines.push(...completeLines);
|
|
72
|
+
incompleteStdoutLine = incompleteLine;
|
|
73
|
+
});
|
|
74
|
+
// Collect stderr lines
|
|
75
|
+
child.stderr?.on('data', (data) => {
|
|
76
|
+
const dataChunk = data.toString();
|
|
77
|
+
const { lines: completeLines, remaining: incompleteLine } = this.processStreamBuffer(dataChunk, incompleteStderrLine);
|
|
78
|
+
allStderrLines.push(...completeLines);
|
|
79
|
+
incompleteStderrLine = incompleteLine;
|
|
80
|
+
});
|
|
81
|
+
// When process finishes, add any remaining incomplete lines
|
|
82
|
+
child.on('close', (exitCode) => {
|
|
83
|
+
if (timeoutId) {
|
|
84
|
+
clearTimeout(timeoutId);
|
|
85
|
+
}
|
|
86
|
+
if (incompleteStdoutLine.trim()) {
|
|
87
|
+
allStdoutLines.push(incompleteStdoutLine);
|
|
88
|
+
}
|
|
89
|
+
if (incompleteStderrLine.trim()) {
|
|
90
|
+
allStderrLines.push(incompleteStderrLine);
|
|
91
|
+
}
|
|
92
|
+
const success = exitCode === 0;
|
|
93
|
+
resolve({ success, stdout: allStdoutLines, stderr: allStderrLines });
|
|
94
|
+
});
|
|
95
|
+
child.on('error', (error) => {
|
|
96
|
+
if (timeoutId) {
|
|
97
|
+
clearTimeout(timeoutId);
|
|
98
|
+
}
|
|
99
|
+
const errorMessage = `Error: ${error.message}`;
|
|
100
|
+
resolve({ success: false, stdout: allStdoutLines, stderr: [...allStderrLines, errorMessage] });
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Run command in real-time mode (output immediately as it happens)
|
|
106
|
+
*/
|
|
107
|
+
async runRealtime(command, displayName, hasWhenCondition, lineNumber, fileName, workingDirectory, timeoutSeconds) {
|
|
108
|
+
const { spawn } = await import('child_process');
|
|
109
|
+
const [commandName, ...commandArgs] = this.parseCommand(command);
|
|
110
|
+
const spawnOptions = this.createSpawnOptions(workingDirectory);
|
|
111
|
+
// Green border if step has condition, cyan otherwise
|
|
112
|
+
const borderColor = hasWhenCondition ? 'green' : 'cyan';
|
|
113
|
+
const headerBox = createStepHeaderBox(displayName, lineNumber, fileName, { borderColor });
|
|
114
|
+
console.log(headerBox);
|
|
115
|
+
return new Promise((resolve) => {
|
|
116
|
+
const child = spawn(commandName, commandArgs, spawnOptions);
|
|
117
|
+
let incompleteStdoutLine = '';
|
|
118
|
+
let incompleteStderrLine = '';
|
|
119
|
+
let timeoutId = null;
|
|
120
|
+
// Set up timeout if specified
|
|
121
|
+
if (timeoutSeconds && timeoutSeconds > 0) {
|
|
122
|
+
timeoutId = setTimeout(() => {
|
|
123
|
+
child.kill('SIGTERM');
|
|
124
|
+
const timeoutMessage = `Command timed out after ${timeoutSeconds} seconds`;
|
|
125
|
+
const errorBox = createErrorBox(timeoutMessage);
|
|
126
|
+
console.error(errorBox);
|
|
127
|
+
const footerMessage = createStepFooterMessage(false);
|
|
128
|
+
console.log(footerMessage);
|
|
129
|
+
resolve(false);
|
|
130
|
+
}, timeoutSeconds * 1000);
|
|
131
|
+
}
|
|
132
|
+
// Process stdout: output complete lines immediately
|
|
133
|
+
child.stdout?.on('data', (data) => {
|
|
134
|
+
const dataChunk = data.toString();
|
|
135
|
+
const { lines: completeLines, remaining: incompleteLine } = this.processStreamBuffer(dataChunk, incompleteStdoutLine);
|
|
136
|
+
completeLines.forEach(line => process.stdout.write(`│ ${line}\n`));
|
|
137
|
+
incompleteStdoutLine = incompleteLine;
|
|
138
|
+
});
|
|
139
|
+
// Process stderr: output complete lines immediately
|
|
140
|
+
child.stderr?.on('data', (data) => {
|
|
141
|
+
const dataChunk = data.toString();
|
|
142
|
+
const { lines: completeLines, remaining: incompleteLine } = this.processStreamBuffer(dataChunk, incompleteStderrLine);
|
|
143
|
+
completeLines.forEach(line => process.stderr.write(`│ ${line}\n`));
|
|
144
|
+
incompleteStderrLine = incompleteLine;
|
|
145
|
+
});
|
|
146
|
+
// When process finishes, output any remaining incomplete lines
|
|
147
|
+
child.on('close', (exitCode) => {
|
|
148
|
+
if (timeoutId) {
|
|
149
|
+
clearTimeout(timeoutId);
|
|
150
|
+
}
|
|
151
|
+
if (incompleteStdoutLine.trim()) {
|
|
152
|
+
process.stdout.write(`│ ${incompleteStdoutLine}\n`);
|
|
153
|
+
}
|
|
154
|
+
if (incompleteStderrLine.trim()) {
|
|
155
|
+
process.stderr.write(`│ ${incompleteStderrLine}\n`);
|
|
156
|
+
}
|
|
157
|
+
const success = exitCode === 0;
|
|
158
|
+
const footerMessage = createStepFooterMessage(success);
|
|
159
|
+
console.log(footerMessage);
|
|
160
|
+
resolve(success);
|
|
161
|
+
});
|
|
162
|
+
child.on('error', (error) => {
|
|
163
|
+
if (timeoutId) {
|
|
164
|
+
clearTimeout(timeoutId);
|
|
165
|
+
}
|
|
166
|
+
const errorBox = createErrorBox(`Error: ${error.message}`);
|
|
167
|
+
console.error(errorBox);
|
|
168
|
+
resolve(false);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Parse command string into command and arguments
|
|
174
|
+
*/
|
|
175
|
+
parseCommand(command) {
|
|
176
|
+
const parts = command.split(' ');
|
|
177
|
+
return [parts[0], ...parts.slice(1)];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Create spawn options with optional working directory
|
|
181
|
+
*/
|
|
182
|
+
createSpawnOptions(workingDirectory) {
|
|
183
|
+
const options = {
|
|
184
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
185
|
+
shell: true,
|
|
186
|
+
};
|
|
187
|
+
if (workingDirectory) {
|
|
188
|
+
options.cwd = workingDirectory;
|
|
189
|
+
}
|
|
190
|
+
return options;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Process stream buffer and extract complete lines
|
|
194
|
+
*
|
|
195
|
+
* Command output comes in chunks, not necessarily line-by-line.
|
|
196
|
+
* This function:
|
|
197
|
+
* 1. Combines new chunk with existing buffer
|
|
198
|
+
* 2. Extracts all complete lines (ending with \n)
|
|
199
|
+
* 3. Keeps incomplete line in buffer for next chunk
|
|
200
|
+
*
|
|
201
|
+
* Example:
|
|
202
|
+
* - Buffer: "Hello "
|
|
203
|
+
* - Chunk: "World\nHow are"
|
|
204
|
+
* - Result: lines=["Hello World"], remaining="How are"
|
|
205
|
+
*/
|
|
206
|
+
processStreamBuffer(chunk, buffer) {
|
|
207
|
+
const newBuffer = buffer + chunk;
|
|
208
|
+
const lines = [];
|
|
209
|
+
let remaining = newBuffer;
|
|
210
|
+
// Extract all complete lines (ending with \n)
|
|
211
|
+
while (remaining.includes('\n')) {
|
|
212
|
+
const newlineIndex = remaining.indexOf('\n');
|
|
213
|
+
const line = remaining.substring(0, newlineIndex);
|
|
214
|
+
remaining = remaining.substring(newlineIndex + 1);
|
|
215
|
+
lines.push(line);
|
|
216
|
+
}
|
|
217
|
+
return { lines, remaining };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Format nested output (add | prefix for nested display)
|
|
221
|
+
*/
|
|
222
|
+
formatNestedOutput(content, isNested) {
|
|
223
|
+
if (isNested) {
|
|
224
|
+
content.split('\n').forEach(line => {
|
|
225
|
+
if (line.trim()) {
|
|
226
|
+
console.log(`| ${line}`);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
console.log(content);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Display buffered output in box format (for parallel execution, nested display)
|
|
236
|
+
*/
|
|
237
|
+
displayBufferedOutput(result, stepName, isNested = false, lineNumber, fileName) {
|
|
238
|
+
const headerBox = createStepHeaderBox(stepName, lineNumber, fileName, { borderColor: 'cyan', isNested });
|
|
239
|
+
this.formatNestedOutput(headerBox, isNested);
|
|
240
|
+
result.stdout.forEach(line => {
|
|
241
|
+
const formattedLine = formatNestedLine(line, isNested);
|
|
242
|
+
process.stdout.write(`${formattedLine}\n`);
|
|
243
|
+
});
|
|
244
|
+
result.stderr.forEach(line => {
|
|
245
|
+
const formattedLine = formatNestedLine(line, isNested);
|
|
246
|
+
process.stderr.write(`${formattedLine}\n`);
|
|
247
|
+
});
|
|
248
|
+
const footerMessage = createStepFooterMessage(result.success, isNested);
|
|
249
|
+
console.log(footerMessage);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=task-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-runner.js","sourceRoot":"","sources":["../../src/core/task-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Variable Substitution
|
|
3
|
+
* Replaces {{variable}} with actual values from workspace
|
|
4
|
+
*/
|
|
5
|
+
import type { Workspace } from './workspace.js';
|
|
6
|
+
/**
|
|
7
|
+
* Substitute {{variable}} template variables in string with actual values
|
|
8
|
+
* Example: "Hello {{name}}" becomes "Hello John" if name variable is "John"
|
|
9
|
+
*/
|
|
10
|
+
export declare function substituteVariables(template: string, workspace: Workspace): string;
|
|
11
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/core/template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AA2BhD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,SAAS,GACnB,MAAM,CAMR"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Variable Substitution
|
|
3
|
+
* Replaces {{variable}} with actual values from workspace
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Find variable value from workspace
|
|
7
|
+
* Checks variables, facts, and choices in that order
|
|
8
|
+
*/
|
|
9
|
+
function findVariableValue(variableName, workspace, defaultValue) {
|
|
10
|
+
// First, check variables
|
|
11
|
+
if (workspace.hasVariable(variableName)) {
|
|
12
|
+
return workspace.getVariable(variableName) || defaultValue;
|
|
13
|
+
}
|
|
14
|
+
// Second, check facts
|
|
15
|
+
if (workspace.hasFact(variableName)) {
|
|
16
|
+
const factValue = workspace.getFact(variableName);
|
|
17
|
+
return typeof factValue === 'string' ? factValue : String(factValue);
|
|
18
|
+
}
|
|
19
|
+
// Third, check choices
|
|
20
|
+
if (workspace.hasChoice(variableName)) {
|
|
21
|
+
return workspace.getChoice(variableName) || defaultValue;
|
|
22
|
+
}
|
|
23
|
+
// If not found, return the original template text
|
|
24
|
+
return defaultValue;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Substitute {{variable}} template variables in string with actual values
|
|
28
|
+
* Example: "Hello {{name}}" becomes "Hello John" if name variable is "John"
|
|
29
|
+
*/
|
|
30
|
+
export function substituteVariables(template, workspace) {
|
|
31
|
+
const variablePattern = /\{\{(\w+)\}\}/g;
|
|
32
|
+
return template.replace(variablePattern, (originalMatch, variableName) => {
|
|
33
|
+
return findVariableValue(variableName, workspace, originalMatch);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=template.js.map
|