wilfredwake 1.0.4 → 1.0.6
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/bin/cli.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { Command } from 'commander';
|
|
16
16
|
import chalk from 'chalk';
|
|
17
|
+
import fs from 'fs';
|
|
17
18
|
import { initCommand } from '../src/cli/commands/init.js';
|
|
18
19
|
import { statusCommand } from '../src/cli/commands/status.js';
|
|
19
20
|
import { wakeCommand } from '../src/cli/commands/wake.js';
|
|
@@ -30,7 +31,16 @@ program
|
|
|
30
31
|
.description(
|
|
31
32
|
chalk.cyan('🌅 CLI Tool for Multi-Developer Development Environment Wake & Status Management')
|
|
32
33
|
)
|
|
33
|
-
.version(
|
|
34
|
+
.version(
|
|
35
|
+
(() => {
|
|
36
|
+
try {
|
|
37
|
+
const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url)));
|
|
38
|
+
return pkg.version || '0.0.0';
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return '0.0.0';
|
|
41
|
+
}
|
|
42
|
+
})()
|
|
43
|
+
)
|
|
34
44
|
.usage(chalk.yellow('[command] [options]'));
|
|
35
45
|
|
|
36
46
|
// ═══════════════════════════════════════════════════════════════
|
|
@@ -59,7 +69,7 @@ program
|
|
|
59
69
|
program
|
|
60
70
|
.command('status [service]')
|
|
61
71
|
.description(chalk.green('Check status of all services or a specific service'))
|
|
62
|
-
.option('-e, --env <environment>', 'Environment (dev, staging, prod)'
|
|
72
|
+
.option('-e, --env <environment>', 'Environment (dev, staging, prod)')
|
|
63
73
|
.option('-f, --format <format>', 'Output format (table, json)', 'table')
|
|
64
74
|
.action(statusCommand);
|
|
65
75
|
|
|
@@ -72,7 +82,7 @@ program
|
|
|
72
82
|
program
|
|
73
83
|
.command('wake [target]')
|
|
74
84
|
.description(chalk.blue('Wake services on demand (all, <service>, or <group>)'))
|
|
75
|
-
.option('-e, --env <environment>', 'Environment (dev, staging, prod)'
|
|
85
|
+
.option('-e, --env <environment>', 'Environment (dev, staging, prod)')
|
|
76
86
|
.option('--no-wait', 'Don\'t wait for services to be ready')
|
|
77
87
|
.option('--timeout <seconds>', 'Timeout for service readiness', '300')
|
|
78
88
|
.action(wakeCommand);
|
|
@@ -85,7 +95,7 @@ program
|
|
|
85
95
|
program
|
|
86
96
|
.command('health [service]')
|
|
87
97
|
.description(chalk.cyan('Check health status of services'))
|
|
88
|
-
.option('-e, --env <environment>', 'Environment (dev, staging, prod)'
|
|
98
|
+
.option('-e, --env <environment>', 'Environment (dev, staging, prod)')
|
|
89
99
|
.action(healthCommand);
|
|
90
100
|
|
|
91
101
|
// ═══════════════════════════════════════════════════════════════
|
package/package.json
CHANGED
|
@@ -126,14 +126,14 @@ function _displayTableStatus(services, environment) {
|
|
|
126
126
|
const lastWoken = service.lastWakeTime
|
|
127
127
|
? new Date(service.lastWakeTime).toLocaleString()
|
|
128
128
|
: 'Never';
|
|
129
|
-
|
|
130
129
|
const cells = [
|
|
131
130
|
chalk.cyan(service.name.padEnd(20)),
|
|
132
131
|
statusColor(service.status.toUpperCase().padEnd(20)),
|
|
133
132
|
chalk.yellow(lastWoken.padEnd(20)),
|
|
134
|
-
chalk.gray(service.url.substring(0, 20).padEnd(20)),
|
|
133
|
+
chalk.gray((service.url || '').substring(0, 20).padEnd(20)),
|
|
135
134
|
];
|
|
136
135
|
console.log(format.tableRow(cells));
|
|
136
|
+
console.log(''); // Extra spacing between rows for clarity
|
|
137
137
|
});
|
|
138
138
|
|
|
139
139
|
console.log(''); // Spacing
|
|
@@ -158,23 +158,16 @@ function _displaySummary(services) {
|
|
|
158
158
|
|
|
159
159
|
const stats = {
|
|
160
160
|
total: services.length,
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
live: services.filter(s => s.status === 'live').length,
|
|
162
|
+
dead: services.filter(s => s.status === 'dead').length,
|
|
163
163
|
waking: services.filter(s => s.status === 'waking').length,
|
|
164
164
|
failed: services.filter(s => s.status === 'failed').length,
|
|
165
|
+
unknown: services.filter(s => s.status === 'unknown').length,
|
|
165
166
|
};
|
|
166
167
|
|
|
167
168
|
console.log(chalk.magentaBright.bold('Summary'));
|
|
168
169
|
console.log(
|
|
169
|
-
` ${colors.status.
|
|
170
|
-
stats.ready
|
|
171
|
-
)} | ${colors.status.sleeping('⚫')} Sleeping: ${colors.status.sleeping(
|
|
172
|
-
stats.sleeping
|
|
173
|
-
)} | ${colors.status.waking('⟳')} Waking: ${colors.status.waking(
|
|
174
|
-
stats.waking
|
|
175
|
-
)} | ${colors.status.failed('✗')} Failed: ${colors.status.failed(
|
|
176
|
-
stats.failed
|
|
177
|
-
)}`
|
|
170
|
+
` ${colors.status.live('✓')} Live: ${colors.status.live(stats.live)} | ${colors.status.dead('⚫')} Dead: ${colors.status.dead(stats.dead)} | ${colors.status.waking('⟳')} Waking: ${colors.status.waking(stats.waking)} | ${colors.status.failed('✗')} Failed: ${colors.status.failed(stats.failed)} | ${colors.status.unknown('?')} Unknown: ${colors.status.unknown(stats.unknown)}`
|
|
178
171
|
);
|
|
179
172
|
console.log(` Total: ${stats.total} services\n`);
|
|
180
173
|
}
|
|
@@ -283,16 +283,13 @@ export class Orchestrator {
|
|
|
283
283
|
// ═══════════════════════════════════════════════════════════════
|
|
284
284
|
// DETERMINE STATE FROM STATUS CODE
|
|
285
285
|
// ═══════════════════════════════════════════════════════════════
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
} else if (response.status >= 500) {
|
|
286
|
+
// Consider any HTTP response (2xx/3xx/4xx/5xx) as evidence the
|
|
287
|
+
// service is responsive — treat as LIVE. Only mark FAILED for
|
|
288
|
+
// server errors (5xx). This follows "mark as woken when any
|
|
289
|
+
// response is received" behavior.
|
|
290
|
+
let state = ServiceState.LIVE;
|
|
291
|
+
if (response.status >= 500) {
|
|
293
292
|
state = ServiceState.FAILED;
|
|
294
|
-
} else if (response.status >= 400) {
|
|
295
|
-
state = ServiceState.UNKNOWN;
|
|
296
293
|
}
|
|
297
294
|
|
|
298
295
|
this._logTimestamp(
|
|
@@ -85,7 +85,8 @@ export class ServiceRegistry {
|
|
|
85
85
|
*/
|
|
86
86
|
getServices(environment = 'dev') {
|
|
87
87
|
const env = this.registry?.services?.[environment] || {};
|
|
88
|
-
|
|
88
|
+
// Return service objects augmented with their name for downstream code
|
|
89
|
+
return Object.entries(env).map(([name, svc]) => ({ name, ...svc }));
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
/**
|
|
@@ -95,7 +96,9 @@ export class ServiceRegistry {
|
|
|
95
96
|
* @returns {Object|null} Service definition
|
|
96
97
|
*/
|
|
97
98
|
getService(serviceName, environment = 'dev') {
|
|
98
|
-
|
|
99
|
+
const svc = this.registry?.services?.[environment]?.[serviceName] || null;
|
|
100
|
+
if (!svc) return null;
|
|
101
|
+
return { name: serviceName, ...svc };
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
/**
|
|
@@ -125,8 +128,8 @@ export class ServiceRegistry {
|
|
|
125
128
|
// RESOLVE TARGET SERVICES
|
|
126
129
|
// ═══════════════════════════════════════════════════════════════
|
|
127
130
|
if (target === 'all') {
|
|
128
|
-
// Wake all services
|
|
129
|
-
targetServices =
|
|
131
|
+
// Wake all services (services is already an array of named objects)
|
|
132
|
+
targetServices = services;
|
|
130
133
|
} else if (Array.isArray(target)) {
|
|
131
134
|
// Wake specified services
|
|
132
135
|
targetServices = target
|