pgpm 5.29.5 → 5.30.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.
@@ -26,6 +26,7 @@ PostgreSQL Options:
26
26
 
27
27
  Additional Services:
28
28
  --minio Include MinIO S3-compatible object storage (API: 9000, Console: 9001)
29
+ --rustfs Include RustFS S3-compatible object storage (API: 9000, Console: 9001)
29
30
  --ollama Include Ollama LLM inference server (API: 11434)
30
31
  --gpu Enable NVIDIA GPU passthrough for Ollama (requires NVIDIA Container Toolkit)
31
32
 
@@ -36,6 +37,7 @@ General Options:
36
37
  Examples:
37
38
  pgpm docker start Start PostgreSQL only
38
39
  pgpm docker start --minio Start PostgreSQL + MinIO
40
+ pgpm docker start --rustfs Start PostgreSQL + RustFS
39
41
  pgpm docker start --ollama Start PostgreSQL + Ollama (CPU)
40
42
  pgpm docker start --ollama --gpu Start PostgreSQL + Ollama (NVIDIA GPU)
41
43
  pgpm docker start --port 5433 Start on custom port
@@ -44,6 +46,7 @@ Examples:
44
46
  pgpm docker start --recreate --minio Recreate PostgreSQL + MinIO
45
47
  pgpm docker stop Stop PostgreSQL
46
48
  pgpm docker stop --minio Stop PostgreSQL + MinIO
49
+ pgpm docker stop --rustfs Stop PostgreSQL + RustFS
47
50
  pgpm docker stop --ollama Stop PostgreSQL + Ollama
48
51
  pgpm docker ls List services and status
49
52
  `;
@@ -62,6 +65,23 @@ const ADDITIONAL_SERVICES = {
62
65
  command: ['server', '/data', '--console-address', ':9001'],
63
66
  volumes: [{ name: 'minio-data', containerPath: '/data' }]
64
67
  },
68
+ rustfs: {
69
+ name: 'rustfs',
70
+ image: 'rustfs/rustfs',
71
+ ports: [
72
+ { host: 9000, container: 9000 },
73
+ { host: 9001, container: 9001 }
74
+ ],
75
+ env: {
76
+ RUSTFS_ACCESS_KEY: 'minioadmin',
77
+ RUSTFS_SECRET_KEY: 'minioadmin',
78
+ RUSTFS_ADDRESS: ':9000',
79
+ RUSTFS_CONSOLE_ADDRESS: ':9001',
80
+ RUSTFS_CONSOLE_ENABLE: 'true'
81
+ },
82
+ command: ['/data'],
83
+ volumes: [{ name: 'rustfs-data', containerPath: '/data' }]
84
+ },
65
85
  ollama: {
66
86
  name: 'ollama',
67
87
  image: 'ollama/ollama',
@@ -283,6 +303,19 @@ function resolveServiceFlags(args) {
283
303
  }
284
304
  return services;
285
305
  }
306
+ function findPortConflict(services) {
307
+ const owners = new Map();
308
+ for (const service of services) {
309
+ for (const { host } of service.ports) {
310
+ const owner = owners.get(host);
311
+ if (owner) {
312
+ return `Services "${owner}" and "${service.name}" both bind host port ${host}. Start only one of them.`;
313
+ }
314
+ owners.set(host, service.name);
315
+ }
316
+ }
317
+ return null;
318
+ }
286
319
  async function listServices() {
287
320
  const dockerStatus = await (0, doctor_1.getDockerStatus)();
288
321
  const dockerAvailable = dockerStatus.binary && dockerStatus.daemon;
@@ -333,12 +366,18 @@ exports.default = async (argv, _prompter, _options) => {
333
366
  const gpu = args.gpu === true;
334
367
  const includedServices = resolveServiceFlags(args);
335
368
  switch (subcommand) {
336
- case 'start':
369
+ case 'start': {
370
+ const conflict = findPortConflict(includedServices);
371
+ if (conflict) {
372
+ await (0, inquirerer_1.cliExitWithError)(conflict);
373
+ return;
374
+ }
337
375
  await startContainer({ name, image, port, user, password, shmSize, recreate });
338
376
  for (const service of includedServices) {
339
377
  await startService(service, recreate, gpu);
340
378
  }
341
379
  break;
380
+ }
342
381
  case 'stop':
343
382
  await stopContainer(name);
344
383
  for (const service of includedServices) {
package/commands/env.js CHANGED
@@ -15,6 +15,7 @@ Database Profiles:
15
15
 
16
16
  Additional Services:
17
17
  --minio Include MinIO/S3 environment variables
18
+ --rustfs Include RustFS/S3 environment variables (same vars as --minio)
18
19
 
19
20
  Modes:
20
21
  No command Print export statements for shell evaluation
@@ -24,11 +25,13 @@ Options:
24
25
  --help, -h Show this help message
25
26
  --supabase Use Supabase profile instead of default Postgres
26
27
  --minio Include CDN_ENDPOINT, AWS_ACCESS_KEY, AWS_SECRET_KEY, AWS_REGION
28
+ --rustfs Alias for --minio (RustFS serves the same S3 API on :9000)
27
29
 
28
30
  Examples:
29
31
  pgpm env Print default Postgres env exports
30
32
  pgpm env --supabase Print Supabase env exports
31
33
  pgpm env --minio Print Postgres + MinIO env exports
34
+ pgpm env --rustfs Print Postgres + RustFS env exports
32
35
  pgpm env --supabase --minio Print Supabase + MinIO env exports
33
36
  eval "$(pgpm env)" Load default Postgres env into shell
34
37
  eval "$(pgpm env --minio)" Load Postgres + MinIO env into shell
@@ -46,13 +49,13 @@ const SUPABASE_PROFILE = {
46
49
  const DEFAULT_PROFILE = {
47
50
  ...pg_env_1.defaultPgConfig
48
51
  };
49
- const MINIO_PROFILE = {
52
+ const OBJECT_STORE_PROFILE = {
50
53
  endpoint: 'http://localhost:9000',
51
54
  accessKey: 'minioadmin',
52
55
  secretKey: 'minioadmin',
53
56
  region: 'us-east-1',
54
57
  };
55
- function configToEnvVars(config, minio) {
58
+ function configToEnvVars(config, objectStore) {
56
59
  const vars = {
57
60
  PGHOST: config.host,
58
61
  PGPORT: String(config.port),
@@ -60,23 +63,23 @@ function configToEnvVars(config, minio) {
60
63
  PGPASSWORD: config.password,
61
64
  PGDATABASE: config.database
62
65
  };
63
- if (minio) {
64
- vars.CDN_ENDPOINT = minio.endpoint;
65
- vars.AWS_ACCESS_KEY = minio.accessKey;
66
- vars.AWS_SECRET_KEY = minio.secretKey;
67
- vars.AWS_REGION = minio.region;
66
+ if (objectStore) {
67
+ vars.CDN_ENDPOINT = objectStore.endpoint;
68
+ vars.AWS_ACCESS_KEY = objectStore.accessKey;
69
+ vars.AWS_SECRET_KEY = objectStore.secretKey;
70
+ vars.AWS_REGION = objectStore.region;
68
71
  }
69
72
  return vars;
70
73
  }
71
- function printExports(config, minio) {
72
- const envVars = configToEnvVars(config, minio);
74
+ function printExports(config, objectStore) {
75
+ const envVars = configToEnvVars(config, objectStore);
73
76
  for (const [key, value] of Object.entries(envVars)) {
74
77
  console.log(`export ${key}=${value}`);
75
78
  }
76
79
  }
77
- function executeCommand(config, command, args, minio) {
80
+ function executeCommand(config, command, args, objectStore) {
78
81
  return new Promise((resolve, reject) => {
79
- const envVars = configToEnvVars(config, minio);
82
+ const envVars = configToEnvVars(config, objectStore);
80
83
  const env = {
81
84
  ...process.env,
82
85
  ...envVars
@@ -100,10 +103,11 @@ exports.default = async (argv, _prompter) => {
100
103
  process.exit(0);
101
104
  }
102
105
  const useSupabase = argv.supabase === true || typeof argv.supabase === 'string';
103
- const useMinio = argv.minio === true || typeof argv.minio === 'string';
106
+ const useObjectStore = argv.minio === true || typeof argv.minio === 'string' ||
107
+ argv.rustfs === true || typeof argv.rustfs === 'string';
104
108
  const profile = useSupabase ? SUPABASE_PROFILE : DEFAULT_PROFILE;
105
- const minioProfile = useMinio ? MINIO_PROFILE : undefined;
106
- const knownFlags = ['--supabase', '--minio'];
109
+ const objectStoreProfile = useObjectStore ? OBJECT_STORE_PROFILE : undefined;
110
+ const knownFlags = ['--supabase', '--minio', '--rustfs'];
107
111
  const rawArgs = process.argv.slice(2);
108
112
  let envIndex = rawArgs.findIndex(arg => arg === 'env');
109
113
  if (envIndex === -1) {
@@ -117,12 +121,12 @@ exports.default = async (argv, _prompter) => {
117
121
  commandArgs.splice(cwdIndex, 2);
118
122
  }
119
123
  if (commandArgs.length === 0) {
120
- printExports(profile, minioProfile);
124
+ printExports(profile, objectStoreProfile);
121
125
  return;
122
126
  }
123
127
  const [command, ...args] = commandArgs;
124
128
  try {
125
- const exitCode = await executeCommand(profile, command, args, minioProfile);
129
+ const exitCode = await executeCommand(profile, command, args, objectStoreProfile);
126
130
  process.exit(exitCode);
127
131
  }
128
132
  catch (error) {
@@ -7,7 +7,6 @@ exports.createInitUsageText = void 0;
7
7
  const core_1 = require("@pgpmjs/core");
8
8
  const env_1 = require("@pgpmjs/env");
9
9
  const types_1 = require("@pgpmjs/types");
10
- const child_process_1 = require("child_process");
11
10
  const fs_1 = __importDefault(require("fs"));
12
11
  const inquirerer_1 = require("inquirerer");
13
12
  const path_1 = __importDefault(require("path"));
@@ -273,9 +272,8 @@ function installSkillsViaNpx(skills, cwd) {
273
272
  ? entry.source
274
273
  : `https://github.com/${entry.source}`;
275
274
  for (const skill of entry.skills) {
276
- const cmd = `npx --yes skills add ${source} --skill ${skill} --yes`;
277
275
  try {
278
- (0, child_process_1.execSync)(cmd, {
276
+ (0, core_1.spawnSyncChecked)('npx', ['--yes', 'skills', 'add', source, '--skill', skill, '--yes'], {
279
277
  cwd,
280
278
  stdio: ['pipe', 'inherit', 'inherit'],
281
279
  timeout: 120_000,
@@ -24,6 +24,7 @@ PostgreSQL Options:
24
24
 
25
25
  Additional Services:
26
26
  --minio Include MinIO S3-compatible object storage (API: 9000, Console: 9001)
27
+ --rustfs Include RustFS S3-compatible object storage (API: 9000, Console: 9001)
27
28
  --ollama Include Ollama LLM inference server (API: 11434)
28
29
  --gpu Enable NVIDIA GPU passthrough for Ollama (requires NVIDIA Container Toolkit)
29
30
 
@@ -34,6 +35,7 @@ General Options:
34
35
  Examples:
35
36
  pgpm docker start Start PostgreSQL only
36
37
  pgpm docker start --minio Start PostgreSQL + MinIO
38
+ pgpm docker start --rustfs Start PostgreSQL + RustFS
37
39
  pgpm docker start --ollama Start PostgreSQL + Ollama (CPU)
38
40
  pgpm docker start --ollama --gpu Start PostgreSQL + Ollama (NVIDIA GPU)
39
41
  pgpm docker start --port 5433 Start on custom port
@@ -42,6 +44,7 @@ Examples:
42
44
  pgpm docker start --recreate --minio Recreate PostgreSQL + MinIO
43
45
  pgpm docker stop Stop PostgreSQL
44
46
  pgpm docker stop --minio Stop PostgreSQL + MinIO
47
+ pgpm docker stop --rustfs Stop PostgreSQL + RustFS
45
48
  pgpm docker stop --ollama Stop PostgreSQL + Ollama
46
49
  pgpm docker ls List services and status
47
50
  `;
@@ -60,6 +63,23 @@ const ADDITIONAL_SERVICES = {
60
63
  command: ['server', '/data', '--console-address', ':9001'],
61
64
  volumes: [{ name: 'minio-data', containerPath: '/data' }]
62
65
  },
66
+ rustfs: {
67
+ name: 'rustfs',
68
+ image: 'rustfs/rustfs',
69
+ ports: [
70
+ { host: 9000, container: 9000 },
71
+ { host: 9001, container: 9001 }
72
+ ],
73
+ env: {
74
+ RUSTFS_ACCESS_KEY: 'minioadmin',
75
+ RUSTFS_SECRET_KEY: 'minioadmin',
76
+ RUSTFS_ADDRESS: ':9000',
77
+ RUSTFS_CONSOLE_ADDRESS: ':9001',
78
+ RUSTFS_CONSOLE_ENABLE: 'true'
79
+ },
80
+ command: ['/data'],
81
+ volumes: [{ name: 'rustfs-data', containerPath: '/data' }]
82
+ },
63
83
  ollama: {
64
84
  name: 'ollama',
65
85
  image: 'ollama/ollama',
@@ -281,6 +301,19 @@ function resolveServiceFlags(args) {
281
301
  }
282
302
  return services;
283
303
  }
304
+ function findPortConflict(services) {
305
+ const owners = new Map();
306
+ for (const service of services) {
307
+ for (const { host } of service.ports) {
308
+ const owner = owners.get(host);
309
+ if (owner) {
310
+ return `Services "${owner}" and "${service.name}" both bind host port ${host}. Start only one of them.`;
311
+ }
312
+ owners.set(host, service.name);
313
+ }
314
+ }
315
+ return null;
316
+ }
284
317
  async function listServices() {
285
318
  const dockerStatus = await getDockerStatus();
286
319
  const dockerAvailable = dockerStatus.binary && dockerStatus.daemon;
@@ -331,12 +364,18 @@ export default async (argv, _prompter, _options) => {
331
364
  const gpu = args.gpu === true;
332
365
  const includedServices = resolveServiceFlags(args);
333
366
  switch (subcommand) {
334
- case 'start':
367
+ case 'start': {
368
+ const conflict = findPortConflict(includedServices);
369
+ if (conflict) {
370
+ await cliExitWithError(conflict);
371
+ return;
372
+ }
335
373
  await startContainer({ name, image, port, user, password, shmSize, recreate });
336
374
  for (const service of includedServices) {
337
375
  await startService(service, recreate, gpu);
338
376
  }
339
377
  break;
378
+ }
340
379
  case 'stop':
341
380
  await stopContainer(name);
342
381
  for (const service of includedServices) {
@@ -13,6 +13,7 @@ Database Profiles:
13
13
 
14
14
  Additional Services:
15
15
  --minio Include MinIO/S3 environment variables
16
+ --rustfs Include RustFS/S3 environment variables (same vars as --minio)
16
17
 
17
18
  Modes:
18
19
  No command Print export statements for shell evaluation
@@ -22,11 +23,13 @@ Options:
22
23
  --help, -h Show this help message
23
24
  --supabase Use Supabase profile instead of default Postgres
24
25
  --minio Include CDN_ENDPOINT, AWS_ACCESS_KEY, AWS_SECRET_KEY, AWS_REGION
26
+ --rustfs Alias for --minio (RustFS serves the same S3 API on :9000)
25
27
 
26
28
  Examples:
27
29
  pgpm env Print default Postgres env exports
28
30
  pgpm env --supabase Print Supabase env exports
29
31
  pgpm env --minio Print Postgres + MinIO env exports
32
+ pgpm env --rustfs Print Postgres + RustFS env exports
30
33
  pgpm env --supabase --minio Print Supabase + MinIO env exports
31
34
  eval "$(pgpm env)" Load default Postgres env into shell
32
35
  eval "$(pgpm env --minio)" Load Postgres + MinIO env into shell
@@ -44,13 +47,13 @@ const SUPABASE_PROFILE = {
44
47
  const DEFAULT_PROFILE = {
45
48
  ...defaultPgConfig
46
49
  };
47
- const MINIO_PROFILE = {
50
+ const OBJECT_STORE_PROFILE = {
48
51
  endpoint: 'http://localhost:9000',
49
52
  accessKey: 'minioadmin',
50
53
  secretKey: 'minioadmin',
51
54
  region: 'us-east-1',
52
55
  };
53
- function configToEnvVars(config, minio) {
56
+ function configToEnvVars(config, objectStore) {
54
57
  const vars = {
55
58
  PGHOST: config.host,
56
59
  PGPORT: String(config.port),
@@ -58,23 +61,23 @@ function configToEnvVars(config, minio) {
58
61
  PGPASSWORD: config.password,
59
62
  PGDATABASE: config.database
60
63
  };
61
- if (minio) {
62
- vars.CDN_ENDPOINT = minio.endpoint;
63
- vars.AWS_ACCESS_KEY = minio.accessKey;
64
- vars.AWS_SECRET_KEY = minio.secretKey;
65
- vars.AWS_REGION = minio.region;
64
+ if (objectStore) {
65
+ vars.CDN_ENDPOINT = objectStore.endpoint;
66
+ vars.AWS_ACCESS_KEY = objectStore.accessKey;
67
+ vars.AWS_SECRET_KEY = objectStore.secretKey;
68
+ vars.AWS_REGION = objectStore.region;
66
69
  }
67
70
  return vars;
68
71
  }
69
- function printExports(config, minio) {
70
- const envVars = configToEnvVars(config, minio);
72
+ function printExports(config, objectStore) {
73
+ const envVars = configToEnvVars(config, objectStore);
71
74
  for (const [key, value] of Object.entries(envVars)) {
72
75
  console.log(`export ${key}=${value}`);
73
76
  }
74
77
  }
75
- function executeCommand(config, command, args, minio) {
78
+ function executeCommand(config, command, args, objectStore) {
76
79
  return new Promise((resolve, reject) => {
77
- const envVars = configToEnvVars(config, minio);
80
+ const envVars = configToEnvVars(config, objectStore);
78
81
  const env = {
79
82
  ...process.env,
80
83
  ...envVars
@@ -98,10 +101,11 @@ export default async (argv, _prompter) => {
98
101
  process.exit(0);
99
102
  }
100
103
  const useSupabase = argv.supabase === true || typeof argv.supabase === 'string';
101
- const useMinio = argv.minio === true || typeof argv.minio === 'string';
104
+ const useObjectStore = argv.minio === true || typeof argv.minio === 'string' ||
105
+ argv.rustfs === true || typeof argv.rustfs === 'string';
102
106
  const profile = useSupabase ? SUPABASE_PROFILE : DEFAULT_PROFILE;
103
- const minioProfile = useMinio ? MINIO_PROFILE : undefined;
104
- const knownFlags = ['--supabase', '--minio'];
107
+ const objectStoreProfile = useObjectStore ? OBJECT_STORE_PROFILE : undefined;
108
+ const knownFlags = ['--supabase', '--minio', '--rustfs'];
105
109
  const rawArgs = process.argv.slice(2);
106
110
  let envIndex = rawArgs.findIndex(arg => arg === 'env');
107
111
  if (envIndex === -1) {
@@ -115,12 +119,12 @@ export default async (argv, _prompter) => {
115
119
  commandArgs.splice(cwdIndex, 2);
116
120
  }
117
121
  if (commandArgs.length === 0) {
118
- printExports(profile, minioProfile);
122
+ printExports(profile, objectStoreProfile);
119
123
  return;
120
124
  }
121
125
  const [command, ...args] = commandArgs;
122
126
  try {
123
- const exitCode = await executeCommand(profile, command, args, minioProfile);
127
+ const exitCode = await executeCommand(profile, command, args, objectStoreProfile);
124
128
  process.exit(exitCode);
125
129
  }
126
130
  catch (error) {
@@ -1,7 +1,6 @@
1
- import { DEFAULT_TEMPLATE_REPO, DEFAULT_TEMPLATE_TOOL_NAME, inspectTemplate, PgpmPackage, resolveBoilerplateBaseDir, scaffoldTemplate, scanBoilerplates, SkillInstaller, sluggify, } from '@pgpmjs/core';
1
+ import { DEFAULT_TEMPLATE_REPO, DEFAULT_TEMPLATE_TOOL_NAME, inspectTemplate, PgpmPackage, resolveBoilerplateBaseDir, scaffoldTemplate, scanBoilerplates, SkillInstaller, sluggify, spawnSyncChecked, } from '@pgpmjs/core';
2
2
  import { resolveWorkspaceByType } from '@pgpmjs/env';
3
3
  import { errors } from '@pgpmjs/types';
4
- import { execSync } from 'child_process';
5
4
  import fs from 'fs';
6
5
  import { registerDefaultResolver } from 'inquirerer';
7
6
  import path from 'path';
@@ -266,9 +265,8 @@ function installSkillsViaNpx(skills, cwd) {
266
265
  ? entry.source
267
266
  : `https://github.com/${entry.source}`;
268
267
  for (const skill of entry.skills) {
269
- const cmd = `npx --yes skills add ${source} --skill ${skill} --yes`;
270
268
  try {
271
- execSync(cmd, {
269
+ spawnSyncChecked('npx', ['--yes', 'skills', 'add', source, '--skill', skill, '--yes'], {
272
270
  cwd,
273
271
  stdio: ['pipe', 'inherit', 'inherit'],
274
272
  timeout: 120_000,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgpm",
3
- "version": "5.29.5",
3
+ "version": "5.30.0",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PostgreSQL Package Manager - Database migration and package management CLI",
6
6
  "main": "index.js",
@@ -33,36 +33,38 @@
33
33
  "test:watch": "jest --watch"
34
34
  },
35
35
  "devDependencies": {
36
- "@inquirerer/test": "^1.4.5",
36
+ "@inquirerer/test": "^1.4.6",
37
+ "@types/cross-spawn": "^6.0.6",
37
38
  "@types/js-yaml": "^4.0.9",
38
39
  "@types/node": "^22.19.11",
39
40
  "@types/pg": "^8.20.4",
40
41
  "@types/semver": "^7.8.0",
41
42
  "@types/shelljs": "^0.10.0",
42
43
  "glob": "^13.0.6",
43
- "makage": "^0.3.0",
44
+ "makage": "^0.8.0",
44
45
  "pg": "^8.21.0",
45
46
  "ts-node": "^10.9.2"
46
47
  },
47
48
  "dependencies": {
48
- "@inquirerer/utils": "^3.3.12",
49
- "@pgpmjs/core": "^7.27.1",
50
- "@pgpmjs/diff": "^0.5.1",
51
- "@pgpmjs/env": "^2.43.1",
52
- "@pgpmjs/export": "^1.20.5",
53
- "@pgpmjs/import": "^0.5.1",
54
- "@pgpmjs/logger": "^2.25.0",
55
- "@pgpmjs/slice": "^0.16.1",
56
- "@pgpmjs/transform": "^0.25.1",
57
- "@pgpmjs/types": "^2.52.1",
49
+ "@inquirerer/utils": "^3.3.13",
50
+ "@pgpmjs/core": "^7.27.3",
51
+ "@pgpmjs/diff": "^0.5.2",
52
+ "@pgpmjs/env": "^2.43.2",
53
+ "@pgpmjs/export": "^1.20.7",
54
+ "@pgpmjs/import": "^0.5.2",
55
+ "@pgpmjs/logger": "^2.25.1",
56
+ "@pgpmjs/slice": "^0.16.2",
57
+ "@pgpmjs/transform": "^0.25.2",
58
+ "@pgpmjs/types": "^2.53.0",
58
59
  "@pgsql/quotes": "^18.2.4",
59
60
  "appstash": "^0.8.0",
61
+ "cross-spawn": "^7.0.6",
60
62
  "find-and-require-package-json": "^0.9.1",
61
- "genomic": "^5.6.5",
62
- "inquirerer": "^4.9.3",
63
+ "genomic": "^5.6.6",
64
+ "inquirerer": "^4.9.4",
63
65
  "js-yaml": "^4.1.0",
64
- "pg-cache": "^3.27.1",
65
- "pg-env": "^1.31.0",
66
+ "pg-cache": "^3.27.2",
67
+ "pg-env": "^1.31.1",
66
68
  "pgsql-deparser": "^18.3.6",
67
69
  "semver": "^7.8.5",
68
70
  "shelljs": "^0.10.0",
@@ -80,5 +82,5 @@
80
82
  "pg",
81
83
  "pgsql"
82
84
  ],
83
- "gitHead": "9a919ff3f7ec90eab2d510bb6682ce5209e53198"
85
+ "gitHead": "5e0bfead2856d1a062b495d343a43e543343f9b8"
84
86
  }