gsd-opencode 1.20.1 → 1.20.3
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/commands/gsd/gsd-check-profile.md +30 -0
- package/commands/gsd/gsd-research-phase.md +2 -2
- package/get-shit-done/bin/gsd-oc-commands/check-oc-config-json.cjs +169 -0
- package/get-shit-done/bin/gsd-oc-commands/check-opencode-json.cjs +86 -0
- package/get-shit-done/bin/gsd-oc-commands/get-profile.cjs +117 -0
- package/get-shit-done/bin/gsd-oc-commands/set-profile.cjs +357 -0
- package/get-shit-done/bin/gsd-oc-commands/update-opencode-json.cjs +199 -0
- package/get-shit-done/bin/gsd-oc-commands/validate-models.cjs +75 -0
- package/get-shit-done/bin/gsd-oc-lib/oc-config.cjs +205 -0
- package/get-shit-done/bin/gsd-oc-lib/oc-core.cjs +113 -0
- package/get-shit-done/bin/gsd-oc-lib/oc-models.cjs +133 -0
- package/get-shit-done/bin/gsd-oc-lib/oc-profile-config.cjs +409 -0
- package/get-shit-done/bin/gsd-oc-tools.cjs +130 -0
- package/get-shit-done/bin/lib/oc-config.cjs +200 -0
- package/get-shit-done/bin/lib/oc-core.cjs +114 -0
- package/get-shit-done/bin/lib/oc-models.cjs +133 -0
- package/get-shit-done/bin/test/fixtures/oc-config-invalid.json +14 -0
- package/get-shit-done/bin/test/fixtures/oc-config-valid.json +22 -0
- package/get-shit-done/bin/test/get-profile.test.cjs +447 -0
- package/get-shit-done/bin/test/oc-profile-config.test.cjs +377 -0
- package/get-shit-done/bin/test/pivot-profile.test.cjs +276 -0
- package/get-shit-done/bin/test/set-profile.test.cjs +301 -0
- package/get-shit-done/workflows/diagnose-issues.md +1 -1
- package/get-shit-done/workflows/discuss-phase.md +1 -1
- package/get-shit-done/workflows/new-project.md +4 -4
- package/get-shit-done/workflows/oc-check-profile.md +181 -0
- package/get-shit-done/workflows/oc-set-profile.md +83 -243
- package/get-shit-done/workflows/plan-phase.md +4 -4
- package/get-shit-done/workflows/quick.md +1 -1
- package/get-shit-done/workflows/settings.md +4 -3
- package/package.json +2 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd-check-profile
|
|
3
|
+
description: Validate gsd-opencode profile configuration
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- read
|
|
6
|
+
- bash
|
|
7
|
+
---
|
|
8
|
+
<objective>
|
|
9
|
+
Validate gsd-opencode profile configuration across both `opencode.json` and `.planning/oc_config.json`, then report results.
|
|
10
|
+
|
|
11
|
+
Routes to the oc-check-profile workflow which handles:
|
|
12
|
+
- Validating all agent model IDs exist in the opencode models catalog
|
|
13
|
+
- Validating gsd-opencode profile structure and current profile exists
|
|
14
|
+
- Reporting results with severity classification (OK/WARNING/ERROR)
|
|
15
|
+
- Recommending /gsd-set-profile when issues are found
|
|
16
|
+
</objective>
|
|
17
|
+
|
|
18
|
+
<execution_context>
|
|
19
|
+
@~/.config/opencode/get-shit-done/workflows/oc-check-profile.md
|
|
20
|
+
</execution_context>
|
|
21
|
+
|
|
22
|
+
<process>
|
|
23
|
+
**Follow the oc-check-profile workflow** from `@~/.config/opencode/get-shit-done/workflows/oc-check-profile.md`.
|
|
24
|
+
|
|
25
|
+
The workflow handles all logic including:
|
|
26
|
+
1. Running both validations (check-opencode-json and check-config-json)
|
|
27
|
+
2. Classifying results by severity (OK/WARNING/ERROR)
|
|
28
|
+
3. Reporting results with structured diagnostic output
|
|
29
|
+
4. Recommending /gsd-set-profile when errors are found
|
|
30
|
+
</process>
|
|
@@ -136,7 +136,7 @@ write to: .planning/phases/${PHASE}-{slug}/${PHASE}-RESEARCH.md
|
|
|
136
136
|
```
|
|
137
137
|
task(
|
|
138
138
|
prompt="First, read ~/.config/opencode/agents/gsd-phase-researcher.md for your role and instructions.\n\n" + filled_prompt,
|
|
139
|
-
subagent_type="
|
|
139
|
+
subagent_type="general",
|
|
140
140
|
model="{researcher_model}",
|
|
141
141
|
description="Research Phase {phase}"
|
|
142
142
|
)
|
|
@@ -172,7 +172,7 @@ Continue research for Phase {phase_number}: {phase_name}
|
|
|
172
172
|
```
|
|
173
173
|
task(
|
|
174
174
|
prompt="First, read ~/.config/opencode/agents/gsd-phase-researcher.md for your role and instructions.\n\n" + continuation_prompt,
|
|
175
|
-
subagent_type="
|
|
175
|
+
subagent_type="general",
|
|
176
176
|
model="{researcher_model}",
|
|
177
177
|
description="Continue research Phase {phase}"
|
|
178
178
|
)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-oc-config-json.cjs — Validate profile configuration in .planning/oc_config.json
|
|
3
|
+
*
|
|
4
|
+
* Command module that validates .planning/oc_config.json profile configuration.
|
|
5
|
+
* Validates:
|
|
6
|
+
* - current_oc_profile field exists and refers to a profile in profiles.presets
|
|
7
|
+
* - profiles.presets.{current_oc_profile} contains required keys: planning, execution, verification
|
|
8
|
+
* - All model IDs exist in opencode models catalog
|
|
9
|
+
* Outputs JSON envelope format with validation results.
|
|
10
|
+
*
|
|
11
|
+
* Usage: node check-oc-config-json.cjs [cwd]
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const { output, error } = require('../gsd-oc-lib/oc-core.cjs');
|
|
17
|
+
const { getModelCatalog } = require('../gsd-oc-lib/oc-models.cjs');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Main command function
|
|
21
|
+
*
|
|
22
|
+
* @param {string} cwd - Current working directory
|
|
23
|
+
* @param {string[]} args - Command line arguments
|
|
24
|
+
*/
|
|
25
|
+
function checkOcConfigJson(cwd, args) {
|
|
26
|
+
const verbose = args.includes('--verbose');
|
|
27
|
+
const configPath = path.join(cwd, '.planning', 'oc_config.json');
|
|
28
|
+
|
|
29
|
+
// Check if oc_config.json exists
|
|
30
|
+
if (!fs.existsSync(configPath)) {
|
|
31
|
+
error('.planning/oc_config.json not found', 'CONFIG_NOT_FOUND');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// read and parse config
|
|
35
|
+
let config;
|
|
36
|
+
try {
|
|
37
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
38
|
+
config = JSON.parse(content);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
if (err instanceof SyntaxError) {
|
|
41
|
+
error('.planning/oc_config.json is not valid JSON', 'INVALID_JSON');
|
|
42
|
+
}
|
|
43
|
+
error(`Failed to read config: ${err.message}`, 'READ_FAILED');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const issues = [];
|
|
47
|
+
|
|
48
|
+
// Extract profile information
|
|
49
|
+
const currentOcProfile = config.current_oc_profile;
|
|
50
|
+
const presets = config.profiles?.presets;
|
|
51
|
+
|
|
52
|
+
// Validate current_oc_profile field (required)
|
|
53
|
+
if (currentOcProfile === undefined) {
|
|
54
|
+
issues.push({
|
|
55
|
+
field: 'current_oc_profile',
|
|
56
|
+
value: '(missing)',
|
|
57
|
+
reason: 'current_oc_profile field is required'
|
|
58
|
+
});
|
|
59
|
+
} else if (presets && typeof presets === 'object' && !presets[currentOcProfile]) {
|
|
60
|
+
const availableProfiles = presets ? Object.keys(presets).join(', ') : 'none';
|
|
61
|
+
issues.push({
|
|
62
|
+
field: 'current_oc_profile',
|
|
63
|
+
value: currentOcProfile,
|
|
64
|
+
reason: `Profile "${currentOcProfile}" not found in profiles.presets. Available: ${availableProfiles}`
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Validate profiles.presets section exists
|
|
69
|
+
if (!presets || typeof presets !== 'object') {
|
|
70
|
+
issues.push({
|
|
71
|
+
field: 'profiles.presets',
|
|
72
|
+
value: '(missing or invalid)',
|
|
73
|
+
reason: 'profiles.presets section is required'
|
|
74
|
+
});
|
|
75
|
+
const result = {
|
|
76
|
+
success: false,
|
|
77
|
+
data: {
|
|
78
|
+
passed: false,
|
|
79
|
+
current_oc_profile: currentOcProfile || null,
|
|
80
|
+
profile_data: null,
|
|
81
|
+
issues
|
|
82
|
+
},
|
|
83
|
+
error: {
|
|
84
|
+
code: 'INVALID_PROFILE',
|
|
85
|
+
message: `${issues.length} invalid profile configuration(s) found`
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
output(result);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Validate profile structure if current profile exists
|
|
93
|
+
if (currentOcProfile && presets[currentOcProfile]) {
|
|
94
|
+
const profile = presets[currentOcProfile];
|
|
95
|
+
|
|
96
|
+
// Validate that profile has required keys: planning, execution, verification
|
|
97
|
+
const requiredKeys = ['planning', 'execution', 'verification'];
|
|
98
|
+
for (const key of requiredKeys) {
|
|
99
|
+
if (profile[key] === undefined) {
|
|
100
|
+
issues.push({
|
|
101
|
+
field: `profiles.presets.${currentOcProfile}.${key}`,
|
|
102
|
+
value: '(missing)',
|
|
103
|
+
reason: `${key} model is required for ${currentOcProfile} profile`
|
|
104
|
+
});
|
|
105
|
+
} else if (typeof profile[key] !== 'string') {
|
|
106
|
+
issues.push({
|
|
107
|
+
field: `profiles.presets.${currentOcProfile}.${key}`,
|
|
108
|
+
value: profile[key],
|
|
109
|
+
reason: `${key} must be a string model ID`
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Validate model IDs against catalog
|
|
115
|
+
if (verbose) {
|
|
116
|
+
console.error('[verbose] Fetching model catalog...');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const catalogResult = getModelCatalog();
|
|
120
|
+
if (!catalogResult.success) {
|
|
121
|
+
error(catalogResult.error.message, catalogResult.error.code);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const validModels = catalogResult.models;
|
|
125
|
+
|
|
126
|
+
if (verbose) {
|
|
127
|
+
console.error(`[verbose] Found ${validModels.length} models in catalog`);
|
|
128
|
+
console.error('[verbose] Validating profile model IDs...');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (const key of requiredKeys) {
|
|
132
|
+
if (profile[key] && typeof profile[key] === 'string') {
|
|
133
|
+
if (!validModels.includes(profile[key])) {
|
|
134
|
+
issues.push({
|
|
135
|
+
field: `profiles.presets.${currentOcProfile}.${key}`,
|
|
136
|
+
value: profile[key],
|
|
137
|
+
reason: `Model ID not found in opencode models catalog`
|
|
138
|
+
});
|
|
139
|
+
} else if (verbose) {
|
|
140
|
+
console.error(`[verbose] ✓ profiles.presets.${currentOcProfile}.${key}: ${profile[key]} (valid)`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const passed = issues.length === 0;
|
|
147
|
+
|
|
148
|
+
const result = {
|
|
149
|
+
success: passed,
|
|
150
|
+
data: {
|
|
151
|
+
passed,
|
|
152
|
+
current_oc_profile: currentOcProfile || null,
|
|
153
|
+
profile_data: currentOcProfile && presets ? presets[currentOcProfile] : null,
|
|
154
|
+
issues
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
if (!passed) {
|
|
159
|
+
result.error = {
|
|
160
|
+
code: 'INVALID_PROFILE',
|
|
161
|
+
message: `${issues.length} invalid profile configuration(s) found`
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
output(result);
|
|
166
|
+
process.exit(passed ? 0 : 1);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = checkOcConfigJson;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* check-opencode-json.cjs — Validate model IDs in opencode.json
|
|
3
|
+
*
|
|
4
|
+
* Command module that validates opencode.json model IDs against the opencode models catalog.
|
|
5
|
+
* Outputs JSON envelope format with validation results.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node check-opencode-json.cjs [cwd] [--verbose]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const { output, error } = require('../gsd-oc-lib/oc-core.cjs');
|
|
13
|
+
const { getModelCatalog, validateModelIds } = require('../gsd-oc-lib/oc-models.cjs');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Main command function
|
|
17
|
+
*
|
|
18
|
+
* @param {string} cwd - Current working directory
|
|
19
|
+
* @param {string[]} args - Command line arguments
|
|
20
|
+
*/
|
|
21
|
+
function checkOpencodeJson(cwd, args) {
|
|
22
|
+
const verbose = args.includes('--verbose');
|
|
23
|
+
const opencodePath = path.join(cwd, 'opencode.json');
|
|
24
|
+
|
|
25
|
+
// Check if opencode.json exists
|
|
26
|
+
if (!fs.existsSync(opencodePath)) {
|
|
27
|
+
error('opencode.json not found in current directory', 'CONFIG_NOT_FOUND');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (verbose) {
|
|
31
|
+
console.error(`[verbose] Validating: ${opencodePath}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Fetch model catalog
|
|
35
|
+
if (verbose) {
|
|
36
|
+
console.error('[verbose] Fetching model catalog from opencode models...');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const catalogResult = getModelCatalog();
|
|
40
|
+
if (!catalogResult.success) {
|
|
41
|
+
error(catalogResult.error.message, catalogResult.error.code);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (verbose) {
|
|
45
|
+
console.error(`[verbose] Found ${catalogResult.models.length} models in catalog`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Validate model IDs
|
|
49
|
+
if (verbose) {
|
|
50
|
+
console.error('[verbose] Validating model IDs...');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const validationResult = validateModelIds(opencodePath, catalogResult.models);
|
|
55
|
+
|
|
56
|
+
const result = {
|
|
57
|
+
success: true,
|
|
58
|
+
data: validationResult
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Exit code based on validation result
|
|
62
|
+
if (validationResult.valid) {
|
|
63
|
+
output(result);
|
|
64
|
+
process.exit(0);
|
|
65
|
+
} else {
|
|
66
|
+
// Add error details for invalid models
|
|
67
|
+
result.error = {
|
|
68
|
+
code: 'INVALID_MODEL_ID',
|
|
69
|
+
message: `${validationResult.invalidCount} invalid model ID(s) found`
|
|
70
|
+
};
|
|
71
|
+
output(result);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
} catch (err) {
|
|
75
|
+
if (err.message === 'CONFIG_NOT_FOUND') {
|
|
76
|
+
error('opencode.json not found', 'CONFIG_NOT_FOUND');
|
|
77
|
+
} else if (err.message === 'INVALID_JSON') {
|
|
78
|
+
error('opencode.json is not valid JSON', 'INVALID_JSON');
|
|
79
|
+
} else {
|
|
80
|
+
error(err.message, 'VALIDATION_FAILED');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Export for use by main router
|
|
86
|
+
module.exports = checkOpencodeJson;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get-profile.cjs — Retrieve profile definitions from oc_config.json
|
|
3
|
+
*
|
|
4
|
+
* Command module that exports getProfile(cwd, args) function with two operation modes:
|
|
5
|
+
* 1. No parameters: Returns current profile definition
|
|
6
|
+
* 2. Profile name parameter: Returns specified profile definition
|
|
7
|
+
*
|
|
8
|
+
* Output format: JSON envelope {success: true, data: {profileName: {planning, execution, verification}}}
|
|
9
|
+
* Flags: --raw (output raw JSON without envelope), --verbose (output diagnostics to stderr)
|
|
10
|
+
*
|
|
11
|
+
* Usage: node get-profile.cjs [profile-name] [--raw] [--verbose]
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const { output, error } = require('../gsd-oc-lib/oc-core.cjs');
|
|
17
|
+
const { loadOcProfileConfig } = require('../gsd-oc-lib/oc-profile-config.cjs');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Main command function
|
|
21
|
+
*
|
|
22
|
+
* @param {string} cwd - Current working directory
|
|
23
|
+
* @param {string[]} args - Command line arguments
|
|
24
|
+
*/
|
|
25
|
+
function getProfile(cwd, args) {
|
|
26
|
+
const verbose = args.includes('--verbose');
|
|
27
|
+
const raw = args.includes('--raw');
|
|
28
|
+
const log = verbose ? (...args) => console.error('[get-profile]', ...args) : () => {};
|
|
29
|
+
|
|
30
|
+
// Filter out flags to get profile name argument
|
|
31
|
+
const profileArgs = args.filter(arg => !arg.startsWith('--'));
|
|
32
|
+
|
|
33
|
+
// Check for too many arguments
|
|
34
|
+
if (profileArgs.length > 1) {
|
|
35
|
+
error('Too many arguments. Usage: get-profile [profile-name]', 'INVALID_ARGS');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const profileName = profileArgs.length > 0 ? profileArgs[0] : null;
|
|
39
|
+
|
|
40
|
+
log('Loading oc_config.json');
|
|
41
|
+
|
|
42
|
+
// Load oc_config.json
|
|
43
|
+
const loadResult = loadOcProfileConfig(cwd);
|
|
44
|
+
if (!loadResult.success) {
|
|
45
|
+
error(loadResult.error.message, loadResult.error.code);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { config, configPath } = loadResult;
|
|
49
|
+
|
|
50
|
+
log(`Config loaded from ${configPath}`);
|
|
51
|
+
|
|
52
|
+
// ========== MODE 1: No parameters (get current profile) ==========
|
|
53
|
+
if (!profileName) {
|
|
54
|
+
log('Mode 1: Getting current profile');
|
|
55
|
+
|
|
56
|
+
// Check current_oc_profile is set
|
|
57
|
+
if (!config.current_oc_profile) {
|
|
58
|
+
error(
|
|
59
|
+
'current_oc_profile not set in oc_config.json. Run set-profile first.',
|
|
60
|
+
'MISSING_CURRENT_PROFILE'
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const currentProfileName = config.current_oc_profile;
|
|
65
|
+
log(`Current profile: ${currentProfileName}`);
|
|
66
|
+
|
|
67
|
+
// Check profile exists in profiles.presets
|
|
68
|
+
const presets = config.profiles?.presets;
|
|
69
|
+
if (!presets || !presets[currentProfileName]) {
|
|
70
|
+
const availableProfiles = presets ? Object.keys(presets).join(', ') : 'none';
|
|
71
|
+
error(
|
|
72
|
+
`Current profile "${currentProfileName}" not found in profiles.presets. Available profiles: ${availableProfiles}`,
|
|
73
|
+
'PROFILE_NOT_FOUND'
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const profile = presets[currentProfileName];
|
|
78
|
+
const result = { [currentProfileName]: profile };
|
|
79
|
+
|
|
80
|
+
log(`Returning profile definition for "${currentProfileName}"`);
|
|
81
|
+
|
|
82
|
+
if (raw) {
|
|
83
|
+
output(result, true, JSON.stringify(result, null, 2));
|
|
84
|
+
} else {
|
|
85
|
+
output({ success: true, data: result });
|
|
86
|
+
}
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ========== MODE 2: Profile name parameter (get specific profile) ==========
|
|
91
|
+
log(`Mode 2: Getting profile "${profileName}"`);
|
|
92
|
+
|
|
93
|
+
// Check profile exists in profiles.presets
|
|
94
|
+
// Note: Does NOT require current_oc_profile to be set
|
|
95
|
+
const presets = config.profiles?.presets;
|
|
96
|
+
if (!presets || !presets[profileName]) {
|
|
97
|
+
const availableProfiles = presets ? Object.keys(presets).join(', ') : 'none';
|
|
98
|
+
error(
|
|
99
|
+
`Profile "${profileName}" not found in profiles.presets. Available profiles: ${availableProfiles}`,
|
|
100
|
+
'PROFILE_NOT_FOUND'
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const profile = presets[profileName];
|
|
105
|
+
const result = { [profileName]: profile };
|
|
106
|
+
|
|
107
|
+
log(`Returning profile definition for "${profileName}"`);
|
|
108
|
+
|
|
109
|
+
if (raw) {
|
|
110
|
+
output(result, true, JSON.stringify(result, null, 2));
|
|
111
|
+
} else {
|
|
112
|
+
output({ success: true, data: result });
|
|
113
|
+
}
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
module.exports = getProfile;
|