@constellation-network/node-pilot 0.0.17 → 0.0.19
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 +39 -10
- package/dist/checks/check-dependencies.js +32 -26
- package/dist/checks/check-layers.js +2 -2
- package/dist/checks/check-network.js +2 -2
- package/dist/checks/check-pilot.d.ts +5 -0
- package/dist/checks/check-pilot.js +72 -0
- package/dist/checks/check-project.js +2 -1
- package/dist/checks/check-wallet.js +1 -1
- package/dist/commands/clean.d.ts +14 -0
- package/dist/commands/clean.js +45 -0
- package/dist/commands/config.js +5 -0
- package/dist/commands/restart.js +8 -3
- package/dist/commands/shutdown.d.ts +3 -0
- package/dist/commands/shutdown.js +19 -4
- package/dist/commands/status.js +3 -0
- package/dist/commands/test.js +3 -2
- package/dist/helpers/key-file-helper.js +46 -14
- package/dist/helpers/project-helper.d.ts +4 -0
- package/dist/helpers/project-helper.js +27 -5
- package/dist/helpers/prompt-helper.d.ts +1 -0
- package/dist/helpers/prompt-helper.js +13 -0
- package/dist/helpers/status-table-helper.js +29 -20
- package/dist/helpers/status-table.js +6 -3
- package/dist/services/cluster-service.js +4 -1
- package/dist/services/docker-service.d.ts +2 -1
- package/dist/services/docker-service.js +11 -4
- package/dist/services/fastforward-service.js +14 -3
- package/install-dependencies.sh +0 -48
- package/oclif.manifest.json +62 -2
- package/package.json +1 -1
- package/projects/hypergraph/test +0 -0
- package/projects/hypergraph/seedlist +0 -268
|
@@ -65,11 +65,7 @@ export const projectHelper = {
|
|
|
65
65
|
await this.installEmbedded('hypergraph');
|
|
66
66
|
const { projectDir } = configStore.getProjectInfo();
|
|
67
67
|
const { platform } = configStore.getSystemInfo();
|
|
68
|
-
|
|
69
|
-
const gl0DataDir = path.join(projectDir, 'gl0', 'data');
|
|
70
|
-
fs.mkdirSync(path.join(gl0DataDir, 'incremental_snapshot'), { recursive: true });
|
|
71
|
-
fs.mkdirSync(path.join(gl0DataDir, 'snapshot_info'));
|
|
72
|
-
fs.mkdirSync(path.join(gl0DataDir, 'tmp'));
|
|
68
|
+
this.prepareDataFolder();
|
|
73
69
|
if (platform === 'linux') {
|
|
74
70
|
const layerDir = path.join(projectDir, 'gl0');
|
|
75
71
|
// set permission for group "docker" on the layer folder and any subfolders created later
|
|
@@ -91,6 +87,16 @@ export const projectHelper = {
|
|
|
91
87
|
clm.debug(`Installing project from ${projectFolder} to ${projectDir}`);
|
|
92
88
|
fs.cpSync(projectFolder, projectDir, { recursive: true });
|
|
93
89
|
},
|
|
90
|
+
prepareDataFolder() {
|
|
91
|
+
const { projectDir } = configStore.getProjectInfo();
|
|
92
|
+
// Create gl0 folder for the fast-forward feature before Docker does
|
|
93
|
+
const gl0DataDir = path.join(projectDir, 'gl0', 'data');
|
|
94
|
+
if (!fs.existsSync(gl0DataDir)) {
|
|
95
|
+
fs.mkdirSync(path.join(gl0DataDir, 'incremental_snapshot'), { recursive: true });
|
|
96
|
+
fs.mkdirSync(path.join(gl0DataDir, 'snapshot_info'));
|
|
97
|
+
fs.mkdirSync(path.join(gl0DataDir, 'tmp'));
|
|
98
|
+
}
|
|
99
|
+
},
|
|
94
100
|
async selectProject() {
|
|
95
101
|
// prompt user to install hypergraph or metagraph
|
|
96
102
|
const networkType = await select({
|
|
@@ -139,5 +145,21 @@ export const projectHelper = {
|
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
147
|
}
|
|
148
|
+
},
|
|
149
|
+
async upgradeEmbedded(name) {
|
|
150
|
+
const projectFolder = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../projects/${name}`);
|
|
151
|
+
if (!fs.existsSync(projectFolder)) {
|
|
152
|
+
clm.error(`Project folder not found: ${projectFolder}`);
|
|
153
|
+
}
|
|
154
|
+
await this.upgradeProject(name, projectFolder);
|
|
155
|
+
},
|
|
156
|
+
async upgradeHypergraph() {
|
|
157
|
+
await this.upgradeEmbedded('hypergraph');
|
|
158
|
+
this.importEnvFiles();
|
|
159
|
+
},
|
|
160
|
+
async upgradeProject(name, projectFolder) {
|
|
161
|
+
const { projectDir } = configStore.getProjectInfo();
|
|
162
|
+
clm.debug(`Upgrading project from ${projectFolder} to ${projectDir}`);
|
|
163
|
+
fs.cpSync(projectFolder, projectDir, { recursive: true });
|
|
142
164
|
}
|
|
143
165
|
};
|
|
@@ -38,6 +38,19 @@ export const promptHelper = {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
|
+
async confirmPrompt(msg) {
|
|
42
|
+
const result = await input({
|
|
43
|
+
default: 'y',
|
|
44
|
+
message: `${msg} (y/n)`,
|
|
45
|
+
validate(value) {
|
|
46
|
+
if (value.toLowerCase() === 'y' || value.toLowerCase() === 'n') {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return 'Please enter "y" or "n"';
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return result.toLowerCase() !== 'n';
|
|
53
|
+
},
|
|
41
54
|
async doYouWishToContinue(defaultAnswer = 'y') {
|
|
42
55
|
const result = await input({
|
|
43
56
|
default: defaultAnswer,
|
|
@@ -1,44 +1,49 @@
|
|
|
1
|
+
import os from "node:os";
|
|
1
2
|
class CellFormatter {
|
|
2
3
|
formatCpu(value) {
|
|
3
|
-
if (value === '-')
|
|
4
|
-
return
|
|
5
|
-
const
|
|
4
|
+
if (!value || value === '-')
|
|
5
|
+
return '-';
|
|
6
|
+
const cores = os.cpus().length;
|
|
7
|
+
const num = Number.parseFloat(value) / cores;
|
|
8
|
+
value = num.toFixed(1) + '%';
|
|
6
9
|
if (num === 0)
|
|
7
10
|
return value;
|
|
8
|
-
if (num <
|
|
9
|
-
return this.style(value
|
|
10
|
-
if (num <
|
|
11
|
-
return this.style(value
|
|
12
|
-
return this.style(value
|
|
11
|
+
if (num < 40)
|
|
12
|
+
return this.style(value, "green");
|
|
13
|
+
if (num < 85)
|
|
14
|
+
return this.style(value, "yellow", "bold");
|
|
15
|
+
return this.style(value, "bgRed", "bold");
|
|
13
16
|
}
|
|
14
17
|
formatDistance(value) {
|
|
15
|
-
if (value === '-')
|
|
16
|
-
return
|
|
17
|
-
const num = Number(value);
|
|
18
|
+
if (!value || value === '-')
|
|
19
|
+
return '-';
|
|
20
|
+
const num = Math.abs(Number(value));
|
|
18
21
|
if (num === 0)
|
|
19
22
|
return value;
|
|
20
23
|
if (num < 9)
|
|
21
|
-
return this.style(value
|
|
22
|
-
return this.style(value
|
|
24
|
+
return this.style(value, "bgYellow", "whiteBright", "bold");
|
|
25
|
+
return this.style(value, "bgRed", "bold");
|
|
23
26
|
}
|
|
24
27
|
formatError(value) {
|
|
25
|
-
if (value === '-')
|
|
26
|
-
return
|
|
28
|
+
if (!value || value === '-')
|
|
29
|
+
return '-';
|
|
27
30
|
return this.style(value, "bgRed", "bold");
|
|
28
31
|
}
|
|
29
32
|
formatMem(value) {
|
|
30
|
-
if (value === '-')
|
|
31
|
-
return
|
|
32
|
-
const num = Number.parseInt(value
|
|
33
|
+
if (!value || value === '-')
|
|
34
|
+
return '-';
|
|
35
|
+
const num = Number.parseInt(value, 10);
|
|
33
36
|
if (num === 0)
|
|
34
37
|
return value;
|
|
35
|
-
if (num <
|
|
38
|
+
if (num < 86)
|
|
36
39
|
return this.style(value.toString(), "green");
|
|
37
|
-
if (num <
|
|
40
|
+
if (num < 99)
|
|
38
41
|
return this.style(value.toString(), "yellow", "bold");
|
|
39
42
|
return this.style(value.toString(), "red", "bold");
|
|
40
43
|
}
|
|
41
44
|
formatOrdinal(value) {
|
|
45
|
+
if (!value || value === '-')
|
|
46
|
+
return '-';
|
|
42
47
|
const [v, changed] = value.split(':');
|
|
43
48
|
if (changed) {
|
|
44
49
|
return this.style(v, "bgCyan", "whiteBright", "bold");
|
|
@@ -46,6 +51,8 @@ class CellFormatter {
|
|
|
46
51
|
return this.style(v, "cyan");
|
|
47
52
|
}
|
|
48
53
|
formatState(value) {
|
|
54
|
+
if (!value || value === '-')
|
|
55
|
+
return '-';
|
|
49
56
|
if (value === 'Offline')
|
|
50
57
|
return this.style(value, "bgRed", "bold");
|
|
51
58
|
if (value === 'Ready')
|
|
@@ -57,6 +64,8 @@ class CellFormatter {
|
|
|
57
64
|
return this.style(value, "white");
|
|
58
65
|
}
|
|
59
66
|
formatUpTIme(startTime) {
|
|
67
|
+
if (!startTime)
|
|
68
|
+
return '-';
|
|
60
69
|
const formattedTime = formatTime(Date.now() - Number(startTime), true);
|
|
61
70
|
return formattedTime ?? '-';
|
|
62
71
|
}
|
|
@@ -24,7 +24,6 @@ export class StatusTable {
|
|
|
24
24
|
return '';
|
|
25
25
|
});
|
|
26
26
|
await onKeyPress({});
|
|
27
|
-
console.log("\u001B[?25h");
|
|
28
27
|
process.exit();
|
|
29
28
|
}
|
|
30
29
|
getProjectInfo() {
|
|
@@ -55,7 +54,7 @@ export class StatusTable {
|
|
|
55
54
|
for (const p of projects) {
|
|
56
55
|
if (!values[p.layer])
|
|
57
56
|
values[p.layer] = {};
|
|
58
|
-
const n = JSON.parse(fs.readFileSync(p.path, 'utf8'));
|
|
57
|
+
const n = fs.existsSync(p.path) ? JSON.parse(fs.readFileSync(p.path, 'utf8')) : {};
|
|
59
58
|
const projectName = p.project === 'hypergraph' ? '' : p.project;
|
|
60
59
|
const network = p.network === 'integrationnet' ? 'intnet' : p.network;
|
|
61
60
|
const distance = Number.isNaN(n.clusterOrdinal - n.ordinal) ? '-' : String(n.clusterOrdinal - n.ordinal);
|
|
@@ -82,7 +81,11 @@ export class StatusTable {
|
|
|
82
81
|
}
|
|
83
82
|
this.render(rows, err.msg !== '');
|
|
84
83
|
if (err.msg) {
|
|
85
|
-
|
|
84
|
+
const d = new Date(err.date);
|
|
85
|
+
// if under 8 hours ago
|
|
86
|
+
if (d.getTime() + (8 * 60 * 60 * 1000) > Date.now()) {
|
|
87
|
+
process.stdout.write(chalk.green(` AUTO HEALED (${err.timeAgo}): `) + chalk.red(`${err.layer}:${err.msg} - ${err.date}\n`));
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
90
|
process.stdout.write(" * press any key to cancel");
|
|
88
91
|
// eslint-disable-next-line no-await-in-loop
|
|
@@ -68,6 +68,9 @@ export const clusterService = {
|
|
|
68
68
|
const { CL_L0_PEER_HTTP_HOST } = configStore.getEnvNetworkInfo(type);
|
|
69
69
|
clm.debug(`http://${CL_L0_PEER_HTTP_HOST}:${CL_PUBLIC_HTTP_PORT}/${path}`);
|
|
70
70
|
return fetch(`http://${CL_L0_PEER_HTTP_HOST}:${CL_PUBLIC_HTTP_PORT}/${path}`)
|
|
71
|
-
.then(res => res.json())
|
|
71
|
+
.then(res => res.json())
|
|
72
|
+
.catch(() => {
|
|
73
|
+
throw new Error(`Unable to connect to source node at http://${CL_L0_PEER_HTTP_HOST}:${CL_PUBLIC_HTTP_PORT}/${path}`);
|
|
74
|
+
});
|
|
72
75
|
}
|
|
73
76
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { TessellationLayer } from "../types.js";
|
|
2
2
|
export declare const dockerService: {
|
|
3
3
|
dockerBuild(): Promise<void>;
|
|
4
|
-
dockerDown(): Promise<void>;
|
|
4
|
+
dockerDown(layers?: TessellationLayer[]): Promise<void>;
|
|
5
5
|
dockerRestart(layer: TessellationLayer): Promise<void>;
|
|
6
|
+
dockerRestartAll(): Promise<void>;
|
|
6
7
|
dockerStartLayers(layers: TessellationLayer[]): Promise<void>;
|
|
7
8
|
dockerUp(): Promise<void>;
|
|
8
9
|
isRunning(): Promise<boolean>;
|
|
@@ -19,16 +19,23 @@ export const dockerService = {
|
|
|
19
19
|
if (silent) {
|
|
20
20
|
spinner.stop();
|
|
21
21
|
}
|
|
22
|
-
clm.postStep('Node container built.');
|
|
22
|
+
clm.postStep('✅ Node container built.');
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
|
-
async dockerDown() {
|
|
26
|
-
await run('down');
|
|
25
|
+
async dockerDown(layers) {
|
|
27
26
|
configStore.setProjectStatusToRunning(false);
|
|
27
|
+
await run('down', layers);
|
|
28
28
|
},
|
|
29
29
|
async dockerRestart(layer) {
|
|
30
30
|
await run('restart', [layer]);
|
|
31
31
|
},
|
|
32
|
+
async dockerRestartAll() {
|
|
33
|
+
if (await this.isRunning()) {
|
|
34
|
+
await this.dockerDown();
|
|
35
|
+
}
|
|
36
|
+
configStore.setProjectStatusToRunning(true);
|
|
37
|
+
await run('up -d');
|
|
38
|
+
},
|
|
32
39
|
async dockerStartLayers(layers) {
|
|
33
40
|
await run('up -d', layers);
|
|
34
41
|
},
|
|
@@ -37,9 +44,9 @@ export const dockerService = {
|
|
|
37
44
|
if (await this.isRunning()) {
|
|
38
45
|
await this.dockerDown();
|
|
39
46
|
}
|
|
47
|
+
configStore.setProjectStatusToRunning(true);
|
|
40
48
|
await projectHelper.generateLayerEnvFiles();
|
|
41
49
|
await run('up -d');
|
|
42
|
-
configStore.setProjectStatusToRunning(true);
|
|
43
50
|
},
|
|
44
51
|
async isRunning() {
|
|
45
52
|
return shellService.runProjectCommand('docker compose ps -q | grep .', undefined, true).then(Boolean).catch(() => false);
|
|
@@ -6,6 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
import { clm } from "../clm.js";
|
|
7
7
|
import { configStore } from "../config-store.js";
|
|
8
8
|
import { promptHelper } from "../helpers/prompt-helper.js";
|
|
9
|
+
import { shellService } from "./shell-service.js";
|
|
9
10
|
const CHUNK_SIZE = 20_000;
|
|
10
11
|
export class FastforwardService {
|
|
11
12
|
dataDir;
|
|
@@ -51,7 +52,7 @@ export class FastforwardService {
|
|
|
51
52
|
clm.debug('Saving compressedSnapshotIncremental to: ' + this.tmpDir);
|
|
52
53
|
fs.writeFileSync(path.join(this.tmpDir, ordinal.toString() + '.c'), compressedSnapshotIncremental);
|
|
53
54
|
await this.saveSnapshotFiles(ordinal.toString(), hash);
|
|
54
|
-
clm.postStep(
|
|
55
|
+
clm.postStep(`✅ Fastforward to snapshot ${chalk.bold(ordinal)} completed.`);
|
|
55
56
|
}
|
|
56
57
|
async fetchLatestSnapshot() {
|
|
57
58
|
const url = `${this.lbUrl}/global-snapshots/latest/combined`;
|
|
@@ -92,8 +93,18 @@ export class FastforwardService {
|
|
|
92
93
|
const incrementalSnapshotDir = path.join(this.dataDir, 'incremental_snapshot');
|
|
93
94
|
const hashDir = path.join(incrementalSnapshotDir, 'hash', hashSubdir);
|
|
94
95
|
const ordinalDir = path.join(incrementalSnapshotDir, 'ordinal', ordinalRounded.toString());
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
try {
|
|
97
|
+
fs.mkdirSync(hashDir, { recursive: true });
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
await shellService.runCommand(`sudo mkdir -p ${hashDir}`);
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
fs.mkdirSync(ordinalDir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
await shellService.runCommand(`sudo mkdir -p ${ordinalDir}`);
|
|
107
|
+
}
|
|
97
108
|
const destOrdinalFile = path.join(ordinalDir, ordinal);
|
|
98
109
|
if (fs.existsSync(destOrdinalFile)) {
|
|
99
110
|
clm.warn(`Snapshot ${destOrdinalFile} already exists. Skipping...`);
|
package/install-dependencies.sh
CHANGED
|
@@ -29,53 +29,6 @@ check_acl() {
|
|
|
29
29
|
fi
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
# Check and install curl
|
|
33
|
-
check_curl() {
|
|
34
|
-
# echo "Checking for curl..."
|
|
35
|
-
if command -v curl >/dev/null 2>&1; then
|
|
36
|
-
echo "✅ curl is already installed."
|
|
37
|
-
return 0
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
echo "⚠️ curl not found. Will attempt to install curl."
|
|
41
|
-
|
|
42
|
-
case "$(uname)" in
|
|
43
|
-
Linux)
|
|
44
|
-
if command -v apt >/dev/null 2>&1; then
|
|
45
|
-
echo "Installing curl using apt..."
|
|
46
|
-
sudo apt update
|
|
47
|
-
sudo apt install -y curl
|
|
48
|
-
elif command -v yum >/dev/null 2>&1; then
|
|
49
|
-
echo "Installing curl using yum..."
|
|
50
|
-
sudo yum install -y curl
|
|
51
|
-
else
|
|
52
|
-
echo "⚠️ Unsupported Linux distribution. Please install curl manually."
|
|
53
|
-
return 1
|
|
54
|
-
fi
|
|
55
|
-
;;
|
|
56
|
-
Darwin)
|
|
57
|
-
if command -v brew >/dev/null 2>&1; then
|
|
58
|
-
echo "Installing curl using Homebrew..."
|
|
59
|
-
brew install curl
|
|
60
|
-
else
|
|
61
|
-
echo "⚠️ Homebrew not found. Please install curl manually."
|
|
62
|
-
return 1
|
|
63
|
-
fi
|
|
64
|
-
;;
|
|
65
|
-
MINGW*|MSYS*|CYGWIN*)
|
|
66
|
-
echo "On Windows, please install curl manually."
|
|
67
|
-
return 1
|
|
68
|
-
;;
|
|
69
|
-
*)
|
|
70
|
-
echo "⚠️ Unsupported OS: $(uname). Please install curl manually."
|
|
71
|
-
return 1
|
|
72
|
-
;;
|
|
73
|
-
esac
|
|
74
|
-
|
|
75
|
-
echo "✅ curl installation complete."
|
|
76
|
-
return 0
|
|
77
|
-
}
|
|
78
|
-
|
|
79
32
|
# Check and install Docker Engine
|
|
80
33
|
check_docker() {
|
|
81
34
|
# echo "Checking for Docker..."
|
|
@@ -115,5 +68,4 @@ check_docker() {
|
|
|
115
68
|
# Run all checks
|
|
116
69
|
echo "🔍 Checking and installing required dependencies..."
|
|
117
70
|
check_acl
|
|
118
|
-
check_curl
|
|
119
71
|
check_docker
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"commands": {
|
|
3
|
+
"clean": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {
|
|
6
|
+
"layer": {
|
|
7
|
+
"description": "network layer to clean. e.g. gl0",
|
|
8
|
+
"name": "layer",
|
|
9
|
+
"required": true
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"description": "Remove data and/or logs from a validator node",
|
|
13
|
+
"examples": [
|
|
14
|
+
"<%= config.bin %> <%= command.id %>"
|
|
15
|
+
],
|
|
16
|
+
"flags": {
|
|
17
|
+
"all": {
|
|
18
|
+
"char": "a",
|
|
19
|
+
"description": "remove all data and logs",
|
|
20
|
+
"name": "all",
|
|
21
|
+
"allowNo": false,
|
|
22
|
+
"type": "boolean"
|
|
23
|
+
},
|
|
24
|
+
"data": {
|
|
25
|
+
"char": "d",
|
|
26
|
+
"description": "remove data",
|
|
27
|
+
"name": "data",
|
|
28
|
+
"allowNo": false,
|
|
29
|
+
"type": "boolean"
|
|
30
|
+
},
|
|
31
|
+
"logs": {
|
|
32
|
+
"char": "l",
|
|
33
|
+
"description": "remove logs",
|
|
34
|
+
"name": "logs",
|
|
35
|
+
"allowNo": false,
|
|
36
|
+
"type": "boolean"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"hasDynamicHelp": false,
|
|
40
|
+
"hiddenAliases": [],
|
|
41
|
+
"id": "clean",
|
|
42
|
+
"pluginAlias": "@constellation-network/node-pilot",
|
|
43
|
+
"pluginName": "@constellation-network/node-pilot",
|
|
44
|
+
"pluginType": "core",
|
|
45
|
+
"strict": true,
|
|
46
|
+
"enableJsonFlag": false,
|
|
47
|
+
"isESM": true,
|
|
48
|
+
"relativePath": [
|
|
49
|
+
"dist",
|
|
50
|
+
"commands",
|
|
51
|
+
"clean.js"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
3
54
|
"config": {
|
|
4
55
|
"aliases": [],
|
|
5
56
|
"args": {},
|
|
@@ -151,7 +202,16 @@
|
|
|
151
202
|
"examples": [
|
|
152
203
|
"<%= config.bin %> <%= command.id %>"
|
|
153
204
|
],
|
|
154
|
-
"flags": {
|
|
205
|
+
"flags": {
|
|
206
|
+
"layer": {
|
|
207
|
+
"char": "l",
|
|
208
|
+
"description": "specify a layer to shutdown. e.g. gl0",
|
|
209
|
+
"name": "layer",
|
|
210
|
+
"hasDynamicHelp": false,
|
|
211
|
+
"multiple": false,
|
|
212
|
+
"type": "option"
|
|
213
|
+
}
|
|
214
|
+
},
|
|
155
215
|
"hasDynamicHelp": false,
|
|
156
216
|
"hiddenAliases": [],
|
|
157
217
|
"id": "shutdown",
|
|
@@ -276,5 +336,5 @@
|
|
|
276
336
|
]
|
|
277
337
|
}
|
|
278
338
|
},
|
|
279
|
-
"version": "0.0.
|
|
339
|
+
"version": "0.0.19"
|
|
280
340
|
}
|
package/package.json
CHANGED
|
File without changes
|