@noego/captain 1.0.0 → 1.0.2
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/dist/components/cli.js
CHANGED
|
@@ -2,19 +2,22 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CLI = void 0;
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
+
const trace_1 = require("@noego/trace");
|
|
6
|
+
const packageJson = require('../../package.json');
|
|
5
7
|
class CLI {
|
|
6
8
|
constructor(logger, parser, scheduler, executor) {
|
|
7
9
|
this.logger = logger;
|
|
8
10
|
this.parser = parser;
|
|
9
11
|
this.scheduler = scheduler;
|
|
10
12
|
this.executor = executor;
|
|
13
|
+
this.trace = (0, trace_1.getTrace)('CLI');
|
|
11
14
|
this.program = new commander_1.Command();
|
|
12
15
|
}
|
|
13
16
|
setup() {
|
|
14
17
|
this.program
|
|
15
18
|
.name('captain')
|
|
16
19
|
.description('YAML-driven task runner for TypeScript')
|
|
17
|
-
.version(
|
|
20
|
+
.version(packageJson.version)
|
|
18
21
|
.argument('[files...]', 'YAML task files to process')
|
|
19
22
|
.option('-r, --run <task>', 'Run a specific task immediately')
|
|
20
23
|
.option('-l, --list', 'List all tasks without running them')
|
|
@@ -24,10 +27,17 @@ class CLI {
|
|
|
24
27
|
});
|
|
25
28
|
}
|
|
26
29
|
async processFiles(files, options) {
|
|
30
|
+
this.trace.info('cli.process.started', {
|
|
31
|
+
fileCount: files.length,
|
|
32
|
+
selectedMode: options.list ? 'list' : options.run ? 'run' : 'schedule',
|
|
33
|
+
requestedTask: options.run
|
|
34
|
+
});
|
|
27
35
|
if (files.length === 0) {
|
|
36
|
+
this.trace.warn('cli.process.skipped', {
|
|
37
|
+
reason: 'missing_files'
|
|
38
|
+
});
|
|
28
39
|
this.logger.error('No task files specified');
|
|
29
40
|
this.program.help();
|
|
30
|
-
return;
|
|
31
41
|
}
|
|
32
42
|
// Parse all files
|
|
33
43
|
const allTasks = {};
|
|
@@ -45,25 +55,45 @@ class CLI {
|
|
|
45
55
|
}
|
|
46
56
|
}
|
|
47
57
|
catch (error) {
|
|
58
|
+
this.trace.error('cli.file.failed', {
|
|
59
|
+
file,
|
|
60
|
+
error: error instanceof Error ? error.message : String(error)
|
|
61
|
+
});
|
|
48
62
|
this.logger.error(`Error processing file ${file}: ${error}`);
|
|
49
63
|
}
|
|
50
64
|
}
|
|
51
65
|
// Handle list option
|
|
52
66
|
if (options.list) {
|
|
53
67
|
this.listTasks(allTasks);
|
|
68
|
+
this.trace.info('cli.process.completed', {
|
|
69
|
+
selectedMode: 'list',
|
|
70
|
+
taskCount: Object.keys(allTasks).length
|
|
71
|
+
});
|
|
54
72
|
return;
|
|
55
73
|
}
|
|
56
74
|
// Handle run option
|
|
57
75
|
if (options.run) {
|
|
58
76
|
await this.runSingleTask(options.run, allTasks);
|
|
77
|
+
this.trace.info('cli.process.completed', {
|
|
78
|
+
selectedMode: 'run',
|
|
79
|
+
taskCount: Object.keys(allTasks).length,
|
|
80
|
+
requestedTask: options.run
|
|
81
|
+
});
|
|
59
82
|
return;
|
|
60
83
|
}
|
|
61
84
|
// Schedule all tasks
|
|
62
85
|
this.scheduleTasks(allTasks);
|
|
86
|
+
this.trace.info('cli.process.completed', {
|
|
87
|
+
selectedMode: 'schedule',
|
|
88
|
+
taskCount: Object.keys(allTasks).length
|
|
89
|
+
});
|
|
63
90
|
// Keep the process running
|
|
64
91
|
this.logger.info('Captain is running. Press Ctrl+C to exit.');
|
|
65
92
|
}
|
|
66
93
|
listTasks(tasks) {
|
|
94
|
+
this.trace.info('cli.tasks.list.started', {
|
|
95
|
+
taskCount: Object.keys(tasks).length
|
|
96
|
+
});
|
|
67
97
|
this.logger.info('Available tasks:');
|
|
68
98
|
Object.entries(tasks).forEach(([name, task]) => {
|
|
69
99
|
this.logger.info(`- ${name}: ${task.description || 'No description'}`);
|
|
@@ -71,25 +101,45 @@ class CLI {
|
|
|
71
101
|
this.logger.info(` File: ${task.file}`);
|
|
72
102
|
this.logger.info('');
|
|
73
103
|
});
|
|
104
|
+
this.trace.info('cli.tasks.list.completed', {
|
|
105
|
+
taskCount: Object.keys(tasks).length
|
|
106
|
+
});
|
|
74
107
|
}
|
|
75
108
|
async runSingleTask(taskName, tasks) {
|
|
76
109
|
const task = tasks[taskName];
|
|
77
110
|
if (!task) {
|
|
111
|
+
this.trace.warn('cli.task.run.skipped', {
|
|
112
|
+
taskName,
|
|
113
|
+
reason: 'not_found'
|
|
114
|
+
});
|
|
78
115
|
this.logger.error(`Task "${taskName}" not found`);
|
|
79
116
|
return;
|
|
80
117
|
}
|
|
118
|
+
this.trace.info('cli.task.run.started', { taskName });
|
|
81
119
|
this.logger.info(`Running task ${taskName} immediately`);
|
|
82
|
-
await this.executor.executeTask(taskName, task);
|
|
120
|
+
const success = await this.executor.executeTask(taskName, task);
|
|
121
|
+
this.trace.info('cli.task.run.completed', { taskName, success });
|
|
83
122
|
this.logger.info('Task execution complete');
|
|
84
123
|
}
|
|
85
124
|
scheduleTasks(tasks) {
|
|
125
|
+
let validCount = 0;
|
|
126
|
+
let scheduledCount = 0;
|
|
86
127
|
Object.entries(tasks).forEach(([name, task]) => {
|
|
87
128
|
if (this.parser.validateTask(name, task)) {
|
|
88
|
-
|
|
129
|
+
validCount += 1;
|
|
130
|
+
const scheduled = this.scheduler.scheduleTask(name, task, async () => {
|
|
89
131
|
await this.executor.executeTask(name, task);
|
|
90
132
|
});
|
|
133
|
+
if (scheduled) {
|
|
134
|
+
scheduledCount += 1;
|
|
135
|
+
}
|
|
91
136
|
}
|
|
92
137
|
});
|
|
138
|
+
this.trace.info('cli.tasks.schedule.completed', {
|
|
139
|
+
taskCount: Object.keys(tasks).length,
|
|
140
|
+
validCount,
|
|
141
|
+
scheduledCount
|
|
142
|
+
});
|
|
93
143
|
this.logger.info(`Scheduled ${Object.keys(tasks).length} tasks`);
|
|
94
144
|
}
|
|
95
145
|
parse(argv) {
|
|
@@ -36,15 +36,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.Executor = void 0;
|
|
37
37
|
const child_process_1 = require("child_process");
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
+
const trace_1 = require("@noego/trace");
|
|
39
40
|
class Executor {
|
|
40
41
|
constructor(logger) {
|
|
41
42
|
this.logger = logger;
|
|
42
43
|
this.runningTasks = new Map();
|
|
44
|
+
this.trace = (0, trace_1.getTrace)('Executor');
|
|
43
45
|
}
|
|
44
46
|
async executeTask(taskName, taskDef) {
|
|
45
47
|
try {
|
|
48
|
+
this.trace.info('executor.task.started', {
|
|
49
|
+
taskName,
|
|
50
|
+
targetType: taskDef.file ? 'file' : taskDef.command ? 'command' : 'none',
|
|
51
|
+
timeoutSeconds: taskDef.timeout,
|
|
52
|
+
maxConcurrency: taskDef.concurrency?.max || 1,
|
|
53
|
+
allowOverlap: taskDef.concurrency?.allow_overlap
|
|
54
|
+
});
|
|
46
55
|
// Check concurrency limits
|
|
47
|
-
|
|
56
|
+
const concurrency = this.checkConcurrency(taskName, taskDef);
|
|
57
|
+
if (!concurrency.allowed) {
|
|
58
|
+
this.trace.warn('executor.task.skipped', {
|
|
59
|
+
taskName,
|
|
60
|
+
reason: concurrency.reason,
|
|
61
|
+
runningCount: concurrency.runningCount,
|
|
62
|
+
maxConcurrency: concurrency.maxConcurrency
|
|
63
|
+
});
|
|
48
64
|
return false;
|
|
49
65
|
}
|
|
50
66
|
const env = { ...process.env, ...taskDef.env };
|
|
@@ -52,6 +68,11 @@ class Executor {
|
|
|
52
68
|
if (taskDef.file) {
|
|
53
69
|
// Execute TypeScript/JavaScript file using tsx
|
|
54
70
|
const filePath = path.resolve(process.cwd(), taskDef.file);
|
|
71
|
+
this.trace.info('executor.task.spawned', {
|
|
72
|
+
taskName,
|
|
73
|
+
targetType: 'file',
|
|
74
|
+
filePath
|
|
75
|
+
});
|
|
55
76
|
this.logger.info(`Executing task ${taskName}: ${filePath}`);
|
|
56
77
|
childProcess = (0, child_process_1.spawn)('npx', ['tsx', filePath], {
|
|
57
78
|
env,
|
|
@@ -61,6 +82,12 @@ class Executor {
|
|
|
61
82
|
else if (taskDef.command) {
|
|
62
83
|
// Execute shell command using user's shell
|
|
63
84
|
const shell = process.env.SHELL || '/bin/sh';
|
|
85
|
+
this.trace.info('executor.task.spawned', {
|
|
86
|
+
taskName,
|
|
87
|
+
targetType: 'command',
|
|
88
|
+
shell,
|
|
89
|
+
commandLength: taskDef.command.length
|
|
90
|
+
});
|
|
64
91
|
this.logger.info(`Executing task ${taskName}: ${taskDef.command}`);
|
|
65
92
|
childProcess = (0, child_process_1.spawn)(shell, ['-c', taskDef.command], {
|
|
66
93
|
env,
|
|
@@ -68,6 +95,10 @@ class Executor {
|
|
|
68
95
|
});
|
|
69
96
|
}
|
|
70
97
|
else {
|
|
98
|
+
this.trace.warn('executor.task.skipped', {
|
|
99
|
+
taskName,
|
|
100
|
+
reason: 'missing_target'
|
|
101
|
+
});
|
|
71
102
|
this.logger.error(`Task ${taskName} has no file or command`);
|
|
72
103
|
return false;
|
|
73
104
|
}
|
|
@@ -80,6 +111,10 @@ class Executor {
|
|
|
80
111
|
// Set timeout if specified
|
|
81
112
|
if (taskDef.timeout) {
|
|
82
113
|
execution.timeout = setTimeout(() => {
|
|
114
|
+
this.trace.warn('executor.task.timed_out', {
|
|
115
|
+
taskName,
|
|
116
|
+
timeoutSeconds: taskDef.timeout
|
|
117
|
+
});
|
|
83
118
|
this.logger.warn(`Task ${taskName} timed out after ${taskDef.timeout}s`);
|
|
84
119
|
childProcess.kill();
|
|
85
120
|
}, taskDef.timeout * 1000);
|
|
@@ -90,10 +125,18 @@ class Executor {
|
|
|
90
125
|
this.runningTasks.set(taskName, runningTasks);
|
|
91
126
|
// Handle stdout
|
|
92
127
|
childProcess.stdout.on('data', (data) => {
|
|
128
|
+
this.trace.debug('executor.task.stdout', {
|
|
129
|
+
taskName,
|
|
130
|
+
outputLength: data.toString().trim().length
|
|
131
|
+
});
|
|
93
132
|
this.logger.info(`[${taskName}] ${data.toString().trim()}`);
|
|
94
133
|
});
|
|
95
134
|
// Handle stderr
|
|
96
135
|
childProcess.stderr.on('data', (data) => {
|
|
136
|
+
this.trace.debug('executor.task.stderr', {
|
|
137
|
+
taskName,
|
|
138
|
+
outputLength: data.toString().trim().length
|
|
139
|
+
});
|
|
97
140
|
this.logger.error(`[${taskName}] ${data.toString().trim()}`);
|
|
98
141
|
});
|
|
99
142
|
// Handle process completion
|
|
@@ -108,9 +151,19 @@ class Executor {
|
|
|
108
151
|
const success = code === 0;
|
|
109
152
|
const duration = (new Date().getTime() - execution.startTime.getTime()) / 1000;
|
|
110
153
|
if (success) {
|
|
154
|
+
this.trace.info('executor.task.completed', {
|
|
155
|
+
taskName,
|
|
156
|
+
exitCode: code,
|
|
157
|
+
durationSeconds: duration
|
|
158
|
+
});
|
|
111
159
|
this.logger.info(`Task ${taskName} completed successfully in ${duration}s`);
|
|
112
160
|
}
|
|
113
161
|
else {
|
|
162
|
+
this.trace.error('executor.task.failed', {
|
|
163
|
+
taskName,
|
|
164
|
+
exitCode: code,
|
|
165
|
+
durationSeconds: duration
|
|
166
|
+
});
|
|
114
167
|
this.logger.error(`Task ${taskName} failed with exit code ${code} after ${duration}s`);
|
|
115
168
|
// Implement retry logic here if needed
|
|
116
169
|
}
|
|
@@ -119,6 +172,10 @@ class Executor {
|
|
|
119
172
|
});
|
|
120
173
|
}
|
|
121
174
|
catch (error) {
|
|
175
|
+
this.trace.error('executor.task.failed', {
|
|
176
|
+
taskName,
|
|
177
|
+
error: error instanceof Error ? error.message : String(error)
|
|
178
|
+
});
|
|
122
179
|
this.logger.error(`Failed to execute task ${taskName}: ${error}`);
|
|
123
180
|
return false;
|
|
124
181
|
}
|
|
@@ -129,14 +186,28 @@ class Executor {
|
|
|
129
186
|
// Check if max concurrency would be exceeded
|
|
130
187
|
if (runningTasks.length >= maxConcurrency) {
|
|
131
188
|
this.logger.warn(`Task ${taskName} reached max concurrency (${maxConcurrency})`);
|
|
132
|
-
return
|
|
189
|
+
return {
|
|
190
|
+
allowed: false,
|
|
191
|
+
maxConcurrency,
|
|
192
|
+
reason: 'max_concurrency',
|
|
193
|
+
runningCount: runningTasks.length
|
|
194
|
+
};
|
|
133
195
|
}
|
|
134
196
|
// Check if overlap is allowed
|
|
135
197
|
if (runningTasks.length > 0 && taskDef.concurrency?.allow_overlap === false) {
|
|
136
198
|
this.logger.warn(`Task ${taskName} is already running and overlap is not allowed`);
|
|
137
|
-
return
|
|
199
|
+
return {
|
|
200
|
+
allowed: false,
|
|
201
|
+
maxConcurrency,
|
|
202
|
+
reason: 'overlap_disallowed',
|
|
203
|
+
runningCount: runningTasks.length
|
|
204
|
+
};
|
|
138
205
|
}
|
|
139
|
-
return
|
|
206
|
+
return {
|
|
207
|
+
allowed: true,
|
|
208
|
+
maxConcurrency,
|
|
209
|
+
runningCount: runningTasks.length
|
|
210
|
+
};
|
|
140
211
|
}
|
|
141
212
|
removeRunningTask(taskName, execution) {
|
|
142
213
|
const runningTasks = this.runningTasks.get(taskName) || [];
|
|
@@ -6,12 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.Parser = void 0;
|
|
7
7
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
8
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
9
|
+
const trace_1 = require("@noego/trace");
|
|
9
10
|
class Parser {
|
|
10
11
|
constructor(logger) {
|
|
11
12
|
this.logger = logger;
|
|
13
|
+
this.trace = (0, trace_1.getTrace)('Parser');
|
|
12
14
|
}
|
|
13
15
|
async parseFile(filePath) {
|
|
14
16
|
try {
|
|
17
|
+
this.trace.info('parser.parse.started', { filePath });
|
|
15
18
|
this.logger.debug(`Parsing file: ${filePath}`);
|
|
16
19
|
// Read file
|
|
17
20
|
const fileContents = await promises_1.default.readFile(filePath, 'utf8');
|
|
@@ -21,10 +24,16 @@ class Parser {
|
|
|
21
24
|
if (!parsedData.tasks) {
|
|
22
25
|
throw new Error(`Invalid task file: ${filePath}. No tasks defined.`);
|
|
23
26
|
}
|
|
24
|
-
|
|
27
|
+
const taskCount = Object.keys(parsedData.tasks).length;
|
|
28
|
+
this.trace.info('parser.parse.completed', { filePath, taskCount });
|
|
29
|
+
this.logger.info(`Parsed ${taskCount} tasks from ${filePath}`);
|
|
25
30
|
return parsedData;
|
|
26
31
|
}
|
|
27
32
|
catch (error) {
|
|
33
|
+
this.trace.error('parser.parse.failed', {
|
|
34
|
+
filePath,
|
|
35
|
+
error: error instanceof Error ? error.message : String(error)
|
|
36
|
+
});
|
|
28
37
|
this.logger.error(`Failed to parse file ${filePath}: ${error}`);
|
|
29
38
|
throw error;
|
|
30
39
|
}
|
|
@@ -32,17 +41,33 @@ class Parser {
|
|
|
32
41
|
validateTask(taskName, task) {
|
|
33
42
|
// Check required fields
|
|
34
43
|
if (!task.schedule) {
|
|
44
|
+
this.trace.warn('parser.task.validation.failed', {
|
|
45
|
+
taskName,
|
|
46
|
+
reason: 'missing_schedule'
|
|
47
|
+
});
|
|
35
48
|
this.logger.error(`Task ${taskName} is missing required field: schedule`);
|
|
36
49
|
return false;
|
|
37
50
|
}
|
|
38
51
|
if (!task.file && !task.command) {
|
|
52
|
+
this.trace.warn('parser.task.validation.failed', {
|
|
53
|
+
taskName,
|
|
54
|
+
reason: 'missing_target'
|
|
55
|
+
});
|
|
39
56
|
this.logger.error(`Task ${taskName} must have either 'file' or 'command'`);
|
|
40
57
|
return false;
|
|
41
58
|
}
|
|
42
59
|
if (task.file && task.command) {
|
|
60
|
+
this.trace.warn('parser.task.validation.failed', {
|
|
61
|
+
taskName,
|
|
62
|
+
reason: 'multiple_targets'
|
|
63
|
+
});
|
|
43
64
|
this.logger.error(`Task ${taskName} cannot have both 'file' and 'command'`);
|
|
44
65
|
return false;
|
|
45
66
|
}
|
|
67
|
+
this.trace.info('parser.task.validation.completed', {
|
|
68
|
+
taskName,
|
|
69
|
+
targetType: task.file ? 'file' : 'command'
|
|
70
|
+
});
|
|
46
71
|
return true;
|
|
47
72
|
}
|
|
48
73
|
}
|
|
@@ -35,34 +35,60 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Scheduler = void 0;
|
|
37
37
|
const cron = __importStar(require("node-cron"));
|
|
38
|
+
const trace_1 = require("@noego/trace");
|
|
38
39
|
class Scheduler {
|
|
39
40
|
constructor(logger) {
|
|
40
41
|
this.logger = logger;
|
|
41
42
|
this.schedules = new Map();
|
|
43
|
+
this.trace = (0, trace_1.getTrace)('Scheduler');
|
|
42
44
|
}
|
|
43
45
|
scheduleTask(taskName, taskDef, callback) {
|
|
44
46
|
try {
|
|
47
|
+
this.trace.info('scheduler.task.schedule.started', {
|
|
48
|
+
taskName,
|
|
49
|
+
schedule: taskDef.schedule
|
|
50
|
+
});
|
|
45
51
|
// Validate cron expression
|
|
46
52
|
if (!cron.validate(taskDef.schedule)) {
|
|
53
|
+
this.trace.warn('scheduler.task.schedule.skipped', {
|
|
54
|
+
taskName,
|
|
55
|
+
schedule: taskDef.schedule,
|
|
56
|
+
reason: 'invalid_cron'
|
|
57
|
+
});
|
|
47
58
|
this.logger.error(`Invalid cron schedule for task ${taskName}: ${taskDef.schedule}`);
|
|
48
59
|
return false;
|
|
49
60
|
}
|
|
50
61
|
// Schedule the task
|
|
51
62
|
const scheduledTask = cron.schedule(taskDef.schedule, async () => {
|
|
63
|
+
this.trace.info('scheduler.task.triggered', { taskName });
|
|
52
64
|
this.logger.info(`Running scheduled task: ${taskName}`);
|
|
53
65
|
try {
|
|
54
66
|
await callback();
|
|
67
|
+
this.trace.info('scheduler.task.completed', { taskName });
|
|
55
68
|
}
|
|
56
69
|
catch (error) {
|
|
70
|
+
this.trace.error('scheduler.task.failed', {
|
|
71
|
+
taskName,
|
|
72
|
+
error: error instanceof Error ? error.message : String(error)
|
|
73
|
+
});
|
|
57
74
|
this.logger.error(`Error in scheduled task ${taskName}: ${error}`);
|
|
58
75
|
}
|
|
59
76
|
});
|
|
60
77
|
// Store the scheduled task
|
|
61
78
|
this.schedules.set(taskName, scheduledTask);
|
|
79
|
+
this.trace.info('scheduler.task.schedule.completed', {
|
|
80
|
+
taskName,
|
|
81
|
+
schedule: taskDef.schedule
|
|
82
|
+
});
|
|
62
83
|
this.logger.info(`Scheduled task ${taskName} with cron: ${taskDef.schedule}`);
|
|
63
84
|
return true;
|
|
64
85
|
}
|
|
65
86
|
catch (error) {
|
|
87
|
+
this.trace.error('scheduler.task.schedule.failed', {
|
|
88
|
+
taskName,
|
|
89
|
+
schedule: taskDef.schedule,
|
|
90
|
+
error: error instanceof Error ? error.message : String(error)
|
|
91
|
+
});
|
|
66
92
|
this.logger.error(`Failed to schedule task ${taskName}: ${error}`);
|
|
67
93
|
return false;
|
|
68
94
|
}
|
|
@@ -72,17 +98,27 @@ class Scheduler {
|
|
|
72
98
|
if (scheduledTask) {
|
|
73
99
|
scheduledTask.stop();
|
|
74
100
|
this.schedules.delete(taskName);
|
|
101
|
+
this.trace.info('scheduler.task.stopped', { taskName });
|
|
75
102
|
this.logger.info(`Stopped scheduled task: ${taskName}`);
|
|
76
103
|
return true;
|
|
77
104
|
}
|
|
105
|
+
this.trace.warn('scheduler.task.stop.skipped', {
|
|
106
|
+
taskName,
|
|
107
|
+
reason: 'not_found'
|
|
108
|
+
});
|
|
78
109
|
return false;
|
|
79
110
|
}
|
|
80
111
|
stopAllTasks() {
|
|
112
|
+
this.trace.info('scheduler.tasks.stop_all.started', {
|
|
113
|
+
taskCount: this.schedules.size
|
|
114
|
+
});
|
|
81
115
|
for (const [taskName, scheduledTask] of this.schedules.entries()) {
|
|
82
116
|
scheduledTask.stop();
|
|
117
|
+
this.trace.info('scheduler.task.stopped', { taskName });
|
|
83
118
|
this.logger.info(`Stopped scheduled task: ${taskName}`);
|
|
84
119
|
}
|
|
85
120
|
this.schedules.clear();
|
|
121
|
+
this.trace.info('scheduler.tasks.stop_all.completed');
|
|
86
122
|
}
|
|
87
123
|
}
|
|
88
124
|
exports.Scheduler = Scheduler;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noego/captain",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "YAML-driven task runner for TypeScript files",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,12 +31,17 @@
|
|
|
31
31
|
"author": "",
|
|
32
32
|
"license": "ISC",
|
|
33
33
|
"type": "commonjs",
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
34
37
|
"dependencies": {
|
|
35
|
-
"@noego/ioc": "^0.
|
|
38
|
+
"@noego/ioc": "^0.3.1",
|
|
39
|
+
"@noego/trace": "^0.0.4",
|
|
36
40
|
"commander": "^13.1.0",
|
|
37
41
|
"dotenv": "^16.5.0",
|
|
38
42
|
"js-yaml": "^4.1.0",
|
|
39
43
|
"node-cron": "^3.0.3",
|
|
44
|
+
"rxjs": "^7.8.2",
|
|
40
45
|
"ts-node": "^10.9.2",
|
|
41
46
|
"winston": "^3.17.0"
|
|
42
47
|
},
|